diff --git a/.travis.yml b/.travis.yml index 17c25da09b8..96a238e6ad4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ # from Dolibarr GitHub repository. # For syntax, see http://about.travis-ci.org/docs/user/languages/php/ -# We use dist: trusty to have php 5.4+ available +# We use dist: trusty to have php 5.4+ available dist: trusty sudo: required @@ -20,7 +20,7 @@ addons: # To use the last version of pgloader, we add repo of postgresql - postgresql - sourceline: 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' - - key_url: 'https://www.postgresql.org/media/keys/ACCC4CF8.asc' + - key_url: 'https://www.postgresql.org/media/keys/ACCC4CF8.asc' packages: # We need a webserver to test the webservices # Let's install Apache with. @@ -105,7 +105,7 @@ before_install: pgloader --version echo fi - + install: - | echo "Updating Composer" @@ -137,7 +137,7 @@ install: - | echo "Installing PHP CodeSniffer" - composer -n require squizlabs/php_codesniffer ^2 + composer -n require squizlabs/php_codesniffer ^3 echo - | @@ -199,7 +199,7 @@ before_script: mysql --version | head - mysql -e "SELECT VERSION();" | head - echo - + - | echo "Setting up database" if [ "$DB" = 'mysql' ] || [ "$DB" = 'mariadb' ] || [ "$DB" = 'postgresql' ]; then @@ -207,12 +207,11 @@ before_script: mysql -e 'DROP DATABASE IF EXISTS travis;' mysql -e 'CREATE DATABASE IF NOT EXISTS travis;' mysql -e 'GRANT ALL PRIVILEGES ON travis.* TO travis@127.0.0.1;' - mysql -e 'FLUSH PRIVILEGES;' + mysql -e 'FLUSH PRIVILEGES;' mysql -D travis < dev/initdemo/mysqldump_dolibarr_3.5.0.sql fi if [ "$DB" = 'postgresql' ]; then - #pgsql travis < dev/initdemo/mysqldump_dolibarr_3.5.0.sql - #pgloader mysql://root:pass@127.0.0.1/base postgresql://dolibarrowner@127.0.0.1/dolibarr + #pgloader mysql://root:pass@127.0.0.1/dolibarr_35 postgresql://dolibarrowner:dolibarrownerpass@127.0.0.1/dolibarr_dev pgloader mysql://root@127.0.0.1/travis postgresql:///travis fi # TODO: SQLite @@ -221,7 +220,7 @@ before_script: - | export CONF_FILE=htdocs/conf/conf.php echo "Setting up Dolibarr $CONF_FILE" - echo ' $CONF_FILE + echo ' $CONF_FILE echo '$'dolibarr_main_url_root=\'http://127.0.0.1\'';' >> $CONF_FILE echo '$'dolibarr_main_document_root=\'$TRAVIS_BUILD_DIR/htdocs\'';' >> $CONF_FILE echo '$'dolibarr_main_data_root=\'$TRAVIS_BUILD_DIR/documents\'';' >> $CONF_FILE @@ -242,8 +241,9 @@ before_script: - | echo "Create documents directory and set permissions" # and admin/temp subdirectory needed for unit tests - mkdir -p documents/admin/temp - echo "first line" > documents/dolibarr.log + mkdir -p $TRAVIS_BUILD_DIR/documents/admin/temp + sudo chmod -R a+rwx $TRAVIS_BUILD_DIR/documents + echo "***** First line of dolibarr.log" > $TRAVIS_BUILD_DIR/documents/dolibarr.log echo @@ -338,33 +338,28 @@ script: php upgrade.php 7.0.0 8.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade700800.log php upgrade2.php 7.0.0 8.0.0 MAIN_MODULE_TICKETSUP > $TRAVIS_BUILD_DIR/upgrade700800-2.log php step5.php 7.0.0 8.0.0 > $TRAVIS_BUILD_DIR/upgrade700800-3.log + php upgrade.php 8.0.0 9.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade800900.log + php upgrade2.php 8.0.0 9.0.0 > $TRAVIS_BUILD_DIR/upgrade800900-2.log + php step5.php 8.0.0 9.0.0 > $TRAVIS_BUILD_DIR/upgrade800900-3.log cd - set +e echo - #cat $TRAVIS_BUILD_DIR/upgrade400500-2.log - #cat $TRAVIS_BUILD_DIR/upgrade500600.log - #cat $TRAVIS_BUILD_DIR/upgrade500600-2.log - #cat $TRAVIS_BUILD_DIR/upgrade500600-3.log - #cat $TRAVIS_BUILD_DIR/upgrade600700-2.log - cat /tmp/dolibarr_install.log - + #cat /tmp/dolibarr_install.log + - | echo "Unit testing" # Ensure we catch errors. Set this to +e if you want to go to the end to see dolibarr.log file. set -e phpunit -d memory_limit=-1 -c test/phpunit/phpunittest.xml test/phpunit/AllTests.php + phpunitresult=$? + echo "Phpunit return code = $phpunitresult" set +e -- | - #echo "Output dolibarr.log" - #cat documents/dolibarr.log - after_script: - | - # Dolibarr log file - #echo "After script" - #cat documents/dolibarr.log - + echo "After script - Output 50 latest lines of dolibarr.log" + ls $TRAVIS_BUILD_DIR/documents + tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log after_success: - | @@ -372,20 +367,24 @@ after_success: after_failure: - | - echo Failure - # This part of code seems to be never executed, error or not ??? - echo "Debugging informations" + echo Failure detected, so we show samples of log to help diagnose + # This part of code is executed only if previous commande that fails are enclosed with set +e # Upgrade log files - cat *.log - echo "Debugging informations" + for ficlog in `ls $TRAVIS_BUILD_DIR/*.log` + do + echo "Debugging informations for file $ficlog" + #cat $ficlog + done # Apache log file + echo "Debugging informations for file apache error.log" sudo cat /var/log/apache2/error.log - # Dolibarr log file - cat documents/dolibarr.log if [ "$DEBUG" = true ]; then + # Dolibarr log file + echo "Debugging informations for file dolibarr.log (latest 50 lines)" + tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log # MariaDB log file - sudo cat /var/log/mysql/error.log + echo "Debugging informations for file mysql error.log" + sudo tail -n 50 /var/log/mysql/error.log # TODO: PostgreSQL log file echo fi - diff --git a/COPYRIGHT b/COPYRIGHT index bd3565c3bd1..83f72bb558b 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -53,6 +53,10 @@ JsTimezoneDetect 1.0.6 MIT License Yes SwaggerUI 2.0.24 GPL-2+ Yes JS library to offer the REST API explorer Ace 1.2.8 BSD Yes JS library to get code syntaxique coloration in a textarea. +Image libraries +Octicons 8.1 MIT Yes + + For licenses compatibility informations: http://www.gnu.org/licenses/licenses.en.html diff --git a/ChangeLog b/ChangeLog index a31b7e0ddfd..f61d3a4820d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,31 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 9.0.0 compared to 8.0.0 ***** +For Users: +NEW: Stable module: Website +NEW: Stable module: WebDAV +NEW: Stable module: Module Builder +NEW: Stable module "Skype" has been replaced with module "Social Networks" to support more tools. +NEW: Experimental module "TakePos" +NEW: Dolibarr can provide information in page title when multicompany is enabled of not, making + Android application like DoliDroid able to provide native features for multicompany module. +NEW: Compatibility with PHP 7.3 + + +For developers: +* Code changes to be more compatible with PSR2 +* Removed trigger USER_LOGOUT, USER_LOGIN, USER_LOGIN_FAILED (Some hooks are already dedicated for that) + +WARNING: + +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* If you use some links like viewimages.php?modulepart=mycompany&file=... in you external modules, you must + replace them with links like viewimages.php?modulepart=mycompany&file=logos/... (note that link change only for + modulepart=mycompany that now works like others). + + + ***** ChangeLog for 8.0.2 compared to 8.0.1 ***** FIX: #8452 FIX: #9043 @@ -70,18 +95,17 @@ FIX: Table llx_facture_rec_extrafields missing after migration ***** ChangeLog for 8.0.0 compared to 7.0.0 ***** - For Users: NEW: Experimental module: Ticket NEW: Experimental module: WebDAV -NEW: Accept anonmymous events (no user assigned) +NEW: Accept anonymous events (no user assigned) NEW: Accountancy - Add import on general ledger NEW: Accountancy - Show journal name on journal page and hide button draft export (Add an option in admin) -NEW: Can create event from record card of a company and member -NEW: Add a button to create Stripe customer from the Payment mode tab +NEW: Can create event from record card of a company and/or member +NEW: Add a button to create Stripe customer from the customer Payment mode tab NEW: Add accounting account number on product tooltip -NEW: add any predefined mail content -NEW: Add arrows to navigate into containers in website module +NEW: Add any predefined mail content +NEW: Add arrows to navigate into containers in experimental website module NEW: Add a tab to specify accountant/auditor of the company NEW: Add Date delivery and Availability on Propals List NEW: Add date in goods reception supplier order table @@ -168,7 +192,7 @@ NEW: Filter export model is now by user NEW: Finish implementation of option PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES NEW: generalize use of button to create new element from list NEW: hidden conf AGENDA_NB_WEEKS_IN_VIEW_PER_USER to set nb weeks to show into per user view -NEW: hidden conf to assign category to thirparty that are not customer nor prospect nor supplier +NEW: hidden conf to assign category to thirparty that are neither customer nor prospect or supplier NEW: hidden conf to set nb weeks to show into user view NEW: hidden option MAIN_DISABLE_FREE_LINES NEW: improve way of adding users/sales representative to thirdparty diff --git a/README-FR.md b/README-FR.md index a9745bb8dbb..19d4ae25df9 100644 --- a/README-FR.md +++ b/README-FR.md @@ -16,8 +16,8 @@ Dolibarr est distribué sous les termes de la licence GNU General Public License ## INSTALLER DOLIBARR Si vous n'avez pas de connaissances techniques, et que vous recherchez -un programme d'installation qui install Dolibarr ERP/CRM en quelques clics, -vous devez vous réorienter vers DoliWamp (la version tout-en-un +un programme d'installation qui installe Dolibarr ERP/CRM en quelques clics, +vous devez vous ré-orienter vers DoliWamp (la version tout-en-un de Dolibarr pour Windows), DoliDeb (la version tout-en-un pour Debian ou Ubuntu) ou DoliRpm (la version tout-en-un de Dolibarr pour Fedora, Redhat, OpenSuse, Mandriva ou Mageia). @@ -25,39 +25,39 @@ OpenSuse, Mandriva ou Mageia). Vous pouvez les télécharger depuis la rubrique *download* du portail officiel: https://www.dolibarr.org/ -Si vous avez déjà installé un serveur Web avec PHP et une base de donnée (MariaDb/MySql/PostgreSql), +Si vous avez déjà installé un serveur Web avec PHP et une base de données (MariaDb/MySql/PostgreSql), vous pouvez installer Dolibarr avec cette version de la manière suivante: -- Copier le répertoire "dolibarr" et son contenu dans la racine de votre serveur - web, ou bien copier le répertoire sur le serveur et configurer ce serveur pour +- Copiez le répertoire "dolibarr" et son contenu dans la racine de votre serveur + web, ou bien copiez le répertoire sur le serveur et configurez ce serveur pour utiliser "dolibarr/htdocs" comme racine d'un nouveau virtual host (ce second choix requiert des compétences et habilitations en administration du serveur web). -- Créer un fichier vide "htdocs/conf/conf.php" et attribuer les permissions +- Créez un fichier vide "htdocs/conf/conf.php" et attribuez les permissions en lecture et écriture pour le user du serveur web (les permissions en écriture seront supprimées une fois l'installation terminée). -- Depuis votre navigateur, appeler la page "install/" de dolibarr. L'url dépend - du choix fait à la première etape: +- Depuis votre navigateur, appelez la page "install/" de dolibarr. L'url dépend + du choix fait à la première étape: http://localhost/dolibarr/htdocs/install/ ou http://yourdolibarrvirtualhost/install/ -- Suivez les instructions fournies par l'installeur... +- Suivez les instructions fournies par l'installateur... ## METTRE A JOUR DOLIBARR -Pour mettre a jour Dolibarr depuis une vieille version vers celle ci: -- Ecraser les vieux fichiers dans le vieux repertoire 'dolibarr' par les fichiers +Pour mettre à jour Dolibarr depuis une vieille version vers celle ci: +- Ecrasez les vieux fichiers dans le vieux répertoire 'dolibarr' par les fichiers fournis dans ce nouveau package. -- Au prochain accès, Dolibarr proposera la page de "mise a jour" des données (si necessaire). - Si un fichier install.lock existe pour vérouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transféré sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents") - -*Note: Le processus de migration peut etre lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/* +- Au prochain accès, Dolibarr proposera la page de "mise à jour" des données (si nécessaire). + Si un fichier install.lock existe pour verrouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transférés sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents") + +*Note: Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/* ## CE QUI EST NOUVEAU @@ -94,14 +94,15 @@ Voir fichier ChangeLog. - Gestion de marque-pages - Gestion des promesses de dons -- Gestion de la TVA NPR (non perçue récupérable - pour les utilisateurs français des DOM-TOM) - Rapports - Imports/Exports des données +- Support des codes barres +- Calcul des marges - Connectivité LDAP - Intégratn de ClickToDial - Intégration RSS - Intégation Skype -- Intégration de système de paiements (Paypal, Strip, Paybox...) +- Intégration de système de paiements (Paypal, Stripe, Paybox...) - … ### Divers: @@ -114,9 +115,18 @@ Voir fichier ChangeLog. - Application simple à utiliser. - Requiert PHP et MariaDb, Mysql ou Postgresql (Voir versions exactes sur https://wiki.dolibarr.org/index.php/Prérequis). - Compatible avec toutes les offres Cloud du marché respectant les prérequis de base de données et PHP. -- Code simple et facilement personnalisable (pas de framework lourd; mécanisme de hook et triggers). - APIs. - Génération PDF et ODT des éléments (factures, propositions commerciales, commandes, bons expéditions, etc...) +- Code simple et facilement personnalisable (pas de framework lourd; mécanisme de hook et triggers). +- Support natif de nombreuses fonctions spécifiques aux pays comme: + - La tax espagnole TE et ISPF + - Gestion de la TVA NPR (non perçue récupérable - pour les utilisateurs français des DOM-TOM) + - La loi française Finance 2016 et logiciels de caisse + - La double taxe canadienne + - Le timbre fiscal tunisien + - Numérotation de facture de l'argentines (avec type A,B,C...) + - Compatible avec vos processus RGPD + - ... - … ### Extension @@ -126,7 +136,7 @@ Dolibarr peut aussi être étendu à volonté avec l'ajout de module/application ## CE QUE DOLIBARR NE PEUT PAS (ENCORE) FAIRE -Voici un liste de fonctionnalites pas encore gérées par Dolibarr: +Voici un liste de fonctionnalités pas encore gérées par Dolibarr: - Dolibarr ne contient pas de module de Gestion de la paie. - Les tâches du module de gestion de projets n'ont pas de dépendances entre elle. - Dolibarr n'embarque pas de Webmail intégré nativement. @@ -135,7 +145,7 @@ Voici un liste de fonctionnalites pas encore gérées par Dolibarr: ## DOCUMENTATION -Les documentations utilisateur, développeur et traducteur sont disponible sous forme de ressources de la communautés via la site [Wiki](https://wiki.dolibarr.org). +La documentation utilisateur, développeur et traducteur est disponible sous forme de ressources de la communauté via le site [Wiki](https://wiki.dolibarr.org). ## CONTRIBUER diff --git a/README.md b/README.md index 5feec47e56f..c38d0ca7dd1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # DOLIBARR ERP & CRM -![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/8.0.svg) ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) +![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg) +[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com) + +|6|7|8|develop| +|----------|----------|----------|----------| +|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/6.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/7.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/8.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg)| Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…). @@ -125,7 +130,6 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Donations management - Reporting - Data export/import -- Thirdparties and/or products categories - Barcodes support - Margin calculations - LDAP connectivity @@ -147,13 +151,15 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Compatible with all Cloud solutions that match MySQL, PHP or PostgreSQL prerequisites. - APIs. - An easy to understand, maintain and develop code (PHP with no heavy framework; trigger and hook architecture) -- Support for country specific features: +- Support a lot of country specific features: - Spanish Tax RE and ISPF - French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM) - Canadian double taxes (federal/province) and other countries using cumulative VAT - Tunisian tax stamp - Argentina invoice numbering using A,B,C... - Compatible with [European directives](http://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) + - Compatible with European GDPR rules + - ... - PDF or ODT generation for invoice, proposals, orders... - … diff --git a/build/aps/APP-META-1.1.xml b/build/aps/APP-META-1.1.xml deleted file mode 100644 index 1394da4d4be..00000000000 --- a/build/aps/APP-META-1.1.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - Dolibarr ERP-CRM - __VERSION__ - __RELEASE__ - http://www.dolibarr.org/ - - Dolibarr - http://www.dolibarr.org/ - - - - Laurent Destailleur - http://www.nltechno.com - uuid:e743ee30-9fe8-11e0-a32e-0025115d642c - - - Dolibarr ERP-CRM, the easy to use software to manage small or medium companies, freelancers or foundations - -Dolibarr is a free modular software (you see only -features you need) to manage small and medium companies, freelancers -or foundations. -This OpenSource software is designed to provide all features you need to -manage information on many aspects of your business -into an intuitive and user-friendly graphical interface -It's an OpenSource software you can install on a web server or as a -standalone software. Dolibarr is designed to provide simplicity to end-user. - - - - Screenshot 1 - - - - See http://www.dolibarr.org/files/ChangeLog - - - - Back office/Billing - Back office/Accounting and Financial - Back office/Customer Relationship Management - Back office/Enterprise Resource Planning - - - en - fr - es - de - pt - - - - - - - - - GPL-3.0+ - COPYING - - - - Dolibarr instance - Dolibarr services - - - - - - - - - - - - - - mysql - mbstring - false - - main - dolibarr - false - mysql - 4.3.1 - - - - - - dolibarr - 35000000 - - - php - - - - - - php - - - - - \ No newline at end of file diff --git a/build/aps/APP-META-1.2.xml b/build/aps/APP-META-1.2.xml deleted file mode 100644 index 1ce51207dd8..00000000000 --- a/build/aps/APP-META-1.2.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - dolibarr - Dolibarr - __VERSION__ - __RELEASE__ - http://www.dolibarr.org/ - - Dolibarr - http://www.dolibarr.org/ - - - - Laurent Destailleur - http://www.nltechno.com - uuid:e743ee30-9fe8-11e0-a32e-0025115d642c - - - Dolibarr ERP - CRM, the easy to use software to manage small or medium companies, freelancers or foundations - -Dolibarr is a free modular software (you see only -features you need) to manage small and medium companies, freelancers -or foundations. -This OpenSource software is designed to provide all features you need to -manage information on many aspects of your business -into an intuitive and user-friendly graphical interface -It's an OpenSource software you can install on a web server or as a -standalone software. Dolibarr is designed to provide simplicity to end-user. - - - - Screenshot 1 - - - - See http://www.dolibarr.org/files/ChangeLog - - - - Back office/Billing - Back office/Accounting and Financial - Back office/Customer Relationship Management - Back office/Enterprise Resource Planning - - - en - fr - es - de - pt - - - - - - - - - GPL-3.0+ - COPYING - - - - Dolibarr instance - - - - - - - - - - Administrator's preferences - - Administrator's login - -Please make sure the text you entered starts with a letter and continues with either numbers, letters, underscores or hyphens. - - - - Password - - - - - - - mysql - mbstring - false - - main - dolibarr - false - mysql - 4.3.1 - - - - - - dolibarr - 35000000 - - - php - - - - - - php - - - - - \ No newline at end of file diff --git a/build/aps/Limitations of APS Support in the Panel.html b/build/aps/Limitations of APS Support in the Panel.html deleted file mode 100644 index 51ba8e18378..00000000000 --- a/build/aps/Limitations of APS Support in the Panel.html +++ /dev/null @@ -1,89 +0,0 @@ - - Limitations of APS Support in the Panel - - - - - - - - -

Limitations of APS Support in the Panel

-

About This Document

-

This document is addressed to independent software -vendors who plan to distribute web applications among the Panel users. -The aim of the document is to help vendors find out whether they can -package their applications to APS to make them available through the -Panel.

-

The document does not contain information about -Application Packaging Standard itself or give application packaging -instructions. It focuses on how the Panel implements APS and what APS -packages are not supported by this implementation.

-

-

APS Support in the Panel

-

Application Packaging Standard (APS) - is a set of rules that defines a web application packaging format. This - standard is designed to ease the integration of applications in a -service provider's infrastructure. It covers provisioning, management, -and integration of cloud-based services and applications.

-

The Panel uses APS to offer third-party applications to hosting customers. These applications are presented in APS catalog, where the customers can buy or download them.

-

Currently, the Panel does not support all aspects of - APS. Therefore, customers may have problems trying to install certain -applications. To find out whether your application is compatible with -the Panel, see section Plesk Panel Restrictions.

-

You can find more information about APS at http://www.apsstandard.org/.

-

APS specification and supporting documents are available at http://www.apsstandard.org/isv/documentation/.

-

-

Restrictions on Packages Processing

-

The current Panel version has restrictions on APS -applications processing. If an application requires performing -restricted actions, the Panel will not install it. Particularly, these -actions are the following:

-

If - you need you application to perform these actions, consider other ways -of integration with the Panel: API RPC, modules or Panel Notifications.

-

Also, the Panel does not support the following actions defined in the application package:

- - \ No newline at end of file diff --git a/build/aps/Limitations of APS Support in the Panel_fichiers/highlight.js b/build/aps/Limitations of APS Support in the Panel_fichiers/highlight.js deleted file mode 100644 index d6386c93792..00000000000 --- a/build/aps/Limitations of APS Support in the Panel_fichiers/highlight.js +++ /dev/null @@ -1,64 +0,0 @@ -function last(href) -{ - var ret = href.split("/"); - return ret[ret.length-1]; -} - -function StopProcess() -{ -LeftFrame = parent.TOC.document.location.href; -LeftFrame = last(LeftFrame); -if (LeftFrame == "dhtml_search.htm") return 1 -else return 0; -} - - - -function highlightTOC(str) { - - - - - - if (StopProcess()) return; - try { - - str = str || parent.BODY.document.location.href; - uri = last(str); - list = parent.TOC.document.getElementsByTagName("a"); - for(i=0; i - * - * For a fairly comprehensive set of languages see the - * README - * file that came with this source. At a minimum, the lexer should work on a - * number of languages including C and friends, Java, Python, Bash, SQL, HTML, - * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk - * and a subset of Perl, but, because of commenting conventions, doesn't work on - * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. - *

- * Usage:

    - *
  1. include this source file in an html page via - * {@code } - *
  2. define style rules. See the example page for examples. - *
  3. mark the {@code
    } and {@code } tags in your source with
    - *    {@code class=prettyprint.}
    - *    You can also use the (html deprecated) {@code } tag, but the pretty
    - *    printer needs to do more substantial DOM manipulations to support that, so
    - *    some css styles may not be preserved.
    - * </ol>
    - * That's it.  I wanted to keep the API as simple as possible, so there's no
    - * need to specify which language the code is in, but if you wish, you can add
    - * another class to the {@code <pre>} or {@code <code>} element to specify the
    - * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    - * starts with "lang-" followed by a file extension, specifies the file type.
    - * See the "lang-*.js" files in this directory for code that implements
    - * per-language file handlers.
    - * <p>
    - * Change log:<br>
    - * cbeust, 2006/08/22
    - * <blockquote>
    - *   Java annotations (start with "@") are now captured as literals ("lit")
    - * </blockquote>
    - * @requires console
    - */
    -
    -// JSLint declarations
    -/*global console, document, navigator, setTimeout, window */
    -
    -/**
    - * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    - * UI events.
    - * If set to {@code false}, {@code prettyPrint()} is synchronous.
    - */
    -window['PR_SHOULD_USE_CONTINUATION'] = true;
    -
    -/** the number of characters between tab columns */
    -window['PR_TAB_WIDTH'] = 8;
    -
    -/** Walks the DOM returning a properly escaped version of innerHTML.
    -  * @param {Node} node
    -  * @param {Array.<string>} out output buffer that receives chunks of HTML.
    -  */
    -window['PR_normalizedHtml']
    -
    -/** Contains functions for creating and registering new language handlers.
    -  * @type {Object}
    -  */
    -  = window['PR']
    -
    -/** Pretty print a chunk of code.
    -  *
    -  * @param {string} sourceCodeHtml code as html
    -  * @return {string} code as html, but prettier
    -  */
    -  = window['prettyPrintOne']
    -/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    -  * {@code class=prettyprint} and prettify them.
    -  * @param {Function?} opt_whenDone if specified, called when the last entry
    -  *     has been finished.
    -  */
    -  = window['prettyPrint'] = void 0;
    -
    -/** browser detection. @extern @returns false if not IE, otherwise the major version. */
    -window['_pr_isIE6'] = function () {
    -  var ieVersion = navigator && navigator.userAgent &&
    -      navigator.userAgent.match(/\bMSIE ([678])\./);
    -  ieVersion = ieVersion ? +ieVersion[1] : false;
    -  window['_pr_isIE6'] = function () { return ieVersion; };
    -  return ieVersion;
    -};
    -
    -
    -(function () {
    -  // Keyword lists for various languages.
    -  var FLOW_CONTROL_KEYWORDS =
    -      "break continue do else for if return while ";
    -  var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
    -      "double enum extern float goto int long register short signed sizeof " +
    -      "static struct switch typedef union unsigned void volatile ";
    -  var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
    -      "new operator private protected public this throw true try typeof ";
    -  var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
    -      "concept concept_map const_cast constexpr decltype " +
    -      "dynamic_cast explicit export friend inline late_check " +
    -      "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
    -      "template typeid typename using virtual wchar_t where ";
    -  var JAVA_KEYWORDS = COMMON_KEYWORDS +
    -      "abstract boolean byte extends final finally implements import " +
    -      "instanceof null native package strictfp super synchronized throws " +
    -      "transient ";
    -  var CSHARP_KEYWORDS = JAVA_KEYWORDS +
    -      "as base by checked decimal delegate descending event " +
    -      "fixed foreach from group implicit in interface internal into is lock " +
    -      "object out override orderby params partial readonly ref sbyte sealed " +
    -      "stackalloc string select uint ulong unchecked unsafe ushort var ";
    -  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
    -      "debugger eval export function get null set undefined var with " +
    -      "Infinity NaN ";
    -  var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
    -      "goto if import last local my next no our print package redo require " +
    -      "sub undef unless until use wantarray while BEGIN END ";
    -  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
    -      "elif except exec finally from global import in is lambda " +
    -      "nonlocal not or pass print raise try with yield " +
    -      "False True None ";
    -  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
    -      " defined elsif end ensure false in module next nil not or redo rescue " +
    -      "retry self super then true undef unless until when yield BEGIN END ";
    -  var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
    -      "function in local set then until ";
    -  var ALL_KEYWORDS = (
    -      CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
    -      PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
    -
    -  // token style names.  correspond to css classes
    -  /** token style for PHP variables */
    -  var PR_VAR = 'vr';
    -  /** token style for a string literal */
    -  var PR_STRING = 'str';
    -  /** token style for a keyword */
    -  var PR_KEYWORD = 'kwd';
    -  /** token style for a comment */
    -  var PR_COMMENT = 'com';
    -  /** token style for a type */
    -  var PR_TYPE = 'typ';
    -  /** token style for a literal value.  e.g. 1, null, true. */
    -  var PR_LITERAL = 'lit';
    -  /** token style for a punctuation string. */
    -  var PR_PUNCTUATION = 'pun';
    -  /** token style for a punctuation string. */
    -  var PR_PLAIN = 'pln';
    -
    -  /** token style for an sgml tag. */
    -  var PR_TAG = 'tag';
    -  /** token style for a markup declaration such as a DOCTYPE. */
    -  var PR_DECLARATION = 'dec';
    -  /** token style for embedded source. */
    -  var PR_SOURCE = 'src';
    -  /** token style for an sgml attribute name. */
    -  var PR_ATTRIB_NAME = 'atn';
    -  /** token style for an sgml attribute value. */
    -  var PR_ATTRIB_VALUE = 'atv';
    -
    -  /**
    -   * A class that indicates a section of markup that is not code, e.g. to allow
    -   * embedding of line numbers within code listings.
    -   */
    -  var PR_NOCODE = 'nocode';
    -
    -  /** A set of tokens that can precede a regular expression literal in
    -    * javascript.
    -    * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
    -    * list, but I've removed ones that might be problematic when seen in
    -    * languages that don't support regular expression literals.
    -    *
    -    * <p>Specifically, I've removed any keywords that can't precede a regexp
    -    * literal in a syntactically legal javascript program, and I've removed the
    -    * "in" keyword since it's not a keyword in many languages, and might be used
    -    * as a count of inches.
    -    *
    -    * <p>The link a above does not accurately describe EcmaScript rules since
    -    * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    -    * very well in practice.
    -    *
    -    * @private
    -    */
    -  var REGEXP_PRECEDER_PATTERN = function () {
    -      var preceders = [
    -          "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
    -          "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
    -          "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
    -          "<", "<<", "<<=", "<=", "=", "==", "===", ">",
    -          ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
    -          "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
    -          "||=", "~" /* handles =~ and !~ */,
    -          "break", "case", "continue", "delete",
    -          "do", "else", "finally", "instanceof",
    -          "return", "throw", "try", "typeof"
    -          ];
    -      var pattern = '(?:^^|[+-]';
    -      for (var i = 0; i < preceders.length; ++i) {
    -        pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
    -      }
    -      pattern += ')\\s*';  // matches at end, and matches empty string
    -      return pattern;
    -      // CAVEAT: this does not properly handle the case where a regular
    -      // expression immediately follows another since a regular expression may
    -      // have flags for case-sensitivity and the like.  Having regexp tokens
    -      // adjacent is not valid in any language I'm aware of, so I'm punting.
    -      // TODO: maybe style special characters inside a regexp as punctuation.
    -    }();
    -
    -  // Define regexps here so that the interpreter doesn't have to create an
    -  // object each time the function containing them is called.
    -  // The language spec requires a new object created even if you don't access
    -  // the $1 members.
    -  var pr_amp = /&/g;
    -  var pr_lt = /</g;
    -  var pr_gt = />/g;
    -  var pr_quot = /\"/g;
    -  /** like textToHtml but escapes double quotes to be attribute safe. */
    -  function attribToHtml(str) {
    -    return str.replace(pr_amp, '&amp;')
    -        .replace(pr_lt, '&lt;')
    -        .replace(pr_gt, '&gt;')
    -        .replace(pr_quot, '&quot;');
    -  }
    -
    -  /** escapest html special characters to html. */
    -  function textToHtml(str) {
    -    return str.replace(pr_amp, '&amp;')
    -        .replace(pr_lt, '&lt;')
    -        .replace(pr_gt, '&gt;');
    -  }
    -
    -
    -  var pr_ltEnt = /&lt;/g;
    -  var pr_gtEnt = /&gt;/g;
    -  var pr_aposEnt = /&apos;/g;
    -  var pr_quotEnt = /&quot;/g;
    -  var pr_ampEnt = /&amp;/g;
    -  var pr_nbspEnt = /&nbsp;/g;
    -  /** unescapes html to plain text. */
    -  function htmlToText(html) {
    -    var pos = html.indexOf('&');
    -    if (pos < 0) { return html; }
    -    // Handle numeric entities specially.  We can't use functional substitution
    -    // since that doesn't work in older versions of Safari.
    -    // These should be rare since most browsers convert them to normal chars.
    -    for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {
    -      var end = html.indexOf(';', pos);
    -      if (end >= 0) {
    -        var num = html.substring(pos + 3, end);
    -        var radix = 10;
    -        if (num && num.charAt(0) === 'x') {
    -          num = num.substring(1);
    -          radix = 16;
    -        }
    -        var codePoint = parseInt(num, radix);
    -        if (!isNaN(codePoint)) {
    -          html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
    -                  html.substring(end + 1));
    -        }
    -      }
    -    }
    -
    -    return html.replace(pr_ltEnt, '<')
    -        .replace(pr_gtEnt, '>')
    -        .replace(pr_aposEnt, "'")
    -        .replace(pr_quotEnt, '"')
    -        .replace(pr_nbspEnt, ' ')
    -        .replace(pr_ampEnt, '&');
    -  }
    -
    -  /** is the given node's innerHTML normally unescaped? */
    -  function isRawContent(node) {
    -    return 'XMP' === node.tagName;
    -  }
    -
    -  var newlineRe = /[\r\n]/g;
    -  /**
    -   * Are newlines and adjacent spaces significant in the given node's innerHTML?
    -   */
    -  function isPreformatted(node, content) {
    -    // PRE means preformatted, and is a very common case, so don't create
    -    // unnecessary computed style objects.
    -    if ('PRE' === node.tagName) { return true; }
    -    if (!newlineRe.test(content)) { return true; }  // Don't care
    -    var whitespace = '';
    -    // For disconnected nodes, IE has no currentStyle.
    -    if (node.currentStyle) {
    -      whitespace = node.currentStyle.whiteSpace;
    -    } else if (window.getComputedStyle) {
    -      // Firefox makes a best guess if node is disconnected whereas Safari
    -      // returns the empty string.
    -      whitespace = window.getComputedStyle(node, null).whiteSpace;
    -    }
    -    return !whitespace || whitespace === 'pre';
    -  }
    -
    -  function normalizedHtml(node, out, opt_sortAttrs) {
    -    switch (node.nodeType) {
    -      case 1:  // an element
    -        var name = node.tagName.toLowerCase();
    -
    -        out.push('<', name);
    -        var attrs = node.attributes;
    -        var n = attrs.length;
    -        if (n) {
    -          if (opt_sortAttrs) {
    -            var sortedAttrs = [];
    -            for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; }
    -            sortedAttrs.sort(function (a, b) {
    -                return (a.name < b.name) ? -1 : a.name === b.name ? 0 : 1;
    -              });
    -            attrs = sortedAttrs;
    -          }
    -          for (var i = 0; i < n; ++i) {
    -            var attr = attrs[i];
    -            if (!attr.specified) { continue; }
    -            out.push(' ', attr.name.toLowerCase(),
    -                     '="', attribToHtml(attr.value), '"');
    -          }
    -        }
    -        out.push('>');
    -        for (var child = node.firstChild; child; child = child.nextSibling) {
    -          normalizedHtml(child, out, opt_sortAttrs);
    -        }
    -        if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
    -          out.push('<\/', name, '>');
    -        }
    -        break;
    -      case 3: case 4: // text
    -        out.push(textToHtml(node.nodeValue));
    -        break;
    -    }
    -  }
    -
    -  /**
    -   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    -   * matches the union o the sets o strings matched d by the input RegExp.
    -   * Since it matches globally, if the input strings have a start-of-input
    -   * anchor (/^.../), it is ignored for the purposes of unioning.
    -   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    -   * @return {RegExp} a global regex.
    -   */
    -  function combinePrefixPatterns(regexs) {
    -    var capturedGroupIndex = 0;
    -
    -    var needToFoldCase = false;
    -    var ignoreCase = false;
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.ignoreCase) {
    -        ignoreCase = true;
    -      } else if (/[a-z]/i.test(regex.source.replace(
    -                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    -        needToFoldCase = true;
    -        ignoreCase = false;
    -        break;
    -      }
    -    }
    -
    -    function decodeEscape(charsetPart) {
    -      if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
    -      switch (charsetPart.charAt(1)) {
    -        case 'b': return 8;
    -        case 't': return 9;
    -        case 'n': return 0xa;
    -        case 'v': return 0xb;
    -        case 'f': return 0xc;
    -        case 'r': return 0xd;
    -        case 'u': case 'x':
    -          return parseInt(charsetPart.substring(2), 16)
    -              || charsetPart.charCodeAt(1);
    -        case '0': case '1': case '2': case '3': case '4':
    -        case '5': case '6': case '7':
    -          return parseInt(charsetPart.substring(1), 8);
    -        default: return charsetPart.charCodeAt(1);
    -      }
    -    }
    -
    -    function encodeEscape(charCode) {
    -      if (charCode < 0x20) {
    -        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    -      }
    -      var ch = String.fromCharCode(charCode);
    -      if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
    -        ch = '\\' + ch;
    -      }
    -      return ch;
    -    }
    -
    -    function caseFoldCharset(charSet) {
    -      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    -          new RegExp(
    -              '\\\\u[0-9A-Fa-f]{4}'
    -              + '|\\\\x[0-9A-Fa-f]{2}'
    -              + '|\\\\[0-3][0-7]{0,2}'
    -              + '|\\\\[0-7]{1,2}'
    -              + '|\\\\[\\s\\S]'
    -              + '|-'
    -              + '|[^-\\\\]',
    -              'g'));
    -      var groups = [];
    -      var ranges = [];
    -      var inverse = charsetParts[0] === '^';
    -      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    -        var p = charsetParts[i];
    -        switch (p) {
    -          case '\\B': case '\\b':
    -          case '\\D': case '\\d':
    -          case '\\S': case '\\s':
    -          case '\\W': case '\\w':
    -            groups.push(p);
    -            continue;
    -        }
    -        var start = decodeEscape(p);
    -        var end;
    -        if (i + 2 < n && '-' === charsetParts[i + 1]) {
    -          end = decodeEscape(charsetParts[i + 2]);
    -          i += 2;
    -        } else {
    -          end = start;
    -        }
    -        ranges.push([start, end]);
    -        // If the range might intersect letters, then expand it.
    -        if (!(end < 65 || start > 122)) {
    -          if (!(end < 65 || start > 90)) {
    -            ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    -          }
    -          if (!(end < 97 || start > 122)) {
    -            ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    -          }
    -        }
    -      }
    -
    -      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    -      // -> [[1, 12], [14, 14], [16, 17]]
    -      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    -      var consolidatedRanges = [];
    -      var lastRange = [NaN, NaN];
    -      for (var i = 0; i < ranges.length; ++i) {
    -        var range = ranges[i];
    -        if (range[0] <= lastRange[1] + 1) {
    -          lastRange[1] = Math.max(lastRange[1], range[1]);
    -        } else {
    -          consolidatedRanges.push(lastRange = range);
    -        }
    -      }
    -
    -      var out = ['['];
    -      if (inverse) { out.push('^'); }
    -      out.push.apply(out, groups);
    -      for (var i = 0; i < consolidatedRanges.length; ++i) {
    -        var range = consolidatedRanges[i];
    -        out.push(encodeEscape(range[0]));
    -        if (range[1] > range[0]) {
    -          if (range[1] + 1 > range[0]) { out.push('-'); }
    -          out.push(encodeEscape(range[1]));
    -        }
    -      }
    -      out.push(']');
    -      return out.join('');
    -    }
    -
    -    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    -      // Split into character sets, escape sequences, punctuation strings
    -      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    -      // include any of the above.
    -      var parts = regex.source.match(
    -          new RegExp(
    -              '(?:'
    -              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    -              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    -              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    -              + '|\\\\[0-9]+'  // a back-reference or octal escape
    -              + '|\\\\[^ux0-9]'  // other escape sequence
    -              + '|\\(\\?[:!=]'  // start of a non-capturing group
    -              + '|[\\(\\)\\^]'  // start/emd of a group, or line start
    -              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    -              + ')',
    -              'g'));
    -      var n = parts.length;
    -
    -      // Maps captured group numbers to the number they will occupy in
    -      // the output or to -1 if that has not been determined, or to
    -      // undefined if they need not be capturing in the output.
    -      var capturedGroups = [];
    -
    -      // Walk over and identify back references to build the capturedGroups
    -      // mapping.
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          // groups are 1-indexed, so max group index is count of '('
    -          ++groupIndex;
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue && decimalValue <= groupIndex) {
    -            capturedGroups[decimalValue] = -1;
    -          }
    -        }
    -      }
    -
    -      // Renumber groups and reduce capturing groups to non-capturing groups
    -      // where possible.
    -      for (var i = 1; i < capturedGroups.length; ++i) {
    -        if (-1 === capturedGroups[i]) {
    -          capturedGroups[i] = ++capturedGroupIndex;
    -        }
    -      }
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          ++groupIndex;
    -          if (capturedGroups[groupIndex] === undefined) {
    -            parts[i] = '(?:';
    -          }
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue && decimalValue <= groupIndex) {
    -            parts[i] = '\\' + capturedGroups[groupIndex];
    -          }
    -        }
    -      }
    -
    -      // Remove any prefix anchors so that the output will match anywhere.
    -      // ^^ really does mean an anchored match though.
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    -      }
    -
    -      // Expand letters to groupts to handle mixing of case-sensitive and
    -      // case-insensitive patterns if necessary.
    -      if (regex.ignoreCase && needToFoldCase) {
    -        for (var i = 0; i < n; ++i) {
    -          var p = parts[i];
    -          var ch0 = p.charAt(0);
    -          if (p.length >= 2 && ch0 === '[') {
    -            parts[i] = caseFoldCharset(p);
    -          } else if (ch0 !== '\\') {
    -            // TODO: handle letters in numeric escapes.
    -            parts[i] = p.replace(
    -                /[a-zA-Z]/g,
    -                function (ch) {
    -                  var cc = ch.charCodeAt(0);
    -                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    -                });
    -          }
    -        }
    -      }
    -
    -      return parts.join('');
    -    }
    -
    -    var rewritten = [];
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    -      rewritten.push(
    -          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    -    }
    -
    -    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    -  }
    -
    -  var PR_innerHtmlWorks = null;
    -  function getInnerHtml(node) {
    -    // inner html is hopelessly broken in Safari 2.0.4 when the content is
    -    // an html description of well formed XML and the containing tag is a PRE
    -    // tag, so we detect that case and emulate innerHTML.
    -    if (null === PR_innerHtmlWorks) {
    -      var testNode = document.createElement('PRE');
    -      testNode.appendChild(
    -          document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));
    -      PR_innerHtmlWorks = !/</.test(testNode.innerHTML);
    -    }
    -
    -    if (PR_innerHtmlWorks) {
    -      var content = node.innerHTML;
    -      // XMP tags contain unescaped entities so require special handling.
    -      if (isRawContent(node)) {
    -        content = textToHtml(content);
    -      } else if (!isPreformatted(node, content)) {
    -        content = content.replace(/(<br\s*\/?>)[\r\n]+/g, '$1')
    -            .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
    -      }
    -      return content;
    -    }
    -
    -    var out = [];
    -    for (var child = node.firstChild; child; child = child.nextSibling) {
    -      normalizedHtml(child, out);
    -    }
    -    return out.join('');
    -  }
    -
    -  /** returns a function that expand tabs to spaces.  This function can be fed
    -    * successive chunks of text, and will maintain its own internal state to
    -    * keep track of how tabs are expanded.
    -    * @return {function (string) : string} a function that takes
    -    *   plain text and return the text with tabs expanded.
    -    * @private
    -    */
    -  function makeTabExpander(tabWidth) {
    -    var SPACES = '                ';
    -    var charInLine = 0;
    -
    -    return function (plainText) {
    -      // walk over each character looking for tabs and newlines.
    -      // On tabs, expand them.  On newlines, reset charInLine.
    -      // Otherwise increment charInLine
    -      var out = null;
    -      var pos = 0;
    -      for (var i = 0, n = plainText.length; i < n; ++i) {
    -        var ch = plainText.charAt(i);
    -
    -        switch (ch) {
    -          case '\t':
    -            if (!out) { out = []; }
    -            out.push(plainText.substring(pos, i));
    -            // calculate how much space we need in front of this part
    -            // nSpaces is the amount of padding -- the number of spaces needed
    -            // to move us to the next column, where columns occur at factors of
    -            // tabWidth.
    -            var nSpaces = tabWidth - (charInLine % tabWidth);
    -            charInLine += nSpaces;
    -            for (; nSpaces >= 0; nSpaces -= SPACES.length) {
    -              out.push(SPACES.substring(0, nSpaces));
    -            }
    -            pos = i + 1;
    -            break;
    -          case '\n':
    -            charInLine = 0;
    -            break;
    -          default:
    -            ++charInLine;
    -        }
    -      }
    -      if (!out) { return plainText; }
    -      out.push(plainText.substring(pos));
    -      return out.join('');
    -    };
    -  }
    -
    -  var pr_chunkPattern = new RegExp(
    -      '[^<]+'  // A run of characters other than '<'
    -      + '|<\!--[\\s\\S]*?--\>'  // an HTML comment
    -      + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>'  // a CDATA section
    -      // a probable tag that should not be highlighted
    -      + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
    -      + '|<',  // A '<' that does not begin a larger chunk
    -      'g');
    -  var pr_commentPrefix = /^<\!--/;
    -  var pr_cdataPrefix = /^<!\[CDATA\[/;
    -  var pr_brPrefix = /^<br\b/i;
    -  var pr_tagNameRe = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;
    -
    -  /** split markup into chunks of html tags (style null) and
    -    * plain text (style {@link #PR_PLAIN}), converting tags which are
    -    * significant for tokenization (<br>) into their textual equivalent.
    -    *
    -    * @param {string} s html where whitespace is considered significant.
    -    * @return {Object} source code and extracted tags.
    -    * @private
    -    */
    -  function extractTags(s) {
    -    // since the pattern has the 'g' modifier and defines no capturing groups,
    -    // this will return a list of all chunks which we then classify and wrap as
    -    // PR_Tokens
    -    var matches = s.match(pr_chunkPattern);
    -    var sourceBuf = [];
    -    var sourceBufLen = 0;
    -    var extractedTags = [];
    -    if (matches) {
    -      for (var i = 0, n = matches.length; i < n; ++i) {
    -        var match = matches[i];
    -        if (match.length > 1 && match.charAt(0) === '<') {
    -          if (pr_commentPrefix.test(match)) { continue; }
    -          if (pr_cdataPrefix.test(match)) {
    -            // strip CDATA prefix and suffix.  Don't unescape since it's CDATA
    -            sourceBuf.push(match.substring(9, match.length - 3));
    -            sourceBufLen += match.length - 12;
    -          } else if (pr_brPrefix.test(match)) {
    -            // <br> tags are lexically significant so convert them to text.
    -            // This is undone later.
    -            sourceBuf.push('\n');
    -            ++sourceBufLen;
    -          } else {
    -            if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
    -              // A <span class="nocode"> will start a section that should be
    -              // ignored.  Continue walking the list until we see a matching end
    -              // tag.
    -              var name = match.match(pr_tagNameRe)[2];
    -              var depth = 1;
    -              var j;
    -              end_tag_loop:
    -              for (j = i + 1; j < n; ++j) {
    -                var name2 = matches[j].match(pr_tagNameRe);
    -                if (name2 && name2[2] === name) {
    -                  if (name2[1] === '/') {
    -                    if (--depth === 0) { break end_tag_loop; }
    -                  } else {
    -                    ++depth;
    -                  }
    -                }
    -              }
    -              if (j < n) {
    -                extractedTags.push(
    -                    sourceBufLen, matches.slice(i, j + 1).join(''));
    -                i = j;
    -              } else {  // Ignore unclosed sections.
    -                extractedTags.push(sourceBufLen, match);
    -              }
    -            } else {
    -              extractedTags.push(sourceBufLen, match);
    -            }
    -          }
    -        } else {
    -          var literalText = htmlToText(match);
    -          sourceBuf.push(literalText);
    -          sourceBufLen += literalText.length;
    -        }
    -      }
    -    }
    -    return { source: sourceBuf.join(''), tags: extractedTags };
    -  }
    -
    -  /** True if the given tag contains a class attribute with the nocode class. */
    -  function isNoCodeTag(tag) {
    -    return !!tag
    -        // First canonicalize the representation of attributes
    -        .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
    -                 ' $1="$2$3$4"')
    -        // Then look for the attribute we want.
    -        .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
    -  }
    -
    -  /**
    -   * Apply the given language handler to sourceCode and add the resulting
    -   * decorations to out.
    -   * @param {number} basePos the index of sourceCode within the chunk of source
    -   *    whose decorations are already present on out.
    -   */
    -  function appendDecorations(basePos, sourceCode, langHandler, out) {
    -    if (!sourceCode) { return; }
    -    var job = {
    -      source: sourceCode,
    -      basePos: basePos
    -    };
    -    langHandler(job);
    -    out.push.apply(out, job.decorations);
    -  }
    -
    -  /** Given triples of [style, pattern, context] returns a lexing function,
    -    * The lexing function interprets the patterns to find token boundaries and
    -    * returns a decoration list of the form
    -    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    -    * where index_n is an index into the sourceCode, and style_n is a style
    -    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    -    * all characters in sourceCode[index_n-1:index_n].
    -    *
    -    * The stylePatterns is a list whose elements have the form
    -    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    -    *
    -    * Style is a style constant like PR_PLAIN, or can be a string of the
    -    * form 'lang-FOO', where FOO is a language extension describing the
    -    * language of the portion of the token in $1 after pattern executes.
    -    * E.g., if style is 'lang-lisp', and group 1 contains the text
    -    * '(hello (world))', then that portion of the token will be passed to the
    -    * registered lisp handler for formatting.
    -    * The text before and after group 1 will be restyled using this decorator
    -    * so decorators should take care that this doesn't result in infinite
    -    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    -    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    -    * '<script>foo()<\/script>', which would cause the current decorator to
    -    * be called with '<script>' which would not match the same rule since
    -    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    -    * the generic tag rule.  The handler registered for the 'js' extension would
    -    * then be called with 'foo()', and finally, the current decorator would
    -    * be called with '<\/script>' which would not match the original rule and
    -    * so the generic tag rule would identify it as a tag.
    -    *
    -    * Pattern must only match prefixes, and if it matches a prefix, then that
    -    * match is considered a token with the same style.
    -    *
    -    * Context is applied to the last non-whitespace, non-comment token
    -    * recognized.
    -    *
    -    * Shortcut is an optional string of characters, any of which, if the first
    -    * character, gurantee that this pattern and only this pattern matches.
    -    *
    -    * @param {Array} shortcutStylePatterns patterns that always start with
    -    *   a known character.  Must have a shortcut string.
    -    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    -    *   order if the shortcut ones fail.  May have shortcuts.
    -    *
    -    * @return {function (Object)} a
    -    *   function that takes source code and returns a list of decorations.
    -    */
    -  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    -    var shortcuts = {};
    -    var tokenizer;
    -    (function () {
    -      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    -      var allRegexs = [];
    -      var regexKeys = {};
    -      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    -        var patternParts = allPatterns[i];
    -        var shortcutChars = patternParts[3];
    -        if (shortcutChars) {
    -          for (var c = shortcutChars.length; --c >= 0;) {
    -            shortcuts[shortcutChars.charAt(c)] = patternParts;
    -          }
    -        }
    -        var regex = patternParts[1];
    -        var k = '' + regex;
    -        if (!regexKeys.hasOwnProperty(k)) {
    -          allRegexs.push(regex);
    -          regexKeys[k] = null;
    -        }
    -      }
    -      allRegexs.push(/[\0-\uffff]/);
    -      tokenizer = combinePrefixPatterns(allRegexs);
    -    })();
    -
    -    var nPatterns = fallthroughStylePatterns.length;
    -    var notWs = /\S/;
    -
    -    /**
    -     * Lexes job.source and produces an output array job.decorations of style
    -     * classes preceded by the position at which they start in job.source in
    -     * order.
    -     *
    -     * @param {Object} job an object like {@code
    -     *    source: {string} sourceText plain text,
    -     *    basePos: {int} position of job.source in the larger chunk of
    -     *        sourceCode.
    -     * }
    -     */
    -    var decorate = function (job) {
    -      var sourceCode = job.source, basePos = job.basePos;
    -      /** Even entries are positions in source in ascending order.  Odd enties
    -        * are style markers (e.g., PR_COMMENT) that run from that position until
    -        * the end.
    -        * @type {Array.<number|string>}
    -        */
    -      var decorations = [basePos, PR_PLAIN];
    -      var pos = 0;  // index into sourceCode
    -      var tokens = sourceCode.match(tokenizer) || [];
    -      var styleCache = {};
    -
    -      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    -        var token = tokens[ti];
    -        var style = styleCache[token];
    -        var match = void 0;
    -
    -        var isEmbedded;
    -        if (typeof style === 'string') {
    -          isEmbedded = false;
    -        } else {
    -          var patternParts = shortcuts[token.charAt(0)];
    -          if (patternParts) {
    -            match = token.match(patternParts[1]);
    -            style = patternParts[0];
    -          } else {
    -            for (var i = 0; i < nPatterns; ++i) {
    -              patternParts = fallthroughStylePatterns[i];
    -              match = token.match(patternParts[1]);
    -              if (match) {
    -                style = patternParts[0];
    -                break;
    -              }
    -            }
    -
    -            if (!match) {  // make sure that we make progress
    -              style = PR_PLAIN;
    -            }
    -          }
    -
    -          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    -          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    -            isEmbedded = false;
    -            style = PR_SOURCE;
    -          }
    -
    -          if (!isEmbedded) { styleCache[token] = style; }
    -        }
    -
    -        var tokenStart = pos;
    -        pos += token.length;
    -
    -        if (!isEmbedded) {
    -          decorations.push(basePos + tokenStart, style);
    -        } else {  // Treat group 1 as an embedded block of source code.
    -          var embeddedSource = match[1];
    -          var embeddedSourceStart = token.indexOf(embeddedSource);
    -          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    -          if (match[2]) {
    -            // If embeddedSource can be blank, then it would match at the
    -            // beginning which would cause us to infinitely recurse on the
    -            // entire token, so we catch the right context in match[2].
    -            embeddedSourceEnd = token.length - match[2].length;
    -            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    -          }
    -          var lang = style.substring(5);
    -          // Decorate the left of the embedded source
    -          appendDecorations(
    -              basePos + tokenStart,
    -              token.substring(0, embeddedSourceStart),
    -              decorate, decorations);
    -          // Decorate the embedded source
    -          appendDecorations(
    -              basePos + tokenStart + embeddedSourceStart,
    -              embeddedSource,
    -              langHandlerForExtension(lang, embeddedSource),
    -              decorations);
    -          // Decorate the right of the embedded section
    -          appendDecorations(
    -              basePos + tokenStart + embeddedSourceEnd,
    -              token.substring(embeddedSourceEnd),
    -              decorate, decorations);
    -        }
    -      }
    -      job.decorations = decorations;
    -    };
    -    return decorate;
    -  }
    -
    -  /** returns a function that produces a list of decorations from source text.
    -    *
    -    * This code treats ", ', and ` as string delimiters, and \ as a string
    -    * escape.  It does not recognize perl's qq() style strings.
    -    * It has no special handling for double delimiter escapes as in basic, or
    -    * the tripled delimiters used in python, but should work on those regardless
    -    * although in those cases a single string literal may be broken up into
    -    * multiple adjacent string literals.
    -    *
    -    * It recognizes C, C++, and shell style comments.
    -    *
    -    * @param {Object} options a set of optional parameters.
    -    * @return {function (Object)} a function that examines the source code
    -    *     in the input job and builds the decoration list.
    -    */
    -  function sourceDecorator(options) {
    -    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    -    if (options['tripleQuotedStrings']) {
    -      // '''multi-line-string''', 'single-line-string', and double-quoted
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    -           null, '\'"']);
    -    } else if (options['multiLineStrings']) {
    -      // 'multi-line-string', "multi-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    -           null, '\'"`']);
    -    } else {
    -      // 'single-line-string', "single-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,
    -           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    -           null, '"\'']);
    -    }
    -    if (options['verbatimStrings']) {
    -      // verbatim-string-literal production from the C# grammar.  See issue 93.
    -      fallthroughStylePatterns.push(
    -          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    -    }
    -    if (options['hashComments']) {
    -      if (options['cStyleComments']) {
    -        // Stop C preprocessor declarations at an unclosed open comment
    -        shortcutStylePatterns.push(
    -            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
    -             null, '#']);
    -        fallthroughStylePatterns.push(
    -            [PR_STRING,
    -             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
    -             null]);
    -      } else {
    -        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    -      }
    -    }
    -    if (options['cStyleComments']) {
    -      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    -      fallthroughStylePatterns.push(
    -          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    -    }
    -    if (options['regexLiterals']) {
    -      var REGEX_LITERAL = (
    -          // A regular expression literal starts with a slash that is
    -          // not followed by * or / so that it is not confused with
    -          // comments.
    -          '/(?=[^/*])'
    -          // and then contains any number of raw characters,
    -          + '(?:[^/\\x5B\\x5C]'
    -          // escape sequences (\x5C),
    -          +    '|\\x5C[\\s\\S]'
    -          // or non-nesting character sets (\x5B\x5D);
    -          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
    -          // finally closed by a /.
    -          + '/');
    -      fallthroughStylePatterns.push(
    -          ['lang-regex',
    -           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    -           ]);
    -    }
    -
    -    var keywords = options['keywords'].replace(/^\s+|\s+$/g, '');
    -    if (keywords.length) {
    -      fallthroughStylePatterns.push(
    -          [PR_KEYWORD,
    -           new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]);
    -    }
    -
    -    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    -    fallthroughStylePatterns.push(
    -        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    -        [PR_COMMENT,     /^.*?\*.*/],
    -		[PR_VAR, /^\$[a-z]{1}[a-z_]+/i, null],
    -		[PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_TYPE,        /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],
    -        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_LITERAL,
    -         new RegExp(
    -             '^(?:'
    -             // A hex number
    -             + '0x[a-f0-9]+'
    -             // or an octal or decimal number,
    -             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    -             // possibly in scientific notation
    -             + '(?:e[+\\-]?\\d+)?'
    -             + ')'
    -             // with an optional modifier like UL for unsigned long
    -             + '[a-z]*', 'i'),
    -         null, '0123456789'],
    -        [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]);
    -
    -    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    -  }
    -
    -  var decorateSource = sourceDecorator({
    -        'keywords': ALL_KEYWORDS,
    -        'hashComments': true,
    -        'cStyleComments': true,
    -        'multiLineStrings': true,
    -        'regexLiterals': true
    -      });
    -
    -  /** Breaks {@code job.source} around style boundaries in
    -    * {@code job.decorations} while re-interleaving {@code job.extractedTags},
    -    * and leaves the result in {@code job.prettyPrintedHtml}.
    -    * @param {Object} job like {
    -    *    source: {string} source as plain text,
    -    *    extractedTags: {Array.<number|string>} extractedTags chunks of raw
    -    *                   html preceded by their position in {@code job.source}
    -    *                   in order
    -    *    decorations: {Array.<number|string} an array of style classes preceded
    -    *                 by the position at which they start in job.source in order
    -    * }
    -    * @private
    -    */
    -  function recombineTagsAndDecorations(job) {
    -    var sourceText = job.source;
    -    var extractedTags = job.extractedTags;
    -    var decorations = job.decorations;
    -
    -    var html = [];
    -    // index past the last char in sourceText written to html
    -    var outputIdx = 0;
    -
    -    var openDecoration = null;
    -    var currentDecoration = null;
    -    var tagPos = 0;  // index into extractedTags
    -    var decPos = 0;  // index into decorations
    -    var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);
    -
    -    var adjacentSpaceRe = /([\r\n ]) /g;
    -    var startOrSpaceRe = /(^| ) /gm;
    -    var newlineRe = /\r\n?|\n/g;
    -    var trailingSpaceRe = /[ \r\n]$/;
    -    var lastWasSpace = true;  // the last text chunk emitted ended with a space.
    -
    -    // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-
    -    var isIE678 = window['_pr_isIE6']();
    -    var lineBreakHtml = (
    -        isIE678
    -        ? (job.sourceNode.tagName === 'PRE'
    -           // Use line feeds instead of <br>s so that copying and pasting works
    -           // on IE.
    -           // Doing this on other browsers breaks lots of stuff since \r\n is
    -           // treated as two newlines on Firefox.
    -           ? (isIE678 === 6 ? '&#160;\r\n' :
    -              isIE678 === 7 ? '&#160;<br>\r' : '&#160;\r')
    -           // IE collapses multiple adjacent <br>s into 1 line break.
    -           // Prefix every newline with '&#160;' to prevent such behavior.
    -           // &nbsp; is the same as &#160; but works in XML as well as HTML.
    -           : '&#160;<br />')
    -        : '<br />');
    -
    -    // Look for a class like linenums or linenums:<n> where <n> is the 1-indexed
    -    // number of the first line.
    -    var numberLines = job.sourceNode.className.match(/\blinenums\b(?::(\d+))?/);
    -    var lineBreaker;
    -    if (numberLines) {
    -      var lineBreaks = [];
    -      for (var i = 0; i < 10; ++i) {
    -        lineBreaks[i] = lineBreakHtml + '</li><li class="L' + i + '">';
    -      }
    -      var lineNum = numberLines[1] && numberLines[1].length 
    -          ? numberLines[1] - 1 : 0;  // Lines are 1-indexed
    -      html.push('<ol class="linenums"><li class="L', (lineNum) % 10, '"');
    -      if (lineNum) {
    -        html.push(' value="', lineNum + 1, '"');
    -      }
    -      html.push('>');
    -      lineBreaker = function () {
    -        var lb = lineBreaks[++lineNum % 10];
    -        // If a decoration is open, we need to close it before closing a list-item
    -        // and reopen it on the other side of the list item.
    -        return openDecoration
    -            ? ('</span>' + lb + '<span class="' + openDecoration + '">') : lb;
    -      };
    -    } else {
    -      lineBreaker = lineBreakHtml;
    -    }
    -
    -    // A helper function that is responsible for opening sections of decoration
    -    // and outputing properly escaped chunks of source
    -    function emitTextUpTo(sourceIdx) {
    -      if (sourceIdx > outputIdx) {
    -        if (openDecoration && openDecoration !== currentDecoration) {
    -          // Close the current decoration
    -          html.push('</span>');
    -          openDecoration = null;
    -        }
    -        if (!openDecoration && currentDecoration) {
    -          openDecoration = currentDecoration;
    -          html.push('<span class="', openDecoration, '">');
    -        }
    -        // This interacts badly with some wikis which introduces paragraph tags
    -        // into pre blocks for some strange reason.
    -        // It's necessary for IE though which seems to lose the preformattedness
    -        // of <pre> tags when their innerHTML is assigned.
    -        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
    -        // and it serves to undo the conversion of <br>s to newlines done in
    -        // chunkify.
    -        var htmlChunk = textToHtml(
    -            tabExpander(sourceText.substring(outputIdx, sourceIdx)))
    -            .replace(lastWasSpace
    -                     ? startOrSpaceRe
    -                     : adjacentSpaceRe, '$1&#160;');
    -        // Keep track of whether we need to escape space at the beginning of the
    -        // next chunk.
    -        lastWasSpace = trailingSpaceRe.test(htmlChunk);
    -        html.push(htmlChunk.replace(newlineRe, lineBreaker));
    -        outputIdx = sourceIdx;
    -      }
    -    }
    -
    -    while (true) {
    -      // Determine if we're going to consume a tag this time around.  Otherwise
    -      // we consume a decoration or exit.
    -      var outputTag;
    -      if (tagPos < extractedTags.length) {
    -        if (decPos < decorations.length) {
    -          // Pick one giving preference to extractedTags since we shouldn't open
    -          // a new style that we're going to have to immediately close in order
    -          // to output a tag.
    -          outputTag = extractedTags[tagPos] <= decorations[decPos];
    -        } else {
    -          outputTag = true;
    -        }
    -      } else {
    -        outputTag = false;
    -      }
    -      // Consume either a decoration or a tag or exit.
    -      if (outputTag) {
    -        emitTextUpTo(extractedTags[tagPos]);
    -        if (openDecoration) {
    -          // Close the current decoration
    -          html.push('</span>');
    -          openDecoration = null;
    -        }
    -        html.push(extractedTags[tagPos + 1]);
    -        tagPos += 2;
    -      } else if (decPos < decorations.length) {
    -        emitTextUpTo(decorations[decPos]);
    -        currentDecoration = decorations[decPos + 1];
    -        decPos += 2;
    -      } else {
    -        break;
    -      }
    -    }
    -    emitTextUpTo(sourceText.length);
    -    if (openDecoration) {
    -      html.push('</span>');
    -    }
    -    if (numberLines) { html.push('</li></ol>'); }
    -    job.prettyPrintedHtml = html.join('');
    -  }
    -
    -  /** Maps language-specific file extensions to handlers. */
    -  var langHandlerRegistry = {};
    -  /** Register a language handler for the given file extensions.
    -    * @param {function (Object)} handler a function from source code to a list
    -    *      of decorations.  Takes a single argument job which describes the
    -    *      state of the computation.   The single parameter has the form
    -    *      {@code {
    -    *        source: {string} as plain text.
    -    *        decorations: {Array.<number|string>} an array of style classes
    -    *                     preceded by the position at which they start in
    -    *                     job.source in order.
    -    *                     The language handler should assigned this field.
    -    *        basePos: {int} the position of source in the larger source chunk.
    -    *                 All positions in the output decorations array are relative
    -    *                 to the larger source chunk.
    -    *      } }
    -    * @param {Array.<string>} fileExtensions
    -    */
    -  function registerLangHandler(handler, fileExtensions) {
    -    for (var i = fileExtensions.length; --i >= 0;) {
    -      var ext = fileExtensions[i];
    -      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    -        langHandlerRegistry[ext] = handler;
    -      } else if ('console' in window) {
    -        console['warn']('cannot override language handler %s', ext);
    -      }
    -    }
    -  }
    -  function langHandlerForExtension(extension, source) {
    -    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    -      // Treat it as markup if the first non whitespace character is a < and
    -      // the last non-whitespace character is a >.
    -      extension = /^\s*</.test(source)
    -          ? 'default-markup'
    -          : 'default-code';
    -    }
    -    return langHandlerRegistry[extension];
    -  }
    -  registerLangHandler(decorateSource, ['default-code']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [],
    -          [
    -		   [PR_PLAIN,       /^[^<?]+/],
    -           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    -           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    -           // Unescaped content in an unknown language
    -           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    -           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    -           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    -           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    -           // Unescaped content in javascript.  (Or possibly vbscript).
    -           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    -           // Contains unescaped stylesheet content
    -           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    -           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    -          ]),
    -      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [
    -		   [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    -           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    -           ],
    -          [
    -		  [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    -           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    -           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    -           [PR_PUNCTUATION,  /^[=<>\/]+/],
    -           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    -           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    -           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    -           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    -           ]),
    -      ['in.tag']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CPP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true
    -        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': 'null true false'
    -        }), ['json']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CSHARP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true,
    -          'verbatimStrings': true
    -        }), ['cs']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JAVA_KEYWORDS,
    -          'cStyleComments': true
    -        }), ['java']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': SH_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true
    -        }), ['bsh', 'csh', 'sh']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PYTHON_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'tripleQuotedStrings': true
    -        }), ['cv', 'py']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PERL_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': true
    -        }), ['perl', 'pl', 'pm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': RUBY_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': true
    -        }), ['rb']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JSCRIPT_KEYWORDS,
    -          'cStyleComments': true,
    -          'regexLiterals': true
    -        }), ['js']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    -
    -  function applyDecorator(job) {
    -    var sourceCodeHtml = job.sourceCodeHtml;
    -    var opt_langExtension = job.langExtension;
    -
    -    // Prepopulate output in case processing fails with an exception.
    -    job.prettyPrintedHtml = sourceCodeHtml;
    -
    -    try {
    -      // Extract tags, and convert the source code to plain text.
    -      var sourceAndExtractedTags = extractTags(sourceCodeHtml);
    -      /** Plain text. @type {string} */
    -      var source = sourceAndExtractedTags.source;
    -      job.source = source;
    -      job.basePos = 0;
    -
    -      /** Even entries are positions in source in ascending order.  Odd entries
    -        * are tags that were extracted at that position.
    -        * @type {Array.<number|string>}
    -        */
    -      job.extractedTags = sourceAndExtractedTags.tags;
    -
    -      // Apply the appropriate language handler
    -      langHandlerForExtension(opt_langExtension, source)(job);
    -      // Integrate the decorations and tags back into the source code to produce
    -      // a decorated html string which is left in job.prettyPrintedHtml.
    -      recombineTagsAndDecorations(job);
    -    } catch (e) {
    -      if ('console' in window) {
    -        console['log'](e && e['stack'] ? e['stack'] : e);
    -      }
    -    }
    -  }
    -
    -  function prettyPrintOne(sourceCodeHtml, opt_langExtension) {
    -    var job = {
    -      sourceCodeHtml: sourceCodeHtml,
    -      langExtension: opt_langExtension
    -    };
    -    applyDecorator(job);
    -    return job.prettyPrintedHtml;
    -  }
    -
    -  function prettyPrint(opt_whenDone) {
    -    function byTagName(tn) { return document.getElementsByTagName(tn); }
    -    // fetch a list of nodes to rewrite
    -    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    -    var elements = [];
    -    for (var i = 0; i < codeSegments.length; ++i) {
    -      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    -        elements.push(codeSegments[i][j]);
    -      }
    -    }
    -    codeSegments = null;
    -
    -    var clock = Date;
    -    if (!clock['now']) {
    -      clock = { 'now': function () { return (new Date).getTime(); } };
    -    }
    -
    -    // The loop is broken into a series of continuations to make sure that we
    -    // don't make the browser unresponsive when rewriting a large page.
    -    var k = 0;
    -    var prettyPrintingJob;
    -
    -    function doWork() {
    -      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
    -                     clock.now() + 250 /* ms */ :
    -                     Infinity);
    -      for (; k < elements.length && clock.now() < endTime; k++) {
    -        var cs = elements[k];
    -        if (cs.className && cs.className.indexOf('preformatted') >= 0) {
    -          // If the classes includes a language extensions, use it.
    -          // Language extensions can be specified like
    -          //     <pre class="prettyprint lang-cpp">
    -          // the language extension "cpp" is used to find a language handler as
    -          // passed to PR_registerLangHandler.
    -          var langExtension = cs.className.match(/\blang-(\w+)\b/);
    -          if (langExtension) { langExtension = langExtension[1]; }
    -
    -          // make sure this is not nested in an already prettified element
    -          var nested = false;
    -          for (var p = cs.parentNode; p; p = p.parentNode) {
    -            if ((p.tagName === 'pre' || p.tagName === 'code' ||
    -                 p.tagName === 'xmp') &&
    -                p.className && p.className.indexOf('preformatted') >= 0) {
    -              nested = true;
    -              break;
    -            }
    -          }
    -          if (!nested) {
    -            // fetch the content as a snippet of properly escaped HTML.
    -            // Firefox adds newlines at the end.
    -            var content = getInnerHtml(cs);
    -            content = content.replace(/(?:\r\n?|\n)$/, '');
    -
    -            // do the pretty printing
    -            prettyPrintingJob = {
    -              sourceCodeHtml: content,
    -              langExtension: langExtension,
    -              sourceNode: cs
    -            };
    -            applyDecorator(prettyPrintingJob);
    -            replaceWithPrettyPrintedHtml();
    -          }
    -        }
    -      }
    -      if (k < elements.length) {
    -        // finish up in a continuation
    -        setTimeout(doWork, 250);
    -      } else if (opt_whenDone) {
    -        opt_whenDone();
    -      }
    -    }
    -
    -    function replaceWithPrettyPrintedHtml() {
    -      var newContent = prettyPrintingJob.prettyPrintedHtml;
    -      if (!newContent) { return; }
    -      var cs = prettyPrintingJob.sourceNode;
    -
    -      // push the prettified html back into the tag.
    -      if (!isRawContent(cs)) {
    -        // just replace the old html with the new
    -        cs.innerHTML = newContent;
    -      } else {
    -        // we need to change the tag to a <pre> since <xmp>s do not allow
    -        // embedded tags such as the span tags used to attach styles to
    -        // sections of source code.
    -        var pre = document.createElement('PRE');
    -        for (var i = 0; i < cs.attributes.length; ++i) {
    -          var a = cs.attributes[i];
    -          if (a.specified) {
    -            var aname = a.name.toLowerCase();
    -            if (aname === 'class') {
    -              pre.className = a.value;  // For IE 6
    -            } else {
    -              pre.setAttribute(a.name, a.value);
    -            }
    -          }
    -        }
    -        pre.innerHTML = newContent;
    -
    -        // remove the old
    -        cs.parentNode.replaceChild(pre, cs);
    -        cs = pre;
    -      }
    -    }
    -
    -    doWork();
    -  }
    -
    -  window['PR_normalizedHtml'] = normalizedHtml;
    -  window['prettyPrintOne'] = prettyPrintOne;
    -  window['prettyPrint'] = prettyPrint;
    -  window['PR'] = {
    -        'combinePrefixPatterns': combinePrefixPatterns,
    -        'createSimpleLexer': createSimpleLexer,
    -        'registerLangHandler': registerLangHandler,
    -        'sourceDecorator': sourceDecorator,
    -        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    -        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    -        'PR_COMMENT': PR_COMMENT,
    -        'PR_DECLARATION': PR_DECLARATION,
    -        'PR_KEYWORD': PR_KEYWORD,
    -        'PR_LITERAL': PR_LITERAL,
    -        'PR_NOCODE': PR_NOCODE,
    -        'PR_PLAIN': PR_PLAIN,
    -        'PR_PUNCTUATION': PR_PUNCTUATION,
    -        'PR_SOURCE': PR_SOURCE,
    -        'PR_STRING': PR_STRING,
    -        'PR_TAG': PR_TAG,
    -        'PR_TYPE': PR_TYPE
    -      };
    -})();
    diff --git a/build/aps/Limitations of APS Support in the Panel_fichiers/stylesheet.css b/build/aps/Limitations of APS Support in the Panel_fichiers/stylesheet.css
    deleted file mode 100644
    index f791ddf4ea8..00000000000
    --- a/build/aps/Limitations of APS Support in the Panel_fichiers/stylesheet.css	
    +++ /dev/null
    @@ -1,1571 +0,0 @@
    -body
    -{ 
    -background: #FFFFFF
    -}
    -
    -/*ol.listalfa
    -{
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }*/
    -li.listalpha {
    -        list-style-type: lower-alpha;
    -		font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -/*ol.listalfa2
    -{
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }*/
    -li.listalpha2 {
    -        list-style-type: lower-alpha;
    -		font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -		  line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -/*ol.listalfa3
    -{
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }*/
    -li.listalpha3 {
    -        list-style-type: lower-alpha;
    -		font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }	   
    -
    -/*li.listalpha2, li.listalpha, li.listalpha3
    -{
    -list-style-type: lower-alpha;
    -} */
    -
    -
    -li.tablelistbullet {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: 10pt;
    -        margin: 0px;
    -        padding: 5px;
    -	vertical-align: top;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -
    -p.centered {
    -
    -        text-align: center;
    -}
    -
    -p.listcontinue3 {
    -    margin-left: 30pt;
    -  }
    -
    -.preformattedbold2ndlvl {
    -  display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: bold;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 20pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -
    -}
    -
    -
    -.preformattedseclevel {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 20pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -}
    -
    -.prcontinuous 
    -{font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -       }
    -
    -.prefblue 
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-size: 10pt;
    -        color: #0000FF;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.prefred 
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-size: 10pt;
    -        color: #FF0000;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.prefdarkblue 
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-weight: bold;
    -        font-size: 10pt;
    -        color: #000080;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.prefgrey 
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-size: 10pt;
    -        color: #EA8110;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -
    -.expandingblock 
    -{font-family: "Tahoma", verdana, arial, helvetica, sans-serif;
    -        border-color: #AFAFAF;
    -        border-top-style: dotted;
    -        border-top-width: 1px;
    -        border-top-color: #AFAFAF;
    -        border-bottom-style: dotted;
    -        border-bottom-width: 1px;
    -        border-bottom-color: #AFAFAF;
    -        border-left-style: dotted;
    -        border-left-width: 1px;
    -        border-left-color: #AFAFAF;
    -        border-right-style: dotted;
    -        border-right-width: 1px;
    -        border-right-color: #AFAFAF;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -	padding-left: 3px;
    -	padding-right: 3px;
    -	padding-top: 3px;
    -	padding-bottom: 3px;
    -
    -       }
    -
    -
    -
    -.copyright {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        font-style: italic;
    -        color: #000000;
    -        margin: 9px 0px 9px 0px;
    -        padding: 0px;
    -}
    -
    -/* Nov-14 begin */
    -
    -.pagenavigation {
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	white-space: nowrap;
    -	vertical-align: middle;
    -	margin: 0px;
    -	margin-right: 2px;
    -	padding: 3px;
    -	padding-right: 4px;
    -	background-color: #f0f1f5;
    -}
    -*html .pagenavigation {
    -	margin-top: -7px;
    -	position: relative;
    -}
    -
    -.pagenavigation a, .pagenavigation a:link, .pagenavigation a:visited {
    -	color: #000000;
    -	text-decoration: none;	
    -}
    -.pagenavigation a:hover {
    -	text-decoration: none;
    -	color: #666666;
    -}
    -
    -/* end */
    -
    -
    -
    -.topBody {
    -	background: #eeeeee;
    -}
    -.nav {
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-left: 7px;
    -	padding-right: 5px;
    -	padding-top: 4px;
    -}
    -.nav a, .nav a:link, .nav a:visited {
    -	color: #000000;
    -	text-decoration: none;	
    -}
    -.nav a:hover {
    -	text-decoration: none;
    -	color: #666666;
    -}
    -
    -td.navTabActive {
    -	color: #1f202c;
    -	text-decoration: none;
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-top: 4px;  
    -	padding-bottom: 0px; 
    -	padding-left: 8px; 
    -	padding-right: 8px;
    -	font-weight: bold;
    -	background-image: url('nav_bg_active.gif');
    -	background-repeat: repeat-x;
    -}
    -td.navTab {
    -	padding-top: 3px;
    -}
    -.navTab a, .navTab a:link, .navTab a:visited {
    -	color: #000000;
    -	text-decoration: none;
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-top: 4px;
    -	padding-bottom: 0px;
    -	padding-left: 8px;
    -	padding-right: 8px;
    -}
    -.navTab a:hover {
    -	color: #1f202c;
    -	text-decoration: none;
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-top: 5px;
    -	padding-bottom: 7px;
    -	padding-left: 8px;
    -	padding-right: 8px;
    -	background-image: url('nav_bg_active.gif');
    -	background-repeat: repeat-x;
    -}
    -
    -.navDiv {
    -	vertical-align: middle;
    -}
    -
    -.topFrameTable {
    -	width: 100%;
    -	/*height: 23px;*/
    -	margin: 0px;
    -	padding: 0px;
    -	border-bottom: 2px solid #d6d6d6;
    -   background-image: url('nav_bg.gif');
    -	background-repeat: repeat-x;
    -}
    -.topFrameTabs {
    -	margin-left: 3px;
    -	margin-top: 0px;
    -}
    -
    -.headerTable {
    -	width: 100%;
    -	vertical-align: top;
    -	height: 23px;
    -	background: #588cc7;
    -}
    -.headerTd {
    -	vertical-align: middle;
    -	font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -	color: #ffffff;
    -	font-size: 12px;
    -	padding-top: 2px;
    -	padding-bottom: 3px;
    -	padding-left: 7px;
    -	padding-right: 5px;
    -}
    -
    -.tocTable {
    -	width: 100%;
    -	vertical-align: top;
    -}
    -.tocLevel1 {
    -	margin: -14px 0 0 0;
    -	padding: 0px;
    -}
    -
    -a.itemActive,
    -a.itemActive:link,
    -a.itemActive:visited,
    -a.itemActive:active {
    -	color: #ffffff;
    -	line-height: 16px;
    -	padding-top: 1px;
    -	padding-bottom: 2px;
    -	padding-left: 3px;
    -	padding-right: 3px;
    -	background-color:#6697cc;
    -}
    -
    -a, a:link,
    -.relateditem a, .relateditem a:link,
    -.tocLevel1 a, .tocLevel1 a:link {
    -	color: #0049b7;
    -	text-decoration: none;
    -}
    -a:hover,
    -.relateditem a:hover,
    -.tocLevel1 a:hover {
    -	text-decoration: underline;
    -}
    -a:visited,
    -.relateditem a:visited,
    -.tocLevel1 a:visited {
    -	color: #003380;
    -}
    -.relateditem a {
    -	text-decoration: none;
    -}
    -
    -.table {
    -	margin-top: 5px;
    -}
    -.tableDescription {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -		  font-weight: bold;
    -        color: #444444;
    -        margin-top: 15px;
    -        margin-bottom: 7px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding: 0px;
    -		  text-align: left;
    -}
    -
    -.relatedheading {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-weight: bold;
    -        font-size: 8pt;
    -        color: #ffffff;
    -        background-color: #729ecf;
    -        margin-top: 25px;
    -        margin-bottom: 2px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding-top: 2px;
    -        padding-bottom: 2px;
    -        padding-left: 4px;
    -        padding-right: 4px;
    -        border-color: #FFFFFF;
    -        border-right-style: solid;
    -        border-right-width: 1px;
    -        border-right-color: #FFFFFF;
    -}
    -.relateditem {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #f3f8fc;
    -        margin-top: 0px;
    -        margin-bottom: 0px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding-top: 2px;
    -        padding-bottom: 3px;
    -        padding-left: 12px;
    -        padding-right: 15px;
    -        border-color: #FFFFFF;
    -        border-right-style: solid;
    -        border-right-width: 1px;
    -        border-right-color: #FFFFFF;
    -	     border-bottom-style: solid;
    -        border-bottom-width: 2px;
    -        border-bottom-color: #ffffff; 
    -}
    -.bodytext {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        margin: 9px 0px 9px 0px;
    -        padding: 0px;
    -}
    -
    -.tableheading {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -		  font-weight: bold;
    -        font-size: 8pt;
    -		  line-height: 12px;
    -        color: #2f739b; 
    -		  line-height: 11px;
    -        margin: 0px;
    -        padding: 3px;
    -        text-align: center;
    -		  background-color: #f5f8fc;/*eef2f9;*/
    -}
    -.tablebodytext {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        padding: 5px;
    -		  padding-top: 7px;
    -		  vertical-align: top;
    -}
    -
    -.preformatted {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -}
    -
    -
    -.prefcleanxml {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -}
    -
    -
    -
    -
    -.preformatedbold2ndlvl, .preformattedbold {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: bold;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -}
    -.specialbold {
    -        display: inline;
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-weight: bold;
    -        font-size: 8pt;
    -        color: #e64a00;
    -        background-color: inherit;
    -        word-spacing: 0pt;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        }
    -.emphasis {
    -        display: inline;
    -        font-style: italic;
    -        color: inherit;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.monospace {
    -        display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        color: inherit;
    -		  font-size: 10pt;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.monospaceitalics {
    -        display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: italic;
    -        color: inherit;
    -		  font-size: 10pt;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -ul.listbullet {
    -        list-style-type: disk;
    -        list-style-image: none;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 0px;
    -        }
    -li.listbullet {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.note {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fffdec;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0cm;
    -        margin-right: 0pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #f8c701;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: 97%;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.buttons {
    -        display: inline;
    -        font-weight: bold;
    -        color: #444444;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -ol.listnumber {
    -        list-style-type: Decimal;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }
    -li.listnumber {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.procedureheading {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-variant: normal;
    -        font-weight: bold;
    -        font-size: 9pt;
    -        color: #266fa4; /* 266fa4 1b64a0 */
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 12pt;
    -        margin-bottom: 0px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding-top: 0px;
    -        padding-bottom: 5px;
    -        padding-left: 0px;
    -        padding-right: 0px;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ol.procedurelistnumber {
    -        list-style-type: Decimal;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 10px;
    -        }
    -li.procedurelistnumber {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6px;
    -        margin-bottom: 0px;
    -        margin-left: 0px;
    -        margin-right: 0pxt;
    -        padding: 0px;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listcontinue {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 5pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ul.listbullet2 {
    -        list-style-type: disk;
    -        list-style-image: none;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 0px;
    -        }
    -li.listbullet2 {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -		  line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listnote {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fffdec;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #f8c701;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: 97%;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.widegraphic {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: center;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listcontinue2 {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 10pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -.listcontinue3 {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 10pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -ul.listbullet3 {
    -        list-style-type: Square;
    -        list-style-image: none;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 0px;
    -        }
    -li.listbullet3 {
    -	     font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ol.procedurelistnumber2 {
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }
    -li.procedurelistnumber2 {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding: 0px;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listnote2 {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fffdec;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #f8c701;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: 97%;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ol.listnumber2 {
    -        list-style-type: Decimal;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }
    -li.listnumber2 {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.warning {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fff5f0;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0cm;
    -        margin-right: 6pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #e64a00;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -.heading1 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -.heading2 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -		  font-size: 12pt;
    -        color: #5c5b64; 
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading3 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading4 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -		  font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading5 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -		  font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading6 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-variant: normal;
    - 		  font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.indexatoz {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-weight: bold;
    -        font-size: 12px;
    -        color: #adadad;
    -        background-color: #f4f4f4;
    -        border: 1px solid #CFCFCF;
    -        margin: -15px -2px 0 -2px;
    -        padding: 6px;
    -		  position: relative;
    -		  z-index:99;
    -       }
    -
    -.indexatoz a:hover {
    -      background-color: #6697cc;
    -      text-decoration: none;
    -      color: #ffffff;
    -      padding: 1px 0;
    -}
    -.indexLetter {
    -	 	  padding-left: 2px;
    -}
    -
    -.indexheading, .indexheading a {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-weight: bold;
    -        font-size: 12pt;
    -        color: #e64a00;
    -		  text-decoration: none;
    -        margin: 0px;
    -        padding: 0px;
    -		  padding-top: 10px;
    -		  margin-top: 12px;
    -		  margin-bottom: 2px;
    -		  margin-right: 2px;
    -		  border-bottom: 1px solid #cfcfcf;
    -}
    -.index1, .index2, .index3 {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        text-decoration: none;
    -        margin: 0px;
    -        padding-top: 3px;
    -        padding-bottom: 0px;
    -        padding-left: 0px;
    -        padding-right: 0px;
    -}
    -.indexlink, .index1link {
    -        padding: 0px;
    -		  padding-top: 3px;
    -		  margin: 0px;
    -}
    -.index1link {
    -		  padding-left: 18px;
    -}
    -.toc {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -		  padding-left: 8px;
    -		  padding-right: 5px;
    -        vertical-align: top;
    -       }
    -span.toc {
    -	line-height: 19px;
    -}
    -		 
    -.searchDetails {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 11px;
    -        color: #666666;
    -        background-color: #ffffff;
    -		  border: 1px solid #CFCFCF;
    -        margin: 5px;
    -		  padding-left: 10px;
    - 		  padding-right: 10px;
    -		  padding-top: 3px;
    -		  padding-bottom: 9px;
    -		  line-height: 20px;
    -}
    -.inputText {
    -		  width: 60%;
    -		  height: 16px;
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 12px;
    -        color: #000000;
    -}
    -form {
    -	margin: 0px;
    -}
    -.search {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        vertical-align: top;
    -        margin: 0px;
    -        padding: 0px 10px;
    -       }
    -.searchFound {
    -	font-weight: bold;
    -	color: #1f202c;
    -	padding-top: 5px;
    -	padding-bottom: 10px;
    -	margin: 0px;
    -}
    -.searchResults {
    -	padding-bottom: 10px;
    -	padding-top: 5px;
    -	margin: 0px;
    -	border-top: 1px solid #cfcfcf;
    -}
    -.searchResults a {
    -	font-weight: bold;
    -}
    -.searchFoundWord {
    -	background-color: #fffdce; 
    -}
    -.searchToTop {
    -	text-align: left;
    -	border-top: 1px solid #cfcfcf;
    -	padding: 7px 0px 15px 0px;
    -	margin: 0px;
    -}
    \ No newline at end of file
    diff --git a/build/aps/README b/build/aps/README
    deleted file mode 100644
    index 6d9b8098977..00000000000
    --- a/build/aps/README
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -README (English)
    -##################################################
    -This directory is dedicated to APS package building
    -##################################################
    -
    -Docs for APS format 1.1:
    -http://www.apsstandard.org/r/doc/aps-format-1.1-packaging-guide/index.htm
    -
    -Docs for APS format 1.2 (need APP-LIST.xml):
    -http://www.apsstandard.org/r/doc/aps-format-1.2-packaging-guide/index.htm
    -
    -
    -To check an APS package on Debian:
    -* Install libgdiplus with 
    -apt-get install libgdiplus
    -* Install apslint.exe (http://www.apsstandard.org/r/doc/aps-format-1.2-packaging-guide/57414.htm)
    -tar -xvf xxxx.tgz 
    -* Go into directory of apslint and run command
    -mono ./apslint.exe '/media/DATA/Mes Developpements/dolibarr/build/dolibarr-3.1.0-dev.app.zip' 
    -
    diff --git a/build/aps/configure.php b/build/aps/configure.php
    deleted file mode 100755
    index 1b2565e3dc8..00000000000
    --- a/build/aps/configure.php
    +++ /dev/null
    @@ -1,151 +0,0 @@
    -#!/usr/bin/env php
    -<?php
    -/*-----------------------------------------------------
    - *
    - *----------------------------------------------------- */
    -
    -// This is list of predefined variables when script is ran
    -// We have to set them manually to run script outside context.
    -/*putenv('SETTINGS_admin_name=admin');
    -putenv('SETTINGS_admin_password=admin-ad');
    -putenv('BASE_URL_SCHEME=http');
    -putenv('BASE_URL_HOST=localhost');
    -putenv('BASE_URL_PORT=0');
    -putenv('BASE_URL_PATH=/');
    -//putenv('WEB___DIR=/var/wwww/dolibarr/htdocs');      // WEB___DIR is dir to htdocs
    -putenv('WEB___DIR=../htdocs');      // WEB___DIR is dir to htdocs
    -putenv('DB_main_NAME=dolibarr');
    -putenv('DB_main_HOST=localhost');
    -putenv('DB_main_PORT=3306');
    -putenv('DB_main_LOGIN=root');
    -putenv('DB_main_PASSWORD=root');
    -*/
    -
    -// Check parameters
    -if(count($_SERVER['argv']) < 2)
    -{
    -    print "Usage: configure.php (install | upgrade <version> | configure | remove)\n";
    -    exit(1);
    -}
    -$command = $_SERVER['argv'][1]; //$command stores the argument with which the script was invoked.
    -
    -
    -if($command == "install")
    -{
    -    $db_id = 'main';
    -
    -    $rootdir = getenv("WEB___DIR");
    -    if ($rootdir != '/') $rootdir = preg_replace('/\/$/','',$rootdir);  // Remove last /
    -    $datadir = $rootdir.'/dolibarr_documents';
    -
    -    //List of database-related variables that are passed to the configuration
    -    //script. See the 6.3.1.1.1. Environment variables section of the
    -    //Specification for details.
    -    $db_address = getenv("DB_${db_id}_HOST");
    -    $db_port = getenv("DB_${db_id}_PORT");
    -    $dblogin = getenv("DB_${db_id}_LOGIN");
    -    $dbpassword = getenv("DB_${db_id}_PASSWORD");
    -    $dbname = getenv("DB_${db_id}_NAME");
    -
    -
    -    //PHP functions for connecting to the mysql server and
    -    //executing SQL queries.
    -    //mysql_connect($dbaddress, $dblogin, $dbpassword);
    -    //mysql_select_db($dbname);
    -    /*
    -     $sql_queries = file($query_file);
    -     foreach ($sql_queries as $query) mysql_query($query);
    -     */
    -
    -
    -    //Other code to be executed on invoking configure with
    -    //the install argument.
    -
    -    // Create empty config file
    -    $file=$rootdir.'/conf/conf.php';
    -    print "Create conf file ".$file."\n";
    -    $fp = fopen($file, 'wb');
    -    if ($fp)
    -    {
    -        fclose($fp);
    -        chmod($file,0775);
    -    }
    -    else
    -    {
    -        print "configure.php install: Unable to write file $file.\n";
    -        exit(1);
    -    }
    -
    -    // Create empty directory that will be used by software to store uploaded documents
    -    print "Create directory ".$datadir."\n";
    -    @mkdir($datadir);
    -    chmod($datadir,0775);
    -
    -    // Create install.forced.php into htdocs/install directory with value.
    -    // This will set parameters of install for web installer wizard.
    -    $file_source=$rootdir.'/../build/aps/install.forced.php.install';
    -    $file=$rootdir.'/install/install.forced.php';
    -    print "Create file ".$file.' from '.$file_source."\n";
    -
    -    $modify_hash=array(
    -    'WEB___DIR'=>$rootdir,
    -    'DB_'.$db_id.'_HOST'=>$db_address,
    -    'DB_'.$db_id.'_PORT'=>$db_port,
    -    'DB_'.$db_id.'_LOGIN'=>$dblogin,
    -    'DB_'.$db_id.'_PASSWORD'=>$dbpassword,
    -    'DB_'.$db_id.'_NAME'=>$dbname
    -    );
    -
    -    $file_content = fread(fopen($file_source, 'r'), filesize($file_source));
    -    foreach($modify_hash as $param => $val){
    -        $file_content = str_replace($param, php_quote($val), $file_content);
    -    }
    -    $fp = fopen($file, 'wb');
    -    if ($fp)
    -    {
    -        fputs($fp, $file_content);
    -        fputs($fp, "\n");
    -        fclose($fp);
    -        chmod($file,0775);
    -    }
    -    else
    -    {
    -        print "configure.php install: Unable to write file $file.\n";
    -        exit(2);
    -    }
    -
    -    exit(0);
    -}
    -
    -if($command == "remove")
    -{
    -    //Code to be executed on invoking configure with the remove argument
    -    exit(0);
    -}
    -
    -if($command == "upgrade")
    -{
    -    //Code to be executed on invoking configure with the upgrade argument
    -    exit(0);
    -}
    -
    -if($command == "configure")
    -{
    -    //Code to be executed on invoking configure with the configure argument
    -    exit(0);
    -}
    -
    -print "configure.php: Error: unknown command $command.\n";
    -exit(1);
    -
    -
    -
    -// Content of file-util.php we need
    -
    -function php_quote($val)
    -{
    -    $res_val = str_replace("\\", "\\\\", $val);
    -    $res_val = str_replace("'", "\\'", $res_val);
    -    return $res_val;
    -}
    -
    diff --git a/build/aps/install.forced.php.install b/build/aps/install.forced.php.install
    deleted file mode 100644
    index a7a3f03c14c..00000000000
    --- a/build/aps/install.forced.php.install
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -<?php
    -// File to force Dolibarr wizard installer choices.
    -//
    -// This file must be present into htdocs/install directory
    -// during install process to be used.
    -//
    -//
    -$force_install_noedit=1;
    -$force_install_message='KeepDefaultValuesDeb';
    -$force_install_main_data_root='WEB___DIR/dolibarr_documents';
    -$force_install_type='mysqli';
    -$force_install_dbserver='DB_main_HOST';
    -$force_install_port='DB_main_PORT';
    -$force_install_database='DB_main_NAME';
    -$force_install_createdatabase='0';
    -$force_install_databaselogin='DB_main_LOGIN';
    -$force_install_databasepass='DB_main_PASSWORD';
    -$force_install_createuser='0';
    -$force_install_databaserootlogin='';
    -$force_install_databaserootpass='';
    -$force_install_dolibarrlogin='admin';
    -$force_install_nophpinfo='1';
    -$force_install_lockinstall='444';
    diff --git a/build/doxygen/doxygen_footer.html b/build/doxygen/doxygen_footer.html
    index a6d5bdfb293..8ffdc5341fe 100644
    --- a/build/doxygen/doxygen_footer.html
    +++ b/build/doxygen/doxygen_footer.html
    @@ -3,42 +3,27 @@ File added into doxygen generated documentation
     -->
     
     
    -<!-- Google analytics -->
    -<script>
    -  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    -  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    -  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    -  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
    -
    -  ga('create', 'UA-9049390-16', 'auto');
    -  ga('send', 'pageview');
    -
    -</script>
    -<!-- End google analytics -->
    -
     
     <hr class="footer" />
    -<address class="footer"><small>Generated on $datetime
    -for <a href="https://www.dolibarr.org">$projectname</a> by Doxygen $doxygenversion </small></address>
    +<address class="footer"><small>Generated on $datetime for <a href="https://www.dolibarr.org">$projectname</a> by Doxygen $doxygenversion </small></address>
     
     
    -<!--  Google AdSense -->
    -<div class="center">
    -<script type="text/javascript"><!--
    -google_ad_client = "pub-1071905880519467";
    -/* PUBBANDEAUDOLIBARR */
    -google_ad_slot = "1421205532";
    -google_ad_width = 468;
    -google_ad_height = 60;
    -//-->
    -</script>
    -<script type="text/javascript" src="https://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
    -</div>
    -<!-- End google adsense -->
     <br>
     
     </div>
     
    +
    +<!-- Global site tag (gtag.js) - Google Analytics -->
    +<script async src="https://www.googletagmanager.com/gtag/js?id=UA-9049390-16"></script>
    +<script>
    +  window.dataLayer = window.dataLayer || [];
    +  function gtag(){dataLayer.push(arguments);}
    +  gtag('js', new Date());
    +
    +  gtag('config', 'UA-9049390-16');
    +</script>
    +
    +
     <!-- Twitter ad collector -->
     <script src="//platform.twitter.com/oct.js" type="text/javascript"></script>
     <script type="text/javascript">twttr.conversion.trackPid('ntm4n', { tw_sale_amount: 0, tw_order_quantity: 0 });</script>
    diff --git a/build/exe/doliwamp/Languages/MyEnglish.isl b/build/exe/doliwamp/Languages/MyEnglish.isl
    index 11d2e4456bd..b7c5ecb6230 100644
    --- a/build/exe/doliwamp/Languages/MyEnglish.isl
    +++ b/build/exe/doliwamp/Languages/MyEnglish.isl
    @@ -13,8 +13,8 @@ AssocingFileExtension=Associating %1 with the %2 file extension...
     
     YouWillInstallDoliWamp=You will install or upgrade DoliWamp (Apache+Mysql+PHP+Dolibarr) on your computer.
     ThisAssistantInstallOrUpgrade=This assistant installs or upgrades Dolibarr ERP-CRM and all required third party softwares (Apache, Mysql and PHP) optimized for a Dolibarr usage.
    -IfYouHaveTechnicalKnowledge=If you have technical knowledge and plan to share your Apache, Mysql and PHP with other projects than Dolibarr, you should not use this assistant and make a manual installation of Dolibarr on your existing Apache, Mysql and PHP installation.
    -ButIfYouLook=But if you look for an automatic setup, you''re on the good way...
    +IfYouHaveTechnicalKnowledge=If you are looking for a hosted version in the Cloud, you should look at https://saas.dolibarr.org. If you have technical knowledge and want to manage your Apache, Mysql and PHP yourself, you should not use this assistant and make a manual installation of Dolibarr on your existing Apache, Mysql and PHP installation.
    +ButIfYouLook=But if you look for an automatic setup on your local computer, you''re on the good way...
     DoYouWantToStart=Do you want to start installation/upgrade process ?
     
     TechnicalParameters=Technical parameters
    diff --git a/build/exe/doliwamp/Languages/MyFrench.isl b/build/exe/doliwamp/Languages/MyFrench.isl
    index 1daf4425e68..8c7cff0bb42 100644
    --- a/build/exe/doliwamp/Languages/MyFrench.isl
    +++ b/build/exe/doliwamp/Languages/MyFrench.isl
    @@ -13,8 +13,8 @@ AssocingFileExtension=Associe %1 avec l'extension de fichier %2...
     
     YouWillInstallDoliWamp=Vous allez installer ou mettre  jour DoliWamp (Apache+Mysql+PHP+Dolibarr) sur votre ordinateur.
     ThisAssistantInstallOrUpgrade=Cet assistant installe ou met  jour Dolibarr ERP-CRM et tous ses composants prrequis (Apache, Mysql et PHP) optimiss pour une utilisation de Dolibarr.
    -IfYouHaveTechnicalKnowledge=Si vous avez des comptences techniques et envisagez de partager votre Apache, Mysql et PHP avec d'autres applications que Dolibarr, vous ne devriez pas utiliser cet assistant mais faire plutt une installation manuelle de Dolibarr sur un socle Apache, Mysql et PHP existant.
    -ButIfYouLook=Mais si vous recherchez une installation cl en main automatise, vous tes sur la bonne voie...
    +IfYouHaveTechnicalKnowledge=Si vous cherchez un hbergement dans le Cloud, aller voir sur https://saas.dolibarr.org. Si vous avez des comptences techniques et voulez grer vous mme Apache, Mysql et PHP, vous ne devriez pas utiliser cet assistant mais faire plutt une installation manuelle de Dolibarr sur votre socle Apache, Mysql et PHP existant.
    +ButIfYouLook=Mais si vous recherchez une installation automatise locale sur votre ordinateur, cl en main, vous tes sur la bonne voie...
     DoYouWantToStart=Voulez-vous dmarrer le processus d'installation/mise  jour ?
     
     TechnicalParameters=Paramtres techniques
    diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss
    index 2d4668b447c..cc6a39a62a4 100644
    --- a/build/exe/doliwamp/doliwamp.iss
    +++ b/build/exe/doliwamp/doliwamp.iss
    @@ -32,7 +32,7 @@ AppPublisherURL=https://www.nltechno.com
     AppSupportURL=https://www.dolibarr.org
     AppUpdatesURL=https://www.dolibarr.org
     AppComments=DoliWamp includes Dolibarr, Apache, PHP and Mysql softwares.
    -AppCopyright=Copyright (C) 2008-2017 Laurent Destailleur (NLTechno), Fabian Rodriguez (Le Goût du Libre)
    +AppCopyright=Copyright (C) 2008-2018 Laurent Destailleur (NLTechno), Fabian Rodriguez (Le Goût du Libre)
     DefaultDirName=c:\dolibarr
     DefaultGroupName=Dolibarr
     ;LicenseFile=COPYING
    diff --git a/build/flatpack/org.flatpak.Dolibarr.json b/build/flatpack/org.flatpak.Dolibarr.json
    new file mode 100644
    index 00000000000..9e2135cf0a3
    --- /dev/null
    +++ b/build/flatpack/org.flatpak.Dolibarr.json
    @@ -0,0 +1 @@
    +Help wanted...
    \ No newline at end of file
    diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php
    index 0764d64b491..ec9ded557ff 100755
    --- a/build/generate_filelist_xml.php
    +++ b/build/generate_filelist_xml.php
    @@ -34,8 +34,8 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
         exit;
     }
     
    -require_once($path."../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    +require_once $path."../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
     
     
     /*
    diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl
    index 1ab3269d0de..01e282aa492 100755
    --- a/build/makepack-dolibarr.pl
    +++ b/build/makepack-dolibarr.pl
    @@ -22,7 +22,7 @@ $PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr";
     $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files";
     
     
    -#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","APS","EXEDOLIWAMP","SNAPSHOT");   # Possible packages
    +#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT");   # Possible packages
     @LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT");   # Possible packages
     %REQUIREMENTPUBLISH=(
     "SF"=>"git ssh rsync",
    @@ -37,7 +37,7 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpd
     "RPM_MANDRIVA"=>"rpmbuild",
     "RPM_OPENSUSE"=>"rpmbuild",
     "DEB"=>"dpkg",
    -"APS"=>"zip",
    +"FLATPACK"=>"flatpack",
     "EXEDOLIWAMP"=>"ISCC.exe",
     "SNAPSHOT"=>"tar"
     );
    @@ -142,7 +142,6 @@ $FILENAMETGZ         = "$PROJECT-$MAJOR.$MINOR.$BUILD";
     $FILENAMEZIP         = "$PROJECT-$MAJOR.$MINOR.$BUILD";
     $FILENAMEXZ          = "$PROJECT-$MAJOR.$MINOR.$BUILD";
     $FILENAMEDEB         = "see later";
    -$FILENAMEAPS         = "$PROJECT-$MAJOR.$MINOR.$BUILD.app";
     $FILENAMEEXEDOLIWAMP = "DoliWamp-$MAJOR.$MINOR.$BUILD";
     # For RPM
     $ARCH='noarch';
    @@ -692,7 +691,7 @@ if ($nboftargetok) {
     			print "Go to directory $BUILDROOT\n";
     			$olddir=getcwd();
     			chdir("$BUILDROOT");
    -			$cmd= "xz -9 -r $BUILDROOT/$FILENAMEAPS.xz \*";
    +			$cmd= "xz -9 -r $BUILDROOT/$FILENAMEXZ.xz \*";
     			print $cmd."\n";
     			$ret= `$cmd`;
     			chdir("$olddir");
    @@ -1033,92 +1032,6 @@ if ($nboftargetok) {
     			next;
     		}
     		
    -		if ($target eq 'APS') 
    -		{
    -			$NEWDESTI=$DESTI;
    -			if ($NEWDESTI =~ /stable/)
    -			{
    -				mkdir($DESTI.'/package_aps');
    -				if (-d $DESTI.'/package_aps') { $NEWDESTI=$DESTI.'/package_aps'; }
    -			} 
    -			
    -			$newbuild = $BUILD;
    -			$newbuild =~ s/(dev|alpha)/0/gi;                # dev
    -			$newbuild =~ s/beta/1/gi;                       # beta
    -			$newbuild =~ s/rc./2/gi;                        # rc
    -			if ($newbuild !~ /-/) { $newbuild.='-3'; }      # finale
    -			# now newbuild is 0-0 or 0-3 for example
    -			$REL1 = $newbuild; $REL1 =~ s/-.*$//gi;
    -			if ($RPMSUBVERSION eq 'auto') { $RPMSUBVERSION = $newbuild; $RPMSUBVERSION =~ s/^.*-//gi; }
    -			print "Version is $MAJOR.$MINOR.$REL1-$RPMSUBVERSION\n";
    -			
    -			print "Remove target $FILENAMEAPS.zip...\n";
    -			unlink "$NEWDESTI/$FILENAMEAPS.zip";
    -
    -			#rmdir "$BUILDROOT/$PROJECT.tmp";
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp`;
    -			print "Create directory $BUILDROOT/$PROJECT.tmp\n";
    -			$ret=`mkdir -p "$BUILDROOT/$PROJECT.tmp"`;
    -			print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$PROJECT.tmp\n";
    -			$cmd="cp -pr \"$BUILDROOT/$PROJECT\" \"$BUILDROOT/$PROJECT.tmp\"";
    -			$ret=`$cmd`;
    -
    -			print "Remove other files\n";
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/deb`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/dmg`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/doap`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/exe`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/live`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/patch`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/rpm`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/zip`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/perl`;
    -
    -            $APSVERSION="1.2";
    -            print "Create APS files $BUILDROOT/$PROJECT.tmp/$PROJECT/APP-META.xml\n";
    -            open (SPECFROM,"<$BUILDROOT/$PROJECT/build/aps/APP-META-$APSVERSION.xml") || die "Error";
    -            open (SPECTO,">$BUILDROOT/$PROJECT.tmp/$PROJECT/APP-META.xml") || die "Error";
    -            while (<SPECFROM>) {
    -                $newbuild = $BUILD;
    -                $newbuild =~ s/(dev|alpha)/0/gi;                # dev
    -                $newbuild =~ s/beta/1/gi;                       # beta
    -                $newbuild =~ s/rc./2/gi;                        # rc
    -                if ($newbuild !~ /-/) { $newbuild.='-3'; }      # finale
    -                # now newbuild is 0-0 or 0-3 for example
    -                $_ =~ s/__VERSION__/$MAJOR.$MINOR.$REL1/;
    -                $_ =~ s/__RELEASE__/$RPMSUBVERSION/;
    -                print SPECTO $_;
    -            }
    -            close SPECFROM;
    -            close SPECTO;
    -            print "Version set to $MAJOR.$MINOR.$newbuild\n";
    -            $cmd="cp -pr \"$BUILDROOT/$PROJECT/build/aps/configure.php\" \"$BUILDROOT/$PROJECT.tmp/$PROJECT/scripts/configure.php\"";
    -            $ret=`$cmd`;
    -            $cmd="cp -pr \"$BUILDROOT/$PROJECT/doc/images\" \"$BUILDROOT/$PROJECT.tmp/$PROJECT/images\"";
    -            $ret=`$cmd`;
    - 
    -            print "Remove other files\n";
    -            $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/dev`;
    -            $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/doc`;
    -            
    -            print "Build APP-LIST.xml files\n";
    -            
    -            print "Compress $BUILDROOT/$PROJECT.tmp/$PROJECT into $FILENAMEAPS.zip...\n";
    - 
    -            print "Go to directory $BUILDROOT/$PROJECT.tmp\/$PROJECT\n";
    -            $olddir=getcwd();
    -            chdir("$BUILDROOT\/$PROJECT.tmp\/$PROJECT");
    -            $cmd= "zip -9 -r $BUILDROOT/$FILENAMEAPS.zip \*";
    -            print $cmd."\n";
    -            $ret= `$cmd`;
    -            chdir("$olddir");
    -                        
    -    		# Move to final dir
    -            print "Move $BUILDROOT/$FILENAMEAPS.zip to $NEWDESTI/$FILENAMEAPS.zip\n";
    -            $ret=`mv "$BUILDROOT/$FILENAMEAPS.zip" "$NEWDESTI/$FILENAMEAPS.zip"`;
    -            next;
    -    	}
    -
     		if ($target eq 'EXEDOLIWAMP')
     		{
     			$NEWDESTI=$DESTI;
    diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec
    index d5a9189229e..b6d526bf8e1 100755
    --- a/build/rpm/dolibarr_fedora.spec
    +++ b/build/rpm/dolibarr_fedora.spec
    @@ -177,9 +177,11 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    +%_datadir/dolibarr/htdocs/emailcollector
     %_datadir/dolibarr/htdocs/expedition
     %_datadir/dolibarr/htdocs/expensereport
     %_datadir/dolibarr/htdocs/exports
    @@ -212,6 +214,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec
    index 673d5919d1a..32c6e50018e 100755
    --- a/build/rpm/dolibarr_generic.spec
    +++ b/build/rpm/dolibarr_generic.spec
    @@ -54,7 +54,7 @@ BuildRequires: desktop-file-utils
     Group: Applications/Productivity
     Requires: apache-base, apache-mod_php, php-cgi, php-cli, php-bz2, php-gd, php-ldap, php-imap, php-mysqli, php-openssl, fonts-ttf-dejavu 
     Requires: mysql, mysql-client 
    -%else
    +%else%_datadir/dolibarr/htdocs/datapolicy
     %if 0%{?suse_version}
     # Voir http://en.opensuse.org/openSUSE:Packaging_Conventions_RPM_Macros
     Group: Productivity/Office/Management
    @@ -124,7 +124,7 @@ cui hai bisogno ed essere facile da usare.
     
     %if 0%{?sles_version}
     %{__rm} -rf $RPM_BUILD_ROOT
    -%{__mkdir} $RPM_BUILD_ROOT
    +%{__mkdir} $RPM_BUILD_ROOT%_datadir/dolibarr/htdocs/datapolicy
     %{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}
     %{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}
     %else
    @@ -257,9 +257,11 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    +%_datadir/dolibarr/htdocs/emailcollector
     %_datadir/dolibarr/htdocs/expedition
     %_datadir/dolibarr/htdocs/expensereport
     %_datadir/dolibarr/htdocs/exports
    @@ -292,6 +294,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec
    index e3d2a849db2..dbb8e0d1310 100755
    --- a/build/rpm/dolibarr_mandriva.spec
    +++ b/build/rpm/dolibarr_mandriva.spec
    @@ -174,9 +174,11 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    +%_datadir/dolibarr/htdocs/emailcollector
     %_datadir/dolibarr/htdocs/expedition
     %_datadir/dolibarr/htdocs/expensereport
     %_datadir/dolibarr/htdocs/exports
    @@ -209,6 +211,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec
    index 5a64bec2e78..aa810a737b9 100755
    --- a/build/rpm/dolibarr_opensuse.spec
    +++ b/build/rpm/dolibarr_opensuse.spec
    @@ -185,9 +185,11 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    +%_datadir/dolibarr/htdocs/emailcollector
     %_datadir/dolibarr/htdocs/expedition
     %_datadir/dolibarr/htdocs/expensereport
     %_datadir/dolibarr/htdocs/exports
    @@ -220,6 +222,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt
    index cdbc2e2bb40..37aef014e63 100644
    --- a/dev/dolibarr_changes.txt
    +++ b/dev/dolibarr_changes.txt
    @@ -1,5 +1,5 @@
     
    -This file describe changes made on external library after beeing included
    +This file describes changes made on external libraries after being included
     in Dolibarr root.
     
     
    @@ -48,6 +48,23 @@ into
     	// initialize subsetchars
     	$subsetchars = array_fill(0, 256, true);
     
    +* Replace the continue into switch with a break:
    +
    +case 're': {
    +	// justify block
    +	if (!TCPDF_STATIC::empty_string($this->lispacer)) {
    +		$this->lispacer = '';
    +		continue;
    +	}
    +
    +into 
    +case 're': {
    +	// justify block
    +	if (!TCPDF_STATIC::empty_string($this->lispacer)) {
    +		$this->lispacer = '';
    +		break;
    +	}
    +
     * Optionnaly, removed all fonts except 
         dejavusans* (used by greek, arab, persan, romanian, turkish), 
         freemono* (russian), 
    @@ -61,17 +78,24 @@ In htdocs/includes/tcpdf/tcpdf.php
     +       protected $default_monospaced_font = 'freemono';
     
     
    +		
     
     TCPDI:
     ------
     Add fpdf_tpl.php 1.2
     Add tcpdi.php
    +
     Add tcpdi_parser.php and replace:
     require_once(dirname(__FILE__).'/include/tcpdf_filters.php');
     with:
     require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php');
     
     
    +* Fix by replacing
    +	} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1] >= 2))) {
    +with
    +	} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) {
    +
     
     
     JSGANTT:
    diff --git a/dev/examples/code/create_invoice.php b/dev/examples/code/create_invoice.php
    index bd82d38d306..e519c62a436 100755
    --- a/dev/examples/code/create_invoice.php
    +++ b/dev/examples/code/create_invoice.php
    @@ -40,7 +40,7 @@ $error=0;
     
     // -------------------- START OF YOUR CODE HERE --------------------
     // Include Dolibarr environment
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     // After this $db, $mysoc, $langs and $conf->entity are defined. Opened handler to database will be closed at end of file.
     
     //$langs->setDefaultLang('en_US'); 	// To change default language of $langs
    @@ -58,7 +58,7 @@ print "***** ".$script_file." (".$version.") *****\n";
     // Start of transaction
     $db->begin();
     
    -require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    +require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
     
     // Create invoice object
     $obj = new Facture($db);
    diff --git a/dev/examples/code/create_order.php b/dev/examples/code/create_order.php
    index 4575e9e28f3..95b047705fa 100755
    --- a/dev/examples/code/create_order.php
    +++ b/dev/examples/code/create_order.php
    @@ -40,7 +40,7 @@ $error=0;
     
     // -------------------- START OF YOUR CODE HERE --------------------
     // Include Dolibarr environment
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     // After this $db, $mysoc, $langs and $conf->entity are defined. Opened handler to database will be closed at end of file.
     
     //$langs->setDefaultLang('en_US'); 	// To change default language of $langs
    @@ -59,7 +59,7 @@ print "***** ".$script_file." (".$version.") *****\n";
     // Start of transaction
     $db->begin();
     
    -require_once(DOL_DOCUMENT_ROOT."/commande/class/commande.class.php");
    +require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php";
     
     // Create order object
     $com = new Commande($db);
    diff --git a/dev/examples/code/create_product.php b/dev/examples/code/create_product.php
    index 61598ff59d9..8cbc07a1b63 100755
    --- a/dev/examples/code/create_product.php
    +++ b/dev/examples/code/create_product.php
    @@ -40,7 +40,7 @@ $error=0;
     
     // -------------------- START OF YOUR CODE HERE --------------------
     // Include Dolibarr environment
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     // After this $db, $mysoc, $langs and $conf->entity are defined. Opened handler to database will be closed at end of file.
     
     //$langs->setDefaultLang('en_US'); 	// To change default language of $langs
    @@ -59,7 +59,7 @@ print "***** ".$script_file." (".$version.") *****\n";
     // Start of transaction
     $db->begin();
     
    -require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    +require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
     
     // Create instance of object
     $myproduct=new Product($db);
    diff --git a/dev/examples/code/create_user.php b/dev/examples/code/create_user.php
    index 20173eb914a..f8e0ba23011 100755
    --- a/dev/examples/code/create_user.php
    +++ b/dev/examples/code/create_user.php
    @@ -40,7 +40,7 @@ $error=0;
     
     // -------------------- START OF YOUR CODE HERE --------------------
     // Include Dolibarr environment
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     // After this $db, $mysoc, $langs and $conf->entity are defined. Opened handler to database will be closed at end of file.
     
     //$langs->setDefaultLang('en_US'); 	// To change default language of $langs
    @@ -58,7 +58,7 @@ print "***** ".$script_file." (".$version.") *****\n";
     // Start of transaction
     $db->begin();
     
    -require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php");
    +require_once DOL_DOCUMENT_ROOT."/user/class/user.class.php";
     
     // Create user object
     $obj = new User($db);
    diff --git a/dev/examples/code/get_contracts.php b/dev/examples/code/get_contracts.php
    index fbe512300e8..daff0e43e6f 100755
    --- a/dev/examples/code/get_contracts.php
    +++ b/dev/examples/code/get_contracts.php
    @@ -40,7 +40,7 @@ $error=0;
     
     // -------------------- START OF YOUR CODE HERE --------------------
     // Include Dolibarr environment
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     // After this $db, $mysoc, $langs and $conf->entity are defined. Opened handler to database will be closed at end of file.
     
     //$langs->setDefaultLang('en_US'); 	// To change default language of $langs
    @@ -65,7 +65,7 @@ print 'Argument id_thirdparty='.$argv[1]."\n";
     // Start of transaction
     $db->begin();
     
    -require_once(DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php");
    +require_once DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php";
     
     // Create contract object
     $obj = new Contrat($db);
    diff --git a/dev/examples/mail/dolibarr_mail_simpleHTML.txt b/dev/examples/mail/dolibarr_mail_simpleHTML.txt
    index 5c552221ca6..391800f5095 100644
    --- a/dev/examples/mail/dolibarr_mail_simpleHTML.txt
    +++ b/dev/examples/mail/dolibarr_mail_simpleHTML.txt
    @@ -4,4 +4,4 @@ X-Mailer: Dolibarr version 2.7.0-beta (using php mail)
     MIME-Version: 1.0
     Content-Type: text/html; charset=UTF-8
     Content-Transfer-Encoding: 8bit
    -<html><head><title></title></head><body>Test&eacute;<br />fdsfsdf<br />fsdf<strong>sfd</strong>s<br />fssdfsd<br /></body></html>
    +<html><head><title></title></head><body>Test&eacute;<br>fdsfsdf<br>fsdf<strong>sfd</strong>s<br>fssdfsd<br></body></html>
    diff --git a/dev/initdata/generate-invoice.php b/dev/initdata/generate-invoice.php
    index e313aa44d1f..280518bd4e3 100755
    --- a/dev/initdata/generate-invoice.php
    +++ b/dev/initdata/generate-invoice.php
    @@ -32,9 +32,9 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     //$path=preg_replace('/generate-produit.php/i','',$_SERVER["PHP_SELF"]);
    -require (__DIR__. '/../../htdocs/master.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    +require __DIR__. '/../../htdocs/master.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
    +require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
     
     
     /*
    @@ -185,7 +185,4 @@ while ($i < GEN_NUMBER_FACTURE && $result >= 0)
     	{
     		dol_print_error($db,$object->error);
     	}
    -
     }
    -
    -
    diff --git a/dev/initdata/generate-order.php b/dev/initdata/generate-order.php
    index c73b15b620d..5e53fa752a2 100755
    --- a/dev/initdata/generate-order.php
    +++ b/dev/initdata/generate-order.php
    @@ -33,14 +33,14 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     //$path=preg_replace('/generate-commande.php/i','',$_SERVER["PHP_SELF"]);
    -require (__DIR__. '/../../htdocs/master.inc.php');
    +require __DIR__. '/../../htdocs/master.inc.php';
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     include_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
     include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
    -require_once(DOL_DOCUMENT_ROOT."/commande/class/commande.class.php");
    +require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php";
     
     
     /*
    diff --git a/dev/initdata/generate-product.php b/dev/initdata/generate-product.php
    index 3ae44b00b3a..393d5c5ce3d 100755
    --- a/dev/initdata/generate-product.php
    +++ b/dev/initdata/generate-product.php
    @@ -33,7 +33,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     //$path=preg_replace('/generate-produit.php/i','',$_SERVER["PHP_SELF"]);
    -require (__DIR__. '/../../htdocs/master.inc.php');
    +require __DIR__. '/../../htdocs/master.inc.php';
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    diff --git a/dev/initdata/generate-proposal.php b/dev/initdata/generate-proposal.php
    index 6f1dc293a68..eb2bfe15a00 100755
    --- a/dev/initdata/generate-proposal.php
    +++ b/dev/initdata/generate-proposal.php
    @@ -33,11 +33,11 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     //$path=preg_replace('/generate-propale.php/i','',$_SERVER["PHP_SELF"]);
    -require (__DIR__. '/../../htdocs/master.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/commande/class/commande.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    +require __DIR__. '/../../htdocs/master.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
    +require_once DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php";
    +require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php";
    +require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
     
     /*
      * Parameters
    @@ -157,7 +157,7 @@ $user->rights->propal->propal_advance->validate=1;
     
     if (! empty($conf->global->PROPALE_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php"))
     {
    -	require_once(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php");
    +	require_once DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php";
     }
     
     $i=0;
    @@ -218,6 +218,4 @@ while ($i < GEN_NUMBER_PROPAL && $result >= 0)
     	{
     		dol_print_error($db,$object->error);
     	}
    -
     }
    -
    diff --git a/dev/initdata/generate-thirdparty.php b/dev/initdata/generate-thirdparty.php
    index 992ab61f4ef..7f2c3e2055d 100755
    --- a/dev/initdata/generate-thirdparty.php
    +++ b/dev/initdata/generate-thirdparty.php
    @@ -33,7 +33,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     //$path=preg_replace('/generate-societe.php/i','',$_SERVER["PHP_SELF"]);
    -require (__DIR__. '/../../htdocs/master.inc.php');
    +require __DIR__. '/../../htdocs/master.inc.php';
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    diff --git a/dev/initdata/import-products.php b/dev/initdata/import-products.php
    index a08e3b6066e..0f4856aefb2 100755
    --- a/dev/initdata/import-products.php
    +++ b/dev/initdata/import-products.php
    @@ -21,7 +21,7 @@
     
     /**
      *      \file       dev/initdata/import-product.php
    - *		\brief      Script example to insert products from a csv file. 
    + *		\brief      Script example to insert products from a csv file.
      *                  To purge data, you can have a look at purge-data.php
      */
     
    @@ -36,7 +36,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     $path=preg_replace('/import-products.php/i','',$_SERVER["PHP_SELF"]);
    -require ($path."../../htdocs/master.inc.php");
    +require $path."../../htdocs/master.inc.php";
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
    @@ -118,22 +118,22 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
     {
         $i++;
         $errorrecord=0;
    -    
    +
         if ($startlinenb && $i < $startlinenb) continue;
         if ($endlinenb && $i > $endlinenb) continue;
    -    
    +
         $nboflines++;
    -    
    +
         $produit = new Product($db);
         $produit->type = 0;
         $produit->status = 1;
         $produit->ref = trim($fields[0]);
    -    
    +
         print "Process line nb ".$i.", ref ".$produit->ref;
         $produit->label = trim($fields[2]);
         $produit->description = trim($fields[4]."\n".($fields[5] ? $fields[5].' x '.$fields[6].' x '.$fields[7] : ''));
         $produit->volume = price2num($fields[8]);
    -    $produit->volume_unit = 0;     
    +    $produit->volume_unit = 0;
         $produit->weight = price2num($fields[9]);
         $produit->weight_units = 0;          // -3 = g
     
    @@ -142,9 +142,9 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
     
         $produit->status = 1;
         $produit->status_buy = 1;
    -    
    +
         $produit->finished = 1;
    -    
    +
         $produit->price_min = null;
         $produit->price_min_ttc = null;
         $produit->price = price2num($fields[11]);
    @@ -152,25 +152,25 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
         $produit->price_base_type = 'TTC';
         $produit->tva_tx = price2num($fields[13]);
         $produit->tva_npr = 0;
    -    
    +
         $produit->cost_price = price2num($fields[16]);
    -    
    +
         // Extrafields
         $produit->array_options['options_ecotaxdeee']=price2num($fields[17]);
    -    
    +
         $ret=$produit->create($user);
         if ($ret < 0)
         {
             print " - Error in create result code = ".$ret." - ".$produit->errorsToString();
             $errorrecord++;
         }
    -	else 
    +	else
     	{
     	    print " - Creation OK with ref ".$produit->ref." - id = ".$ret;
     	}
     
     	dol_syslog("Add prices");
    -	
    +
         // If we use price level, insert price for each level
     	if (! $errorrecord && 1)
     	{
    @@ -181,14 +181,14 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
                 print " - Error in updatePrice result code = ".$ret1." ".$ret2." - ".$produit->errorsToString();
                 $errorrecord++;
             }
    -    	else 
    +    	else
         	{
         	    print " - updatePrice OK";
         	}
     	}
    -	
    +
     	dol_syslog("Add multilangs");
    -	
    +
     	// Add alternative languages
     	if (! $errorrecord && 1)
     	{
    @@ -201,15 +201,15 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
                 print " - Error in setMultiLangs result code = ".$ret." - ".$produit->errorsToString();
                 $errorrecord++;
             }
    -    	else 
    +    	else
         	{
         	    print " - setMultiLangs OK";
         	}
     	}
    -	
    +
     	print "\n";
    -	
    -	if ($errorrecord) 
    +
    +	if ($errorrecord)
     	{
     	    fwrite($fhandleerr, 'Error on record nb '.$i." - ".$produit->errorsToString()."\n");
     	    $error++;    // $errorrecord will be reset
    diff --git a/dev/initdata/import-thirdparties.php b/dev/initdata/import-thirdparties.php
    index 0c32c7ea6a3..63c6856e5ec 100755
    --- a/dev/initdata/import-thirdparties.php
    +++ b/dev/initdata/import-thirdparties.php
    @@ -36,7 +36,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     $path=preg_replace('/import-thirdparties.php/i','',$_SERVER["PHP_SELF"]);
    -require ($path."../../htdocs/master.inc.php");
    +require $path."../../htdocs/master.inc.php";
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
    diff --git a/dev/initdata/import-users.php b/dev/initdata/import-users.php
    index 3aaa9c11a4a..c94f74341f6 100755
    --- a/dev/initdata/import-users.php
    +++ b/dev/initdata/import-users.php
    @@ -21,7 +21,7 @@
     
     /**
      *      \file       dev/initdata/import-thirdparties.php
    - *		\brief      Script example to insert thirdparties from a csv file. 
    + *		\brief      Script example to insert thirdparties from a csv file.
      *                  To purge data, you can have a look at purge-data.php
      */
     
    @@ -36,7 +36,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     $path=preg_replace('/import-users.php/i','',$_SERVER["PHP_SELF"]);
    -require ($path."../../htdocs/master.inc.php");
    +require $path."../../htdocs/master.inc.php";
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
    @@ -118,15 +118,15 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
     {
         $i++;
         $errorrecord=0;
    -    
    +
         if ($startlinenb && $i < $startlinenb) continue;
         if ($endlinenb && $i > $endlinenb) continue;
    -    
    +
         $nboflines++;
    -    
    +
         $object = new User($db);
         $object->statut = 1;
    -    
    +
         $tmp=explode(' ',$fields[3],2);
         $object->firstname = trim($tmp[0]);
         $object->lastname = trim($tmp[1]);
    @@ -134,23 +134,23 @@ while ($fields=fgetcsv($fhandle, $linelength, $delimiter, $enclosure, $escape))
         else $object->login=strtolower($object->firstname);
         $object->login=preg_replace('/ /','',$object->login);
         $object->password = 'init';
    -    
    +
         print "Process line nb ".$i.", login ".$object->login;
    -    
    +
         $ret=$object->create($user);
         if ($ret < 0)
         {
             print " - Error in create result code = ".$ret." - ".$object->errorsToString();
             $errorrecord++;
         }
    -	else 
    +	else
     	{
     	    print " - Creation OK with login ".$object->login." - id = ".$ret;
     	}
     
     	print "\n";
    -	
    -	if ($errorrecord) 
    +
    +	if ($errorrecord)
     	{
     	    fwrite($fhandleerr, 'Error on record nb '.$i." - ".$object->errorsToString()."\n");
     	    $error++;    // $errorrecord will be reset
    diff --git a/dev/initdata/purge-data.php b/dev/initdata/purge-data.php
    index f992dcb2dc6..2bdf200225b 100755
    --- a/dev/initdata/purge-data.php
    +++ b/dev/initdata/purge-data.php
    @@ -36,7 +36,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     
     // Recupere root dolibarr
     $path=preg_replace('/purge-data.php/i','',$_SERVER["PHP_SELF"]);
    -require ($path."../../htdocs/master.inc.php");
    +require $path."../../htdocs/master.inc.php";
     include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    @@ -44,8 +44,7 @@ include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     include_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
     include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
     
    -$langs->load("main");
    -$langs->load("errors");
    +$langs->loadLangs(array("main", "errors"));
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/dev/initdemo/sftpget_and_loaddump.php b/dev/initdemo/sftpget_and_loaddump.php
    index 981ff964b8e..98cb6189935 100755
    --- a/dev/initdemo/sftpget_and_loaddump.php
    +++ b/dev/initdemo/sftpget_and_loaddump.php
    @@ -41,15 +41,15 @@ $passwordbase=isset($argv[6])?$argv[6]:'';
     
     // Include Dolibarr environment
     $res=0;
    -if (! $res && file_exists($path."../../master.inc.php")) $res=@include($path."../../master.inc.php");
    -if (! $res && file_exists($path."../../htdocs/master.inc.php")) $res=@include($path."../../htdocs/master.inc.php");
    -if (! $res && file_exists("../master.inc.php")) $res=@include("../master.inc.php");
    -if (! $res && file_exists("../../master.inc.php")) $res=@include("../../master.inc.php");
    -if (! $res && file_exists("../../../master.inc.php")) $res=@include("../../../master.inc.php");
    -if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include($path."../../../dolibarr".$reg[1]."/htdocs/master.inc.php"); // Used on dev env only
    -if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include("../../../dolibarr".$reg[1]."/htdocs/master.inc.php"); // Used on dev env only
    +if (! $res && file_exists($path."../../master.inc.php")) $res=@include $path."../../master.inc.php";
    +if (! $res && file_exists($path."../../htdocs/master.inc.php")) $res=@include $path."../../htdocs/master.inc.php";
    +if (! $res && file_exists("../master.inc.php")) $res=@include "../master.inc.php";
    +if (! $res && file_exists("../../master.inc.php")) $res=@include "../../master.inc.php";
    +if (! $res && file_exists("../../../master.inc.php")) $res=@include "../../../master.inc.php";
    +if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include $path."../../../dolibarr".$reg[1]."/htdocs/master.inc.php"; // Used on dev env only
    +if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include "../../../dolibarr".$reg[1]."/htdocs/master.inc.php"; // Used on dev env only
     if (! $res) die ("Failed to include master.inc.php file\n");
    -include_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
    +include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
     
     /*
    diff --git a/dev/initdemo/updatedemo.php b/dev/initdemo/updatedemo.php
    index 9c453096904..53717314d5f 100755
    --- a/dev/initdemo/updatedemo.php
    +++ b/dev/initdemo/updatedemo.php
    @@ -15,7 +15,7 @@
      * You should have received a copy of the GNU General Public License
      * along with this program. If not, see <http://www.gnu.org/licenses/>.
      * or see http://www.gnu.org/
    - * 
    + *
      * Get a distant dump file and load it into a mysql database
      */
     
    @@ -36,15 +36,15 @@ $confirm=isset($argv[1])?$argv[1]:'';
     
     // Include Dolibarr environment
     $res=0;
    -if (! $res && file_exists($path."../../master.inc.php")) $res=@include($path."../../master.inc.php");
    -if (! $res && file_exists($path."../../htdocs/master.inc.php")) $res=@include($path."../../htdocs/master.inc.php");
    -if (! $res && file_exists("../master.inc.php")) $res=@include("../master.inc.php");
    -if (! $res && file_exists("../../master.inc.php")) $res=@include("../../master.inc.php");
    -if (! $res && file_exists("../../../master.inc.php")) $res=@include("../../../master.inc.php");
    -if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include($path."../../../dolibarr".$reg[1]."/htdocs/master.inc.php"); // Used on dev env only
    -if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include("../../../dolibarr".$reg[1]."/htdocs/master.inc.php"); // Used on dev env only
    +if (! $res && file_exists($path."../../master.inc.php")) $res=@include $path."../../master.inc.php";
    +if (! $res && file_exists($path."../../htdocs/master.inc.php")) $res=@include $path."../../htdocs/master.inc.php";
    +if (! $res && file_exists("../master.inc.php")) $res=@include "../master.inc.php";
    +if (! $res && file_exists("../../master.inc.php")) $res=@include "../../master.inc.php";
    +if (! $res && file_exists("../../../master.inc.php")) $res=@include "../../../master.inc.php";
    +if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include $path."../../../dolibarr".$reg[1]."/htdocs/master.inc.php"; // Used on dev env only
    +if (! $res && preg_match('/\/nltechno([^\/]*)\//',$_SERVER["PHP_SELF"],$reg)) $res=@include "../../../dolibarr".$reg[1]."/htdocs/master.inc.php"; // Used on dev env only
     if (! $res) die ("Failed to include master.inc.php file\n");
    -include_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
    +include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
     
     /*
    @@ -74,7 +74,7 @@ $tables=array(
     
     $year=2010;
     $currentyear=$tmp['year'];
    -while ($year <= $currentyear) 
    +while ($year <= $currentyear)
     {
         //$year=2021;
         $delta=($currentyear - $year);
    @@ -84,7 +84,7 @@ while ($year <= $currentyear)
         {
             foreach($tables as $tablekey => $tableval)
             {
    -            print "\nCorrect ".$tablekey." for year ".$year." and move them to current year ".$currentyear." "; 
    +            print "\nCorrect ".$tablekey." for year ".$year." and move them to current year ".$currentyear." ";
                 $sql="select rowid from ".MAIN_DB_PREFIX.$tablekey." where ".$tableval[0]." between '".$year."-01-01' and '".$year."-12-31' and ".$tableval[0]." < DATE_ADD(NOW(), INTERVAL -1 YEAR)";
                 //$sql="select rowid from ".MAIN_DB_PREFIX.$tablekey." where ".$tableval[0]." between '".$year."-01-01' and '".$year."-12-31' and ".$tableval[0]." > NOW()";
                 $resql = $db->query($sql);
    @@ -110,14 +110,14 @@ while ($year <= $currentyear)
                             //print $sql2."\n";
                             $resql2 = $db->query($sql2);
                             if (! $resql2) dol_print_error($db);
    -                    }            
    +                    }
                         $i++;
                     }
                 }
                 else dol_print_error($db);
             }
         }
    -    
    +
         $year++;
     }
     
    diff --git a/dev/setup/codesniffer/ruleset.xml b/dev/setup/codesniffer/ruleset.xml
    index a43e4dde82b..67bf58e51ed 100644
    --- a/dev/setup/codesniffer/ruleset.xml
    +++ b/dev/setup/codesniffer/ruleset.xml
    @@ -4,6 +4,7 @@
     	<description>Dolibarr coding standard.</description>
     
     	<exclude-pattern type="relative">build/html</exclude-pattern>
    +	<exclude-pattern type="relative">build/aps</exclude-pattern>
     	<exclude-pattern type="relative">documents</exclude-pattern>
     	<exclude-pattern type="relative">htdocs/custom</exclude-pattern>
     	<exclude-pattern type="relative">htdocs/includes</exclude-pattern>
    @@ -11,43 +12,29 @@
     	<exclude-pattern type="relative">*/nltechno*</exclude-pattern>
     	<exclude-pattern type="relative">*/htdocs/includes</exclude-pattern>
     	<exclude-pattern type="relative">*.min.css</exclude-pattern>
    +	<exclude-pattern type="relative">*.js</exclude-pattern>
     
     		<!-- List of all tests -->
     
    -	
    +
     	<!-- Rules from Internal Standard -->
    -	
    +
     	<rule ref="Internal.NoCodeFound">
     		<severity>0</severity>
     	</rule>
     
    -	
    -	<!-- Rules from Generic Standard -->
    -		
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement" />
     
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedCATCH">
    -		<severity>0</severity>
    -	</rule>
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedFOREACH">
    -		<severity>0</severity>
    -	</rule>
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedIF">
    -		<severity>0</severity>
    -	</rule>
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedELSE">
    -		<severity>0</severity>
    -	</rule>
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedELSEIF">
    -		<severity>0</severity>
    -	</rule>
    -	
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.NotAllowed">
    -		<severity>0</severity>
    -	</rule>
    -	<rule ref="Generic.CodeAnalysis.EmptyStatement.NotAllowedWarning">
    -		<severity>0</severity>
    -	</rule>
    +	<!-- Rules from Generic Standard -->
    +
    +	<rule ref="Generic.CodeAnalysis.EmptyStatement">
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedIf"/>
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedElse"/>
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedElseif"/>
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch"/>
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedForeach"/>
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.NotAllowed"/>
    +        <exclude name="Generic.CodeAnalysis.EmptyStatement.NotAllowedWarning"/>
    +    </rule>
     
         <!-- <rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" /> -->
     
    @@ -147,7 +134,7 @@
         <rule ref="Generic.PHP.DeprecatedFunctions.Deprecated">
             <severity>0</severity>
         </rule>
    -	
    +
     	<rule ref="Generic.PHP.DisallowShortOpenTag" />
     
         <rule ref="Generic.PHP.ForbiddenFunctions" />
    @@ -163,7 +150,7 @@
     	<rule ref="Generic.Strings.UnnecessaryStringConcat.Found">
             <severity>0</severity>
     	</rule>
    -    
    +
     	<!-- Disallow usage of tab -->
     	<!--  <rule ref="Generic.WhiteSpace.DisallowTabIndent" /> -->
     
    @@ -171,7 +158,24 @@
     	<!-- Disabled as this does not support tab -->
     	<!-- <rule ref="Generic.WhiteSpace.ScopeIndent" /> -->
     
    +    <!-- There MUST NOT be trailing whitespace at the end of non-blank lines. -->
    +    <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
    +        <properties>
    +            <property name="ignoreBlankLines" value="true"/>
    +        </properties>
    +    </rule>
    +    <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile">
    +        <severity>0</severity>
    +    </rule>
    +    <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile">
    +        <severity>0</severity>
    +    </rule>
    +    <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines">
    +        <severity>0</severity>
    +    </rule>
    +    <rule ref="Squiz.WhiteSpace.ControlStructureSpacing.SpacingBeforeClose" />
     
    +    <rule ref="Squiz.Functions.MultiLineFunctionDeclaration" />
     
         <!-- Rules from PEAR Standard -->
     
    @@ -186,7 +190,7 @@
         <rule ref="PEAR.Commenting.ClassComment.Missing">
             <severity>0</severity>
         </rule>
    -    
    +
         <rule ref="PEAR.Commenting.ClassComment.MissingTag">
     		<severity>0</severity>
         </rule>
    @@ -206,14 +210,14 @@
         <rule ref="PEAR.Commenting.ClassComment.MissingLinkTag">
             <severity>0</severity>
         </rule>
    -        
    +
         <rule ref="PEAR.Commenting.ClassComment.MissingPackageTag">
             <severity>0</severity>
         </rule>
    -        
     
    -   
    -    <!-- 
    +
    +
    +    <!--
         <rule ref="PEAR.Commenting.FileComment" />
         <rule ref="PEAR.Commenting.FileComment.WrongStyle">
             <severity>0</severity>
    @@ -225,20 +229,20 @@
             <severity>0</severity>
         </rule>
         -->
    -    
    +
         <rule ref="PEAR.Commenting.FunctionComment" />
     
         <rule ref="PEAR.Commenting.FunctionComment.Empty">
             <severity>5</severity>
         </rule>
    -    
    -	<rule ref="PEAR.Commenting.FunctionComment.MissingReturn">
    +
    +	<!--<rule ref="PEAR.Commenting.FunctionComment.MissingReturn">
             <severity>0</severity>
    -    </rule>
    -    <rule ref="PEAR.Commenting.FunctionComment.Missing">
    +    </rule>-->
    +    <!--<rule ref="PEAR.Commenting.FunctionComment.Missing">
             <severity>0</severity>
    -    </rule>
    -    
    +    </rule>-->
    +
         <rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamType" />
     
         <rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamName">
    @@ -254,11 +258,11 @@
         <rule ref="PEAR.Commenting.FunctionComment.ReturnNotRequired">
             <severity>0</severity>
         </rule>
    -    
    +
         <rule ref="PEAR.Commenting.FunctionComment.WrongStyle">
             <severity>0</severity>
         </rule>
    -    
    +
         <rule ref="PEAR.Commenting.FunctionComment.SpacingBeforeParamType">
             <severity>0</severity>
         </rule>
    @@ -285,7 +289,20 @@
     	<!-- <rule ref="PEAR.ControlStructures.MultiLineCondition" /> -->
     
     	<!-- Test if () are removed for includes -->
    -	<!-- <rule ref="PEAR.Files.IncludingFile"/> -->
    +	<rule ref="PEAR.Files.IncludingFile" />
    +    <!-- Disable some error messages that we do not want. -->
    +    <rule ref="PEAR.Files.IncludingFile.UseInclude">
    +        <severity>0</severity>
    +    </rule>
    +    <rule ref="PEAR.Files.IncludingFile.UseIncludeOnce">
    +        <severity>0</severity>
    +    </rule>
    +    <rule ref="PEAR.Files.IncludingFile.UseRequire">
    +        <severity>0</severity>
    +    </rule>
    +    <rule ref="PEAR.Files.IncludingFile.UseRequireOnce">
    +        <severity>0</severity>
    +    </rule>
     
     	<rule ref="PEAR.Formatting.MultiLineAssignment" />
     
    @@ -315,14 +332,14 @@
         <rule ref="PEAR.Functions.FunctionCallSignature.SpaceAfterCloseBracket">
             <severity>0</severity>
         </rule>
    -	
    +
     	<rule ref="PEAR.Functions.ValidDefaultValue" />
     
     	<rule ref="PEAR.NamingConventions.ValidClassName" />
     	<rule ref="PEAR.NamingConventions.ValidClassName.Invalid">
             <severity>0</severity>
     	</rule>
    -	
    +
     	<rule ref="PEAR.NamingConventions.ValidClassName.StartWithCapital">
             <severity>0</severity>
     	</rule>
    @@ -330,7 +347,7 @@
     	<rule ref="PEAR.NamingConventions.ValidClassName.StartWithCaptial">
             <severity>0</severity>
     	</rule>
    -	
    +
     	<rule ref="PEAR.NamingConventions.ValidFunctionName" />
     
     	<rule ref="PEAR.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore">
    @@ -347,31 +364,37 @@
             <severity>0</severity>
     	</rule>
     
    -	<rule ref="PEAR.NamingConventions.ValidFunctionName.NotCamelCaps">
    +    <!--<rule ref="PEAR.NamingConventions.ValidFunctionName.NotCamelCaps">
             <severity>0</severity>
    -	</rule>
    +    </rule>-->
    +	<!--<rule ref="PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps">
    +        <severity>0</severity>
    +	</rule>-->
     	<rule ref="PEAR.NamingConventions.ValidFunctionName.PrivateNoUnderscore">
             <severity>0</severity>
     	</rule>
     	<rule ref="PEAR.NamingConventions.ValidVariableName" />
     
    +    <rule ref="PSR2.Classes.ClassDeclaration" />
    +    <rule ref="PSR2.Methods.FunctionClosingBrace" />
    +
     	<!-- This is not in PSR2 -->
     	<rule ref="PEAR.NamingConventions.ValidVariableName.PrivateNoUnderscore">
             <severity>0</severity>
         </rule>
    -	
    +
     	<rule ref="PEAR.WhiteSpace.ObjectOperatorIndent" />
     
     	<!-- Need to be commented to be disabled
     	<rule ref="PEAR.WhiteSpace.ScopeClosingBrace">
             <severity>0</severity>
         </rule>
    -	
    +
         <rule ref="PEAR.WhiteSpace.ScopeClosingBrace.Line">
             <severity>0</severity>
         </rule>
     	-->
    -    
    +
         <!-- Already found as a Generic rule -->
     	<!-- <rule ref="PEAR.WhiteSpace.ScopeIndent" /> -->
     
    diff --git a/dev/tools/test/testtcpdf.php b/dev/tools/test/testtcpdf.php
    index e14dae9c2a3..ce962dce3d9 100755
    --- a/dev/tools/test/testtcpdf.php
    +++ b/dev/tools/test/testtcpdf.php
    @@ -27,8 +27,8 @@
      * @since 2008-03-04
      */
     
    -require_once('../../htdocs/includes/tecnickcom/tcpdf/config/tcpdf_config.php');
    -require_once('../../htdocs/includes/tecnickcom/tcpdf/tcpdf.php');
    +require_once '../../htdocs/includes/tecnickcom/tcpdf/config/tcpdf_config.php';
    +require_once '../../htdocs/includes/tecnickcom/tcpdf/tcpdf.php';
     
     // create new PDF document
     $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    diff --git a/dev/tools/test/testutf.php b/dev/tools/test/testutf.php
    index c626a92a57d..ffa746bcab5 100644
    --- a/dev/tools/test/testutf.php
    +++ b/dev/tools/test/testutf.php
    @@ -47,8 +47,8 @@ print 'Files has been created. Check its name from your explorer'."\n";
      * @since 2008-09-15
      */
     
    -require_once('../../htdocs/includes/tecnickcom/tcpdf/config/tcpdf_config.php');
    -require_once('../../htdocs/includes/tecnickcom/tcpdf/tcpdf.php');
    +require_once '../../htdocs/includes/tecnickcom/tcpdf/config/tcpdf_config.php';
    +require_once '../../htdocs/includes/tecnickcom/tcpdf/tcpdf.php';
     
     // create new PDF document
     $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    diff --git a/dev/translation/autotranslator.class.php b/dev/translation/autotranslator.class.php
    index 47d6a25ec15..123b7f6157d 100644
    --- a/dev/translation/autotranslator.class.php
    +++ b/dev/translation/autotranslator.class.php
    @@ -64,8 +64,7 @@ class autoTranslator
     		// Translate
     		//ini_set('default_charset','UTF-8');
     		ini_set('default_charset',$this->_outputpagecode);
    -		$this->parse_refLangTranslationFiles();
    -
    +		$this->parseRefLangTranslationFiles();
     	}
     
     	/**
    @@ -73,7 +72,7 @@ class autoTranslator
     	 *
     	 * 	@return	void
     	 */
    -	private function parse_refLangTranslationFiles()
    +	private function parseRefLangTranslationFiles()
     	{
     
     		$files = $this->getTranslationFilesArray($this->_refLang);
    @@ -346,5 +345,4 @@ class autoTranslator
     
     		return $rep;
     	}
    -
     }
    diff --git a/dev/translation/autotranslator.php b/dev/translation/autotranslator.php
    index 58314a23b9e..c7897810a72 100755
    --- a/dev/translation/autotranslator.php
    +++ b/dev/translation/autotranslator.php
    @@ -37,8 +37,8 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     }
     
     // Include Dolibarr environment
    -require_once($path.'../../htdocs/master.inc.php');
    -require_once($path.'../../htdocs/core/lib/files.lib.php');
    +require_once $path.'../../htdocs/master.inc.php';
    +require_once $path.'../../htdocs/core/lib/files.lib.php';
     // After this $db is an opened handler to database. We close it at end of file.
     
     // Load main language strings
    @@ -88,7 +88,7 @@ if ($argv[2] != 'all')
     	}
     }
     
    -require_once(DOL_DOCUMENT_ROOT."/../dev/translation/autotranslator.class.php");
    +require_once DOL_DOCUMENT_ROOT."/../dev/translation/autotranslator.class.php";
     
     $langParser = new autoTranslator($argv[2],$argv[1],$dir,$file,$argv[3]);
     
    diff --git a/dev/translation/sanity_check_en_langfiles.php b/dev/translation/sanity_check_en_langfiles.php
    index 2eedcda8760..0e3b2c7513f 100755
    --- a/dev/translation/sanity_check_en_langfiles.php
    +++ b/dev/translation/sanity_check_en_langfiles.php
    @@ -295,6 +295,7 @@ if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($a
     	    if (preg_match('/^DescADHERENT_/', $value)) $qualifiedforclean=0;
     	    if (preg_match('/^SubmitTranslation/', $value)) $qualifiedforclean=0;
     	    if (preg_match('/^ModuleCompanyCode/', $value)) $qualifiedforclean=0;
    +	    if (preg_match('/InDolibarr$/', $value)) $qualifiedforclean=0;
     	    // admin.lang
     	    if (preg_match('/^DAV_ALLOW_PUBLIC_DIR/i', $value)) $qualifiedforclean=0;
     	    if (preg_match('/^DAV_ALLOW_ECM_DIR/i', $value)) $qualifiedforclean=0;
    diff --git a/doc/images/dolibarr_screenshot5_1920x1080_b.jpg b/doc/images/dolibarr_screenshot5_1920x1080_b.jpg
    index 5f7d8a5b573..0b5c749cb5c 100644
    Binary files a/doc/images/dolibarr_screenshot5_1920x1080_b.jpg and b/doc/images/dolibarr_screenshot5_1920x1080_b.jpg differ
    diff --git a/doc/index.html b/doc/index.html
    index b888b13d9a6..5c655136e3e 100644
    --- a/doc/index.html
    +++ b/doc/index.html
    @@ -11,15 +11,15 @@ informations on Dolibarr.<br>
     But if you are looking for other resources (downloads, documentation, addons, ...), you can find this
     on Internet on web following sites:<br>
     <br>
    -* <a href="http://wiki.dolibarr.org">Dolibarr wiki (documentation)</a><br>
    +* <a href="https://wiki.dolibarr.org">Dolibarr wiki (documentation)</a><br>
     <br>
    -* <a href="http://www.dolibarr.org">Dolibarr portal (official website)</a><br>
    +* <a href="https://www.dolibarr.org">Dolibarr portal (official website)</a><br>
     <br>
    -* <a href="http://demo.dolibarr.org">Dolibarr demo (online)</a><br>
    +* <a href="https://demo.dolibarr.org">Dolibarr demo (online)</a><br>
     <br>
    -* <a href="http://www.nltechno.com/pages/dolibarrwinbin.php">DoliWamp, the Dolibarr for Windows</a><br>
    +* <a href="https://www.nltechno.com/pages/dolibarrwinbin.php">DoliWamp, the Dolibarr for Windows</a><br>
     <br>
    -* <a href="http://www.dolistore.com">DoliStore (official addons/plugins market place)</a><br>
    +* <a href="https://www.dolistore.com">DoliStore (official addons/plugins market place)</a><br>
     
     </body>
     </html>
    \ No newline at end of file
    diff --git a/doc/install/README-FR b/doc/install/README-FR
    index f954601ae0d..2cee29cf2df 100644
    --- a/doc/install/README-FR
    +++ b/doc/install/README-FR
    @@ -9,19 +9,19 @@ Téléchargement
     * Dolibarr ERP/CRM can be downloaded at sourceforge:
     http://sourceforge.net/projects/dolibarr/files
     or from Dolibarr official web site:
    -http://www.dolibarr.org
    +https://www.dolibarr.org
     
     * Most external modules are only available on DoliStore:
    -http://www.dolistore.org
    +https://www.dolistore.org
     
     
     --------------------------------
     Documentation utilisateur
     --------------------------------
     
    -* Pour une prise en main et installation rapide, consulter le fichier
    +* Pour une prise en main et installation rapide, consultez le fichier
     README-FR à la racine.
     
    -* Une documentation utilisateur francophone plus consistente est disponible en
    +* Une documentation utilisateur francophone plus consistante est disponible en
     ligne sur le wiki de Dolibarr à l'adresse:
    -http://wiki.dolibarr.org
    +https://wiki.dolibarr.org
    diff --git a/doc/user/README b/doc/user/README
    index 19507dba0e4..129dff11058 100644
    --- a/doc/user/README
    +++ b/doc/user/README
    @@ -4,4 +4,4 @@ User guide
     --------------------------------
     
     * All Dolibarr guides are available, on line, on the Dolibarr Web site:
    -http://www.dolibarr.org
    +https://www.dolibarr.org
    diff --git a/doc/user/README-FR b/doc/user/README-FR
    index f3a839de008..fbf67fd89bc 100644
    --- a/doc/user/README-FR
    +++ b/doc/user/README-FR
    @@ -3,9 +3,9 @@ README (french)
     Documentation utilisateur
     --------------------------------
     
    -* Pour une prise en main et installation rapide, consulter le fichier
    +* Pour une prise en main et installation rapide, consultez le fichier
     README-FR à la racine.
     
    -* Une documentation utilisateur francophone plus consistente est disponible en
    +* Une documentation utilisateur francophone plus consistante est disponible en
     ligne sur le site Web de Dolibarr à l'adresse:
    -http://www.dolibarr.fr
    +https://www.dolibarr.fr
    diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php
    index da05246b05b..c9b72d9cc4c 100644
    --- a/htdocs/accountancy/admin/account.php
    +++ b/htdocs/accountancy/admin/account.php
    @@ -38,11 +38,11 @@ $id = GETPOST('id', 'int');
     $rowid = GETPOST('rowid', 'int');
     $contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'accountingaccountlist';   // To manage different context of search
     
    -$search_account = GETPOST("search_account");
    -$search_label = GETPOST("search_label");
    -$search_accountparent = GETPOST("search_accountparent");
    -$search_pcgtype = GETPOST("search_pcgtype");
    -$search_pcgsubtype = GETPOST("search_pcgsubtype");
    +$search_account = GETPOST('search_account','alpha');
    +$search_label = GETPOST('search_label','alpha');
    +$search_accountparent = GETPOST('search_accountparent','alpha');
    +$search_pcgtype = GETPOST('search_pcgtype','alpha');
    +$search_pcgsubtype = GETPOST('search_pcgsubtype','alpha');
     
     // Security check
     if ($user->societe_id > 0) accessforbidden();
    @@ -133,7 +133,7 @@ if (empty($reshook))
     				}
     				$offsetforchartofaccount+=($conf->entity  * 100000000);
     
    -				$result = run_sql($sqlfile, 1, $conf->entity, 1, '', 'default', $offsetforchartofaccount);
    +				$result = run_sql($sqlfile, 1, $conf->entity, 1, '', 'default', 32768, 0, $offsetforchartofaccount);
     
     				if ($result > 0)
     				{
    @@ -427,5 +427,6 @@ if ($resql)
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php
    index f024f54c41c..d3843763732 100644
    --- a/htdocs/accountancy/admin/accountmodel.php
    +++ b/htdocs/accountancy/admin/accountmodel.php
    @@ -55,8 +55,8 @@ $acts[1] = "disable";
     $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
     $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
     
    -$listoffset=GETPOST('listoffset');
    -$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
    +$listoffset=GETPOST('listoffset','alpha');
    +$listlimit=GETPOST('listlimit','int')>0?GETPOST('listlimit','int'):1000;
     $active = 1;
     
     $sortfield = GETPOST("sortfield",'aZ09comma');
    @@ -139,13 +139,13 @@ $sourceList=array();
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter_x','alpha'))
     {
     	$search_country_id = '';
     }
     
     // Actions add or modify an entry into a dictionary
    -if (GETPOST('actionadd') || GETPOST('actionmodify'))
    +if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha'))
     {
     	$listfield=explode(',', str_replace(' ', '',$tabfield[$id]));
     	$listfieldinsert=explode(',',$tabfieldinsert[$id]);
    @@ -235,7 +235,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]='';	// If empty, we force to null
     
     	// Si verif ok et action add, on ajoute la ligne
    -	if ($ok && GETPOST('actionadd'))
    +	if ($ok && GETPOST('actionadd','alpha'))
     	{
     		if ($tabrowid[$id])
     		{
    @@ -247,7 +247,6 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     			{
     				$obj = $db->fetch_object($result);
     				$newid=($obj->newid + 1);
    -
     			} else {
     				dol_print_error($db);
     			}
    @@ -300,7 +299,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	}
     
     	// Si verif ok et action modify, on modifie la ligne
    -	if ($ok && GETPOST('actionmodify'))
    +	if ($ok && GETPOST('actionmodify','alpha'))
     	{
     		if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
     		else { $rowidcol="rowid"; }
    @@ -341,7 +340,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
     
    -if (GETPOST('actioncancel'))
    +if (GETPOST('actioncancel','alpha'))
     {
     	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
    @@ -524,62 +523,18 @@ if ($id)
     			$valuetoshow=ucfirst($fieldlist[$field]);   // Par defaut
     			$valuetoshow=$langs->trans($valuetoshow);   // try to translate
     			$align="left";
    -			if ($fieldlist[$field]=='source')          { $valuetoshow=$langs->trans("Contact"); }
    -			if ($fieldlist[$field]=='price')           { $valuetoshow=$langs->trans("PriceUHT"); }
    -			if ($fieldlist[$field]=='taux')            {
    -				if ($tabname[$id] != MAIN_DB_PREFIX."c_revenuestamp") $valuetoshow=$langs->trans("Rate");
    -				else $valuetoshow=$langs->trans("Amount");
    -				$align='right';
    -			}
    -			if ($fieldlist[$field]=='localtax1_type')  { $valuetoshow=$langs->trans("UseLocalTax")." 2"; $align="center"; $sortable=0; }
    -			if ($fieldlist[$field]=='localtax1')       { $valuetoshow=$langs->trans("Rate")." 2";}
    -			if ($fieldlist[$field]=='localtax2_type')  { $valuetoshow=$langs->trans("UseLocalTax")." 3"; $align="center"; $sortable=0; }
    -			if ($fieldlist[$field]=='localtax2')       { $valuetoshow=$langs->trans("Rate")." 3";}
    -			if ($fieldlist[$field]=='organization')    { $valuetoshow=$langs->trans("Organization"); }
    -			if ($fieldlist[$field]=='lang')            { $valuetoshow=$langs->trans("Language"); }
    -			if ($fieldlist[$field]=='type')            {
    -				if ($tabname[$id] == MAIN_DB_PREFIX."c_paiement") $valuetoshow=$form->textwithtooltip($langs->trans("Type"),$langs->trans("TypePaymentDesc"),2,1,img_help(1,''));
    -				else $valuetoshow=$langs->trans("Type");
    -			}
     			if ($fieldlist[$field]=='code')            { $valuetoshow=$langs->trans("Code"); }
     			if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label')
     			{
     				$valuetoshow=$langs->trans("Label");
     				if ($id != 25) $valuetoshow.="*";
     			}
    -			if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments")."*"; }
     			if ($fieldlist[$field]=='country')         {
     				if (in_array('region_id',$fieldlist)) { print '<td>&nbsp;</td>'; continue; }		// For region page, we do not show the country input
     				$valuetoshow=$langs->trans("Country");
     			}
    -			if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; }
    -			if ($fieldlist[$field]=='nbjour')          { $valuetoshow=$langs->trans("NbOfDays"); }
    -			if ($fieldlist[$field]=='type_cdr')        { $valuetoshow=$langs->trans("AtEndOfMonth"); $align="center"; }
    -			if ($fieldlist[$field]=='decalage')        { $valuetoshow=$langs->trans("Offset"); }
    -			if ($fieldlist[$field]=='width')           { $valuetoshow=$langs->trans("Width"); }
    -			if ($fieldlist[$field]=='height')          { $valuetoshow=$langs->trans("Height"); }
    -			if ($fieldlist[$field]=='unit')            { $valuetoshow=$langs->trans("MeasuringUnit"); }
    -			if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $valuetoshow=''; }
    -			if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); }
    -			if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); }
    -			if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); }
    +			if ($fieldlist[$field]=='country_id') { $valuetoshow=''; }
     			if ($fieldlist[$field]=='pcg_version' || $fieldlist[$field]=='fk_pcg_version') { $valuetoshow=$langs->trans("Pcg_version"); }
    -			if ($fieldlist[$field]=='account_parent')  { $valuetoshow=$langs->trans("Accountparent"); }
    -			if ($fieldlist[$field]=='pcg_type')        { $valuetoshow=$langs->trans("Pcg_type"); }
    -			if ($fieldlist[$field]=='pcg_subtype')     { $valuetoshow=$langs->trans("Pcg_subtype"); }
    -			if ($fieldlist[$field]=='sortorder')       { $valuetoshow=$langs->trans("SortOrder"); }
    -			if ($fieldlist[$field]=='short_label')     { $valuetoshow=$langs->trans("ShortLabel"); }
    -			if ($fieldlist[$field]=='type_template')   { $valuetoshow=$langs->trans("TypeOfTemplate"); }
    -			if ($fieldlist[$field]=='range_account')   { $valuetoshow=$langs->trans("Range"); }
    -			if ($fieldlist[$field]=='sens')            { $valuetoshow=$langs->trans("Sens"); }
    -			if ($fieldlist[$field]=='category_type')   { $valuetoshow=$langs->trans("Calculated"); }
    -			if ($fieldlist[$field]=='formula')         { $valuetoshow=$langs->trans("Formula"); }
    -
    -			if ($id == 2)	// Special cas for state page
    -			{
    -				if ($fieldlist[$field]=='region_id') { $valuetoshow='&nbsp;'; $showfield=1; }
    -				if ($fieldlist[$field]=='region') { $valuetoshow=$langs->trans("Country").'/'.$langs->trans("Region"); $showfield=1; }
    -			}
     
     			if ($valuetoshow != '')
     			{
    @@ -604,7 +559,7 @@ if ($id)
     
     		$obj = new stdClass();
     		// If data was already input, we define them in obj to populate input fields.
    -		if (GETPOST('actionadd'))
    +		if (GETPOST('actionadd','alpha'))
     		{
     			foreach ($fieldlist as $key=>$val)
     			{
    @@ -709,50 +664,15 @@ if ($id)
     			*/
     			$valuetoshow=ucfirst($fieldlist[$field]);   // By defaut
     			$valuetoshow=$langs->trans($valuetoshow);   // try to translate
    -			if ($fieldlist[$field]=='source')          { $valuetoshow=$langs->trans("Contact"); }
    -			if ($fieldlist[$field]=='price')           { $valuetoshow=$langs->trans("PriceUHT"); }
    -			if ($fieldlist[$field]=='taux')            {
    -				if ($tabname[$id] != MAIN_DB_PREFIX."c_revenuestamp") $valuetoshow=$langs->trans("Rate");
    -				else $valuetoshow=$langs->trans("Amount");
    -				$align='right';
    -			}
    -			if ($fieldlist[$field]=='localtax1_type')  { $valuetoshow=$langs->trans("UseLocalTax")." 2"; $align="center"; $sortable=0; }
    -			if ($fieldlist[$field]=='localtax1')       { $valuetoshow=$langs->trans("Rate")." 2"; $sortable=0; }
    -			if ($fieldlist[$field]=='localtax2_type')  { $valuetoshow=$langs->trans("UseLocalTax")." 3"; $align="center"; $sortable=0; }
    -			if ($fieldlist[$field]=='localtax2')       { $valuetoshow=$langs->trans("Rate")." 3"; $sortable=0; }
    -			if ($fieldlist[$field]=='organization')    { $valuetoshow=$langs->trans("Organization"); }
    -			if ($fieldlist[$field]=='lang')            { $valuetoshow=$langs->trans("Language"); }
    -			if ($fieldlist[$field]=='type')            { $valuetoshow=$langs->trans("Type"); }
     			if ($fieldlist[$field]=='code')            { $valuetoshow=$langs->trans("Code"); }
     			if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label')
     			{
     				$valuetoshow=$langs->trans("Label");
     			   	if ($id != 25) $valuetoshow.="*";
     			}
    -			if ($fieldlist[$field]=='libelle_facture') { $valuetoshow=$langs->trans("LabelOnDocuments")."*"; }
     			if ($fieldlist[$field]=='country')         { $valuetoshow=$langs->trans("Country"); }
    -			if ($fieldlist[$field]=='recuperableonly') { $valuetoshow=$langs->trans("NPR"); $align="center"; }
    -			if ($fieldlist[$field]=='nbjour')          { $valuetoshow=$langs->trans("NbOfDays"); }
    -			if ($fieldlist[$field]=='type_cdr')        { $valuetoshow=$langs->trans("AtEndOfMonth"); $align="center"; }
    -			if ($fieldlist[$field]=='decalage')        { $valuetoshow=$langs->trans("Offset"); }
    -			if ($fieldlist[$field]=='width')           { $valuetoshow=$langs->trans("Width"); }
    -			if ($fieldlist[$field]=='height')          { $valuetoshow=$langs->trans("Height"); }
    -			if ($fieldlist[$field]=='unit')            { $valuetoshow=$langs->trans("MeasuringUnit"); }
    -			if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; }
    -			if ($fieldlist[$field]=='accountancy_code'){ $valuetoshow=$langs->trans("AccountancyCode"); }
    -			if ($fieldlist[$field]=='accountancy_code_sell'){ $valuetoshow=$langs->trans("AccountancyCodeSell"); $sortable=0; }
    -			if ($fieldlist[$field]=='accountancy_code_buy'){ $valuetoshow=$langs->trans("AccountancyCodeBuy"); $sortable=0; }
    +			if ($fieldlist[$field]=='country_id') { $showfield=0; }
     			if ($fieldlist[$field]=='fk_pcg_version')  { $valuetoshow=$langs->trans("Pcg_version"); }
    -			if ($fieldlist[$field]=='account_parent')  { $valuetoshow=$langs->trans("Accountsparent"); }
    -			if ($fieldlist[$field]=='pcg_type')        { $valuetoshow=$langs->trans("Pcg_type"); }
    -			if ($fieldlist[$field]=='pcg_subtype')     { $valuetoshow=$langs->trans("Pcg_subtype"); }
    -			if ($fieldlist[$field]=='sortorder')       { $valuetoshow=$langs->trans("SortOrder"); }
    -			if ($fieldlist[$field]=='short_label')     { $valuetoshow=$langs->trans("ShortLabel"); }
    -			if ($fieldlist[$field]=='type_template')   { $valuetoshow=$langs->trans("TypeOfTemplate"); }
    -			if ($fieldlist[$field]=='range_account')   { $valuetoshow=$langs->trans("Range"); }
    -			if ($fieldlist[$field]=='sens')            { $valuetoshow=$langs->trans("Sens"); }
    -			if ($fieldlist[$field]=='category_type')   { $valuetoshow=$langs->trans("Calculated"); }
    -			if ($fieldlist[$field]=='formula')         { $valuetoshow=$langs->trans("Formula"); }
     
     			// Affiche nom du champ
     			if ($showfield)
    @@ -832,120 +752,9 @@ if ($id)
     									$valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country);
     								}
     							}
    -							else if ($fieldlist[$field]=='recuperableonly' || $fieldlist[$field]=='type_cdr' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') {
    -								if(empty($valuetoshow)) $valuetoshow = $langs->trans('None');
    -								elseif($valuetoshow == 1) $valuetoshow = $langs->trans('AtEndOfMonth');
    -								elseif($valuetoshow == 2) $valuetoshow = $langs->trans('CurrentNext');
    -								$align="center";
    -							}
    -							else if ($fieldlist[$field]=='price' || preg_match('/^amount/i',$fieldlist[$field])) {
    -								$valuetoshow=price($valuetoshow);
    -							}
    -							else if ($fieldlist[$field]=='libelle_facture') {
    -								$langs->loadLangs(array("bills"));
    -								$key=$langs->trans("PaymentCondition".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "PaymentCondition".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -								$valuetoshow=nl2br($valuetoshow);
    -							}
    -							else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_country') {
    -								$key=$langs->trans("Country".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "Country".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_availability') {
    -								$langs->loadLangs(array("propal"));
    -								$key=$langs->trans("AvailabilityType".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "AvailabilityType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_actioncomm') {
    -								$key=$langs->trans("Action".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "Action".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if (! empty($obj->code_iso) && $fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_currencies') {
    -								$key=$langs->trans("Currency".strtoupper($obj->code_iso));
    -								$valuetoshow=($obj->code_iso && $key != "Currency".strtoupper($obj->code_iso)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_typent') {
    -								$key=$langs->trans(strtoupper($obj->code));
    -								$valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_prospectlevel') {
    -								$key=$langs->trans(strtoupper($obj->code));
    -								$valuetoshow=($key != strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_civility') {
    -								$key=$langs->trans("Civility".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "Civility".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_type_contact') {
    -								$langs->loadLangs(array("agenda"));
    -								$key=$langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_payment_term') {
    -								$langs->loadLangs(array("bills"));
    -								$key=$langs->trans("PaymentConditionShort".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "PaymentConditionShort".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paiement') {
    -								$langs->loadLangs(array("bills"));
    -								$key=$langs->trans("PaymentType".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "PaymentType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='label' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_reason') {
    -								$key=$langs->trans("DemandReasonType".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "DemandReasonType".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_input_method') {
    -								$langs->loadLangs(array("orders"));
    -								$key=$langs->trans($obj->code);
    -								$valuetoshow=($obj->code && $key != $obj->code)?$key:$obj->{$fieldlist[$field]};
    -							}
    -							else if ($fieldlist[$field]=='libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_shipment_mode') {
    -								$langs->loadLangs(array("sendings"));
    -								$key=$langs->trans("SendingMethod".strtoupper($obj->code));
    -								$valuetoshow=($obj->code && $key != "SendingMethod".strtoupper($obj->code)?$key:$obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field] == 'libelle' && $tabname[$id]==MAIN_DB_PREFIX.'c_paper_format')
    -							{
    -								$key = $langs->trans('PaperFormat'.strtoupper($obj->code));
    -								$valuetoshow = ($obj->code && $key != 'PaperFormat'.strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_type_fees')
    -							{
    -								$langs->loadLangs(array("trips"));
    -								$key = $langs->trans(strtoupper($obj->code));
    -								$valuetoshow = ($obj->code && $key != strtoupper($obj->code) ? $key : $obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') {
    +							else if ($fieldlist[$field]=='country_id') {
     								$showfield=0;
     							}
    -							else if ($fieldlist[$field]=='unicode') {
    -								$valuetoshow = $langs->getCurrencySymbol($obj->code,1);
    -							}
    -							else if ($fieldlist[$field]=='label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') {
    -								$langs->loadLangs(array("products"));
    -								$valuetoshow=$langs->trans($obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='short_label' && $tabname[$_GET["id"]]==MAIN_DB_PREFIX.'c_units') {
    -								$langs->loadLangs(array("products"));
    -								$valuetoshow = $langs->trans($obj->{$fieldlist[$field]});
    -							}
    -							else if (($fieldlist[$field] == 'unit') && ($tabname[$id] == MAIN_DB_PREFIX.'c_paper_format'))
    -							{
    -								$key = $langs->trans('SizeUnit'.strtolower($obj->unit));
    -								$valuetoshow = ($obj->code && $key != 'SizeUnit'.strtolower($obj->unit) ? $key : $obj->{$fieldlist[$field]});
    -							}
    -							else if ($fieldlist[$field]=='taux') {
    -								$valuetoshow = price($valuetoshow, 0, $langs, 0, 0);
    -								$align="right";
    -							}
    -							else if (in_array($fieldlist[$field],array('recuperableonly')))
    -							{
    -								$align="center";
    -							}
    -							else if ($fieldlist[$field]=='accountancy_code' || $fieldlist[$field]=='accountancy_code_sell' || $fieldlist[$field]=='accountancy_code_buy') {
    -								$valuetoshow = length_accountg($valuetoshow);
    -							}
     
     							$class='tddict';
     							if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto';
    @@ -956,17 +765,6 @@ if ($id)
     
     					// Can an entry be erased or disabled ?
     					$iserasable=1;$canbedisabled=1;$canbemodified=1;	// true by default
    -					if (isset($obj->code) && $id != 10)
    -					{
    -						if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i',$obj->code))) { $iserasable = 0; $canbedisabled = 0; }
    -						else if ($obj->code == 'RECEP') { $iserasable = 0; $canbedisabled = 0; }
    -						else if ($obj->code == 'EF0')   { $iserasable = 0; $canbedisabled = 0; }
    -					}
    -
    -					if (isset($obj->type) && in_array($obj->type, array('system', 'systemauto'))) { $iserasable=0; }
    -					if (in_array($obj->code, array('AC_OTH','AC_OTH_AUTO')) || in_array($obj->type, array('systemauto'))) { $canbedisabled=0; $canbedisabled = 0; }
    -					$canbemodified=$iserasable;
    -					if ($obj->code == 'RECEP') $canbemodified=1;
     
     					$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;
    @@ -1004,7 +802,7 @@ if ($id)
     
     print '<br>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
     
    @@ -1055,53 +853,7 @@ function fieldListAccountModel($fieldlist, $obj='', $tabname='', $context='')
     				print '</td>';
     			}
     		}
    -		elseif ($fieldlist[$field] == 'region')
    -		{
    -			print '<td>';
    -			$formcompany->select_region($region_id,'region');
    -			print '</td>';
    -		}
    -		elseif ($fieldlist[$field] == 'region_id')
    -		{
    -			$region_id = (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:0);
    -			print '<td>';
    -			print '<input type="hidden" name="'.$fieldlist[$field].'" value="'.$region_id.'">';
    -			print '</td>';
    -		}
    -		elseif ($fieldlist[$field] == 'lang')
    -		{
    -			print '<td>';
    -			print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT,'lang');
    -			print '</td>';
    -		}
    -		// Le type de template
    -		elseif ($fieldlist[$field] == 'type_template')
    -		{
    -			print '<td>';
    -			print $form->selectarray('type_template', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
    -			print '</td>';
    -		}
    -		// Le type de l'element (pour les type de contact)
    -		elseif ($fieldlist[$field] == 'element')
    -		{
    -			print '<td>';
    -			print $form->selectarray('element', $elementList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
    -			print '</td>';
    -		}
    -		// La source de l'element (pour les type de contact)
    -		elseif ($fieldlist[$field] == 'source')
    -		{
    -			print '<td>';
    -			print $form->selectarray('source', $sourceList,(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''));
    -			print '</td>';
    -		}
    -		elseif ($fieldlist[$field] == 'type' && $tabname == MAIN_DB_PREFIX."c_actioncomm")
    -		{
    -			print '<td>';
    -			print 'user<input type="hidden" name="type" value="user">';
    -			print '</td>';
    -		}
    -		elseif ($fieldlist[$field] == 'recuperableonly' || $fieldlist[$field] == 'type_cdr' || $fieldlist[$field] == 'deductible' || $fieldlist[$field] == 'category_type') {
    +		elseif ($fieldlist[$field] == 'type_cdr') {
     			if ($fieldlist[$field] == 'type_cdr') print '<td align="center">';
     			else print '<td>';
     			if ($fieldlist[$field] == 'type_cdr') {
    @@ -1111,49 +863,9 @@ function fieldListAccountModel($fieldlist, $obj='', $tabname='', $context='')
     			}
     			print '</td>';
     		}
    -		elseif (in_array($fieldlist[$field],array('nbjour','decalage','taux','localtax1','localtax2'))) {
    -			$align="left";
    -			if (in_array($fieldlist[$field],array('taux','localtax1','localtax2'))) $align="right";	// Fields aligned on right
    -			print '<td align="'.$align.'">';
    -			print '<input type="text" class="flat" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" size="3" name="'.$fieldlist[$field].'">';
    -			print '</td>';
    -		}
    -		elseif (in_array($fieldlist[$field], array('libelle_facture'))) {
    -			print '<td><textarea cols="30" rows="'.ROWS_2.'" class="flat" name="'.$fieldlist[$field].'">'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'</textarea></td>';
    -		}
    -		elseif (in_array($fieldlist[$field], array('content')))
    -		{
    -			print '<td>';
    -			if ($context != 'hide')
    -			{
    -				//print '<textarea cols="3" rows="'.ROWS_2.'" class="flat" name="'.$fieldlist[$field].'">'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'</textarea>';
    -				$okforextended=true;
    -				$doleditor = new DolEditor($fieldlist[$field], (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_5, '90%');
    -				print $doleditor->Create(1);
    -			}
    -			else print '&nbsp;';
    -			print '</td>';
    -		}
    -		elseif ($fieldlist[$field] == 'price' || preg_match('/^amount/i',$fieldlist[$field])) {
    -			print '<td><input type="text" class="flat" value="'.price((! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')).'" size="8" name="'.$fieldlist[$field].'"></td>';
    -		}
     		elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
     			print '<td><input type="text" class="flat" value="'.(! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" size="10" name="'.$fieldlist[$field].'"></td>';
     		}
    -		elseif ($fieldlist[$field] == 'accountancy_code' || $fieldlist[$field] == 'accountancy_code_sell' || $fieldlist[$field] == 'accountancy_code_buy')
    -		{
    -			print '<td>';
    -			if (! empty($conf->accounting->enabled))
    -			{
    -				$accountancy_account = (! empty($obj->$fieldlist[$field]) ? $obj->$fieldlist[$field] : 0);
    -				print $formaccounting->select_account($accountancy_account, $fieldlist[$field], 1, '', 1, 1, 'maxwidth200 maxwidthonsmartphone');
    -			}
    -			else
    -			{
    -				print '<input type="text" size="10" class="flat" value="'.(isset($obj->$fieldlist[$field])?$obj->$fieldlist[$field]:'').'" name="'.$fieldlist[$field].'">';
    -			}
    -			print '</td>';
    -		}
     		else
     		{
     			print '<td>';
    @@ -1161,7 +873,6 @@ function fieldListAccountModel($fieldlist, $obj='', $tabname='', $context='')
     			if ($fieldlist[$field]=='code') $size='size="8" ';
     			if ($fieldlist[$field]=='position') $size='size="4" ';
     			if ($fieldlist[$field]=='libelle') $size='centpercent';
    -			if ($fieldlist[$field]=='tracking') $class='centpercent';
     			if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" ';
     			print '<input type="text" '.$size.' class="flat'.($class?' '.$class:'').'" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
     			print '</td>';
    diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php
    index 9643227da64..74958d606ec 100644
    --- a/htdocs/accountancy/admin/card.php
    +++ b/htdocs/accountancy/admin/card.php
    @@ -73,25 +73,28 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount)
     		// To manage zero or not at the end of the accounting account
     		if($conf->global->ACCOUNTING_MANAGE_ZERO == 1)
     		{
    -			$account_number = GETPOST('account_number');
    +			$account_number = GETPOST('account_number','string');
     		}
     		else
     		{
    -			$account_number = clean_account(GETPOST('account_number'));
    +			$account_number = clean_account(GETPOST('account_number','string'));
     		}
     
    -		if (GETPOST('account_parent') <= 0) {
    +		if (GETPOST('account_parent','int') <= 0)
    +		{
     			$account_parent = 0;
    -		} else {
    +		}
    +		else
    +		{
     			$account_parent = GETPOST('account_parent','int');
     		}
     
     		$object->fk_pcg_version = $obj->pcg_version;
    -		$object->pcg_type = GETPOST('pcg_type');
    -		$object->pcg_subtype = GETPOST('pcg_subtype');
    +		$object->pcg_type = GETPOST('pcg_type','alpha');
    +		$object->pcg_subtype = GETPOST('pcg_subtype','alpha');
     		$object->account_number = $account_number;
     		$object->account_parent = $account_parent;
    -		$object->account_category = GETPOST('account_category');
    +		$object->account_category = GETPOST('account_category','alpha');
     		$object->label = GETPOST('label', 'alpha');
     		$object->active = 1;
     
    @@ -135,25 +138,28 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount)
     		// To manage zero or not at the end of the accounting account
     		if($conf->global->ACCOUNTING_MANAGE_ZERO == 1)
     		{
    -			$account_number = GETPOST('account_number');
    +			$account_number = GETPOST('account_number','string');
     		}
     		else
     		{
    -			$account_number = clean_account(GETPOST('account_number'));
    +			$account_number = clean_account(GETPOST('account_number','string'));
     		}
     
    -		if (GETPOST('account_parent') <= 0) {
    +		if (GETPOST('account_parent','int') <= 0)
    +		{
     			$account_parent = 0;
    -		} else {
    +		}
    +		else
    +		{
     			$account_parent = GETPOST('account_parent','int');
     		}
     
     		$object->fk_pcg_version = $obj->pcg_version;
    -		$object->pcg_type = GETPOST('pcg_type');
    -		$object->pcg_subtype = GETPOST('pcg_subtype');
    +		$object->pcg_type = GETPOST('pcg_type','alpha');
    +		$object->pcg_subtype = GETPOST('pcg_subtype','alpha');
     		$object->account_number = $account_number;
     		$object->account_parent = $account_parent;
    -		$object->account_category = GETPOST('account_category');
    +		$object->account_category = GETPOST('account_category','alpha');
     		$object->label = GETPOST('label', 'alpha');
     
     		$result = $object->update($user);
    @@ -397,6 +403,6 @@ else if ($id > 0 || $ref) {
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/accountancy/admin/categories.php b/htdocs/accountancy/admin/categories.php
    index aec34469559..6e003738173 100644
    --- a/htdocs/accountancy/admin/categories.php
    +++ b/htdocs/accountancy/admin/categories.php
    @@ -37,9 +37,9 @@ $id = GETPOST('id', 'int');
     $rowid = GETPOST('rowid', 'int');
     $cancel = GETPOST('cancel','alpha');
     $action = GETPOST('action','aZ09');
    -$cat_id = GETPOST('account_category');
    +$cat_id = GETPOST('account_category','int');
     $selectcpt = GETPOST('cpt_bk', 'array');
    -$cpt_id = GETPOST('cptid');
    +$cpt_id = GETPOST('cptid','int');
     
     if ($cat_id == 0) {
     	$cat_id = null;
    @@ -184,6 +184,6 @@ if ($action == 'display' || $action == 'delete') {
     	print "</table>";
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php
    index 15a50e7b8e8..9f6b0bf14fe 100644
    --- a/htdocs/accountancy/admin/categories_list.php
    +++ b/htdocs/accountancy/admin/categories_list.php
    @@ -51,8 +51,8 @@ $acts[1] = "disable";
     $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
     $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
     
    -$listoffset=GETPOST('listoffset');
    -$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
    +$listoffset=GETPOST('listoffset','alpha');
    +$listlimit=GETPOST('listlimit','int')>0?GETPOST('listlimit','int'):1000;
     $active = 1;
     
     $sortfield = GETPOST("sortfield",'aZ09comma');
    @@ -134,13 +134,13 @@ $sourceList=array();
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter_x','alpha'))
     {
         $search_country_id = '';
     }
     
     // Actions add or modify an entry into a dictionary
    -if (GETPOST('actionadd') || GETPOST('actionmodify'))
    +if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha'))
     {
         $listfield=explode(',', str_replace(' ', '',$tabfield[$id]));
         $listfieldinsert=explode(',',$tabfieldinsert[$id]);
    @@ -202,7 +202,6 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
                 {
                     $obj = $db->fetch_object($result);
                     $newid=($obj->newid + 1);
    -
                 } else {
                     dol_print_error($db);
                 }
    @@ -250,7 +249,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
         }
     
         // Si verif ok et action modify, on modifie la ligne
    -    if ($ok && GETPOST('actionmodify'))
    +    if ($ok && GETPOST('actionmodify','alpha'))
         {
             if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
             else { $rowidcol="rowid"; }
    @@ -291,7 +290,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
         //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
     
    -if (GETPOST('actioncancel'))
    +if (GETPOST('actioncancel','alpha'))
     {
         //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
    @@ -513,7 +512,7 @@ if ($id)
     
             $obj = new stdClass();
             // If data was already input, we define them in obj to populate input fields.
    -        if (GETPOST('actionadd'))
    +        if (GETPOST('actionadd','alpha'))
             {
                 foreach ($fieldlist as $key=>$val)
                 {
    @@ -800,7 +799,7 @@ if ($id)
     
     print '<br>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php
    index c33d4326836..31fc04fa745 100644
    --- a/htdocs/accountancy/admin/defaultaccounts.php
    +++ b/htdocs/accountancy/admin/defaultaccounts.php
    @@ -76,7 +76,7 @@ $list_account = array (
     $accounting_mode = empty($conf->global->ACCOUNTING_MODE) ? 'RECETTES-DEPENSES' : $conf->global->ACCOUNTING_MODE;
     
     
    -if (GETPOST('change_chart'))
    +if (GETPOST('change_chart', 'alpha'))
     {
         $chartofaccounts = GETPOST('chartofaccounts', 'int');
     
    @@ -190,5 +190,6 @@ print '<div class="center"><input type="submit" class="button" value="' . $langs
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php
    index 0308df2f400..eccb9b0c06f 100644
    --- a/htdocs/accountancy/admin/export.php
    +++ b/htdocs/accountancy/admin/export.php
    @@ -79,6 +79,7 @@ $model_option = array (
     /*
      * Actions
      */
    +
     if ($action == 'update') {
     	$error = 0;
     
    @@ -124,6 +125,8 @@ if ($action == 'update') {
     	}
     }
     
    +
    +
     /*
      * View
      */
    @@ -267,7 +270,7 @@ if ($num2) {
             } else {
                 print '<input type="text" size="20" id="'. $label .'" name="' . $key['label'] . '" value="' . $conf->global->$label . '">';
             }
    -		
    +
     		print '</td></tr>';
     	}
     
    @@ -278,5 +281,6 @@ print '<div class="center"><input type="submit" class="button" value="' . dol_es
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/fiscalyear.php b/htdocs/accountancy/admin/fiscalyear.php
    index 25223e70c68..62eda456fe7 100644
    --- a/htdocs/accountancy/admin/fiscalyear.php
    +++ b/htdocs/accountancy/admin/fiscalyear.php
    @@ -156,6 +156,6 @@ if ($result)
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/fiscalyear_card.php b/htdocs/accountancy/admin/fiscalyear_card.php
    index 32df9afc932..05c7a3fd174 100644
    --- a/htdocs/accountancy/admin/fiscalyear_card.php
    +++ b/htdocs/accountancy/admin/fiscalyear_card.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2014-2016  Alexandre Spangaro	<aspangaro@zendsi.com>
    +/* Copyright (C) 2014-2016  Alexandre Spangaro  <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -165,16 +166,16 @@ if ($action == 'create')
     	print '<table class="border" width="100%">';
     
     	// Label
    -	print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Label") . '</td><td><input name="label" size="32" value="' . GETPOST("label") . '"></td></tr>';
    +	print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Label") . '</td><td><input name="label" size="32" value="' . GETPOST('label', 'alpha') . '"></td></tr>';
     
     	// Date start
     	print '<tr><td class="fieldrequired">' . $langs->trans("DateStart") . '</td><td>';
    -	print $form->select_date(($date_start ? $date_start : ''), 'fiscalyear');
    +	print $form->selectDate(($date_start ? $date_start : ''), 'fiscalyear');
     	print '</td></tr>';
     
     	// Date end
     	print '<tr><td class="fieldrequired">' . $langs->trans("DateEnd") . '</td><td>';
    -	print $form->select_date(($date_end ? $date_end : - 1), 'fiscalyearend');
    +	print $form->selectDate(($date_end ? $date_end : - 1), 'fiscalyearend');
     	print '</td></tr>';
     
     	/*
    @@ -182,7 +183,7 @@ if ($action == 'create')
     	print '<tr>';
     	print '<td class="fieldrequired">' . $langs->trans("Status") . '</td>';
     	print '<td class="valeur">';
    -	print $form->selectarray('statut', $statut2label, GETPOST('statut'));
    +	print $form->selectarray('statut', $statut2label, GETPOST('statut', 'int'));
     	print '</td></tr>';
     	*/
     
    @@ -225,12 +226,12 @@ if ($action == 'create')
     
     			// Date start
     			print '<tr><td class="fieldrequired">' . $langs->trans("DateStart") . '</td><td>';
    -			print $form->select_date($object->date_start ? $object->date_start : - 1, 'fiscalyear');
    +			print $form->selectDate($object->date_start ? $object->date_start : - 1, 'fiscalyear');
     			print '</td></tr>';
     
     			// Date end
     			print '<tr><td class="fieldrequired">' . $langs->trans("DateEnd") . '</td><td>';
    -			print $form->select_date($object->date_end ? $object->date_end : - 1, 'fiscalyearend');
    +			print $form->selectDate($object->date_end ? $object->date_end : - 1, 'fiscalyearend');
     			print '</td></tr>';
     
     			// Statut
    @@ -318,5 +319,6 @@ if ($action == 'create')
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/fiscalyear_info.php b/htdocs/accountancy/admin/fiscalyear_info.php
    index f16e3b9ca0e..3141a624194 100644
    --- a/htdocs/accountancy/admin/fiscalyear_info.php
    +++ b/htdocs/accountancy/admin/fiscalyear_info.php
    @@ -58,5 +58,6 @@ if ($id) {
     	print '</div>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/importaccounts.php b/htdocs/accountancy/admin/importaccounts.php
    index 3af46eec1a4..a14509a2aee 100644
    --- a/htdocs/accountancy/admin/importaccounts.php
    +++ b/htdocs/accountancy/admin/importaccounts.php
    @@ -1,7 +1,8 @@
     <?php
     /* Copyright (C) 2013-2014 Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013-2017 Alexandre Spangaro   <aspangaro@zendsi.com> 
    + * Copyright (C) 2013-2017 Alexandre Spangaro   <aspangaro@zendsi.com>
      * Copyright (C) 2014      Florian Henry        <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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 +19,7 @@
      */
     
     /**
    - * \file 		htdocs/accountancy/admin/importaccounts.php
    + * \file        htdocs/accountancy/admin/importaccounts.php
      * \ingroup		Advanced accountancy
      * \brief 		Page import accounting account
      */
    @@ -71,10 +72,10 @@ if ($_POST["action"] == 'import') {
     
     				$accounting = new AccountingAccount($db);
     
    -				$monLabel = GETPOST('label' . $maLigneCochee);
    -				$monParentAccount = GETPOST('AccountParent' . $maLigneCochee);
    -				$monType = GETPOST('pcgType' . $maLigneCochee);
    -				$monSubType = GETPOST('pcgSubType' . $maLigneCochee);
    +				$monLabel = (string) GETPOST('label' . $maLigneCochee);
    +				$monParentAccount = (string) GETPOST('AccountParent' . $maLigneCochee);
    +				$monType = (string) GETPOST('pcgType' . $maLigneCochee);
    +				$monSubType = (string) GETPOST('pcgSubType' . $maLigneCochee);
     
     				$accounting->fk_pcg_version = $obj->pcg_version;
     				$accounting->account_number = $maLigneCochee;
    @@ -83,7 +84,7 @@ if ($_POST["action"] == 'import') {
     				$accounting->pcg_type = $monType;
     				$accounting->pcg_subtype = $monSubType;
     				$accounting->active = 1;
    -				
    +
     				$result = $accounting->create($user);
     				if ($result > 0) {
     					setEventMessages($langs->trans("AccountingAccountAdd"), null, 'mesgs');
    @@ -101,7 +102,7 @@ if ($_POST["action"] == 'import') {
     	print '<div><font color="red">' . $langs->trans("EndProcessing") . '</font></div>';
     }
     
    -// list accounting account from product 
    +// list accounting account from product
     
     $sql = "(SELECT p.rowid as product_id, p.accountancy_code_sell as accounting ";
     $sql .= " FROM  " . MAIN_DB_PREFIX . "product as p ";
    @@ -172,14 +173,15 @@ if ($result) {
     		print '</tr>';
     		$i ++;
     	}
    -	
    +
     	print '<tr><td colspan="8">&nbsp;</td></tr><tr><td colspan="8" align="center"><input type="submit" class="butAction" value="' . $langs->trans("Import") . '"></td></tr>';
    -	
    +
     	print '</table>';
     	print '</form>';
     } else {
     	print $db->error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php
    index e39d07fc35d..a17ee45ae4d 100644
    --- a/htdocs/accountancy/admin/index.php
    +++ b/htdocs/accountancy/admin/index.php
    @@ -295,5 +295,6 @@ print '<br>';
     print '<br>';
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php
    index ff3a38769b8..3511ae431ec 100644
    --- a/htdocs/accountancy/admin/journals_list.php
    +++ b/htdocs/accountancy/admin/journals_list.php
    @@ -51,8 +51,8 @@ $acts[1] = "disable";
     $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
     $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
     
    -$listoffset=GETPOST('listoffset');
    -$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
    +$listoffset=GETPOST('listoffset', 'alpha');
    +$listlimit=GETPOST('listlimit', 'int')>0?GETPOST('listlimit', 'int'):1000;
     $active = 1;
     
     $sortfield = GETPOST("sortfield",'alpha');
    @@ -128,28 +128,28 @@ complete_dictionary_with_modules($taborder,$tabname,$tablib,$tabsql,$tabsqlsort,
     
     // Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact")
     $elementList = array();
    -	// Must match ids defined into eldy.lib.php
    -	$sourceList = array(
    -			'1' => $langs->trans('AccountingJournalType1'),
    -			'2' => $langs->trans('AccountingJournalType2'),
    -			'3' => $langs->trans('AccountingJournalType3'),
    -			'4' => $langs->trans('AccountingJournalType4'),
    -			'5' => $langs->trans('AccountingJournalType5'),
    -			'8' => $langs->trans('AccountingJournalType8'),
    -			'9' => $langs->trans('AccountingJournalType9')
    -	);
    +// Must match ids defined into eldy.lib.php
    +$sourceList = array(
    +	'1' => $langs->trans('AccountingJournalType1'),
    +	'2' => $langs->trans('AccountingJournalType2'),
    +	'3' => $langs->trans('AccountingJournalType3'),
    +	'4' => $langs->trans('AccountingJournalType4'),
    +	'5' => $langs->trans('AccountingJournalType5'),
    +	'8' => $langs->trans('AccountingJournalType8'),
    +	'9' => $langs->trans('AccountingJournalType9'),
    +);
     
     /*
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha'))
     {
     	$search_country_id = '';
     }
     
     // Actions add or modify an entry into a dictionary
    -if (GETPOST('actionadd') || GETPOST('actionmodify'))
    +if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha'))
     {
     	$listfield=explode(',', str_replace(' ', '',$tabfield[$id]));
     	$listfieldinsert=explode(',',$tabfieldinsert[$id]);
    @@ -190,7 +190,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]='';	// If empty, we force to null
     
     	// Si verif ok et action add, on ajoute la ligne
    -	if ($ok && GETPOST('actionadd'))
    +	if ($ok && GETPOST('actionadd', 'alpha'))
     	{
     		if ($tabrowid[$id])
     		{
    @@ -202,7 +202,6 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     			{
     				$obj = $db->fetch_object($result);
     				$newid=($obj->newid + 1);
    -
     			} else {
     				dol_print_error($db);
     			}
    @@ -252,7 +251,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	}
     
     	// Si verif ok et action modify, on modifie la ligne
    -	if ($ok && GETPOST('actionmodify'))
    +	if ($ok && GETPOST('actionmodify', 'alpha'))
     	{
     		if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
     		else { $rowidcol="rowid"; }
    @@ -294,10 +293,10 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
     
    -if (GETPOST('actioncancel'))
    -{
    -	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
    -}
    +//if (GETPOST('actioncancel', 'alpha'))
    +//{
    +//	$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
    +//}
     
     if ($action == 'confirm_delete' && $confirm == 'yes')       // delete
     {
    @@ -462,7 +461,7 @@ if ($id)
     
     		$obj = new stdClass();
     		// If data was already input, we define them in obj to populate input fields.
    -		if (GETPOST('actionadd'))
    +		if (GETPOST('actionadd', 'alpha'))
     		{
     			foreach ($fieldlist as $key=>$val)
     			{
    @@ -504,7 +503,7 @@ if ($id)
     		$paramwithsearch = $param;
     		if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder;
     		if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield;
    -		if (GETPOST('from')) $paramwithsearch.= '&from='.GETPOST('from','alpha');
    +		if (GETPOST('from', 'alpha')) $paramwithsearch.= '&from='.GETPOST('from','alpha');
     
     		// There is several pages
     		if ($num > $listlimit)
    @@ -683,7 +682,7 @@ if ($id)
     
     print '<br>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php
    index 070e2f353c3..a84e2f6fcab 100644
    --- a/htdocs/accountancy/admin/productaccount.php
    +++ b/htdocs/accountancy/admin/productaccount.php
    @@ -62,8 +62,8 @@ $search_current_account_valid = GETPOST('search_current_account_valid', 'alpha')
     if ($search_current_account_valid == '') $search_current_account_valid='withoutvalidaccount';
     
     $accounting_product_mode = GETPOST('accounting_product_mode', 'alpha');
    -$btn_changeaccount = GETPOST('changeaccount');
    -$btn_changetype = GETPOST('changetype');
    +$btn_changeaccount = GETPOST('changeaccount', 'alpha');
    +$btn_changetype = GETPOST('changetype', 'alpha');
     
     $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",'alpha');
    @@ -173,7 +173,6 @@ if ($action == 'update') {
     
     				$cpt++;
     			}
    -
     		}
     
     		if ($ko) setEventMessages($langs->trans("XLineFailedToBeBinded", $ko), null, 'errors');
    @@ -495,5 +494,6 @@ if ($result)
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
    index fa1f4b396d5..9feb2a7c234 100644
    --- a/htdocs/accountancy/bookkeeping/balance.php
    +++ b/htdocs/accountancy/bookkeeping/balance.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2016       Olivier Geffroy     <jeff@jeffinfo.com>
    - * Copyright (C) 2016       Florian Henry       <florian.henry@open-concept.pro>
    - * Copyright (C) 2016-2018  Alexandre Spangaro  <aspangaro@zendsi.com>
    +/* Copyright (C) 2016       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2016       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2016-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -166,13 +167,18 @@ if ($action == 'export_csv')
     		print price($line->credit - $line->debit) . $sep;
     		print "\n";
     	}
    +
    +	exit;
     }
     
    -else {
    -	$title_page = $langs->trans("AccountBalance");
     
    -	llxHeader('', $title_page);
    +$title_page = $langs->trans("AccountBalance");
     
    +llxHeader('', $title_page);
    +
    +
    +if ($action != 'export_csv')
    +{
     	// List
     	$nbtotalofrecords = '';
     	if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
    @@ -205,9 +211,9 @@ else {
     
     	$moreforfilter .= '<div class="divsearchfield">';
     	$moreforfilter .= $langs->trans('DateStart') . ': ';
    -	$moreforfilter .= $form->select_date($search_date_start?$search_date_start:-1, 'date_start', 0, 0, 1, '', 1, 0, 1);
    +	$moreforfilter .= $form->selectDate($search_date_start?$search_date_start:-1, 'date_start', 0, 0, 1, '', 1, 0);
     	$moreforfilter .= $langs->trans('DateEnd') . ': ';
    -	$moreforfilter .= $form->select_date($search_date_end?$search_date_end:-1, 'date_end', 0, 0, 1, '', 1, 0, 1);
    +	$moreforfilter .= $form->selectDate($search_date_end?$search_date_end:-1, 'date_end', 0, 0, 1, '', 1, 0);
     	$moreforfilter .= '</div>';
     
     	if (! empty($moreforfilter)) {
    @@ -268,7 +274,7 @@ else {
     		{
     			// Affiche un Sous-Total par compte comptable
     			if ($displayed_account != "") {
    -				print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit - $sous_total_debit) . '</td>';
    +				print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price(price2num($sous_total_credit - $sous_total_debit)) . '</td>';
     				print "<td>&nbsp;</td>\n";
     				print '</tr>';
     			}
    @@ -299,18 +305,18 @@ else {
     		$sous_total_credit += $line->credit;
     	}
     
    -	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit - $sous_total_debit) . '</td>';
    +	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price(price2num($sous_total_credit - $sous_total_debit)) . '</td>';
     	print "<td>&nbsp;</td>\n";
     	print '</tr>';
     
    -	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap" align="right">' . price($total_debit) . '</td><td class="nowrap" align="right">' . price($total_credit) . '</td><td class="nowrap" align="right">' . price($total_credit - $total_debit) . '</td>';
    +	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap" align="right">' . price($total_debit) . '</td><td class="nowrap" align="right">' . price($total_credit) . '</td><td class="nowrap" align="right">' . price(price2num($total_credit - $total_debit)) . '</td>';
     	print "<td>&nbsp;</td>\n";
     	print '</tr>';
     
     	print "</table>";
     	print '</form>';
    -
    -	llxFooter();
     }
     
    +// End of page
    +llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/bookkeeping/balancebymonth.php b/htdocs/accountancy/bookkeeping/balancebymonth.php
    index 03265e434f6..a01c42b285a 100644
    --- a/htdocs/accountancy/bookkeeping/balancebymonth.php
    +++ b/htdocs/accountancy/bookkeeping/balancebymonth.php
    @@ -64,7 +64,7 @@ $result = $db->query($sql);
     if ($result) {
     	$row = $db->fetch_row($result);
     	$nbfac = $row[0];
    -	
    +
     	$db->free($result);
     }
     
    @@ -85,7 +85,7 @@ print '<td align="center">' . $langs->trans("SeptemberMin") . '</td>';
     print '<td align="center">' . $langs->trans("OctoberMin") . '</td>';
     print '<td align="center">' . $langs->trans("NovemberMin") . '</td>';
     print '<td align="center">' . $langs->trans("DecemberMin") . '</td>';
    -print '<td align="center"><b>Total</b></td>';
    +print '<td align="center"><strong>Total</strong></td>';
     print '</tr>';
     
     $sql = "SELECT bk.numero_compte AS 'compte',";
    @@ -111,11 +111,11 @@ $resql = $db->query($sql);
     if ($resql) {
     	$i = 0;
     	$num = $db->num_rows($resql);
    -	
    +
     	while ( $i < $num ) {
    -		
    +
     		$row = $db->fetch_row($resql);
    -		
    +
     		print '<tr class="oddeven"><td width="14%">' . length_accountg($row[0]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[1]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[2]) . '</td>';
    @@ -129,9 +129,9 @@ if ($resql) {
     		print '<td align="right" width="6.5%">' . price($row[10]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[11]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[12]) . '</td>';
    -		print '<td align="right" width="8%"><b>' . price($row[13]) . '</b></td>';
    +		print '<td align="right" width="8%"><strong>' . price($row[13]) . '</strong></td>';
     		print '</tr>';
    -		
    +
     		$i ++;
     	}
     	$db->free($resql);
    @@ -140,5 +140,6 @@ if ($resql) {
     }
     print "</table>\n";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php
    index 92c5713880c..567fccaeab1 100644
    --- a/htdocs/accountancy/bookkeeping/card.php
    +++ b/htdocs/accountancy/bookkeeping/card.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2013-2017 Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013-2017 Florian Henry        <florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2018 Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2017      Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2013-2017  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2017  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2017       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -31,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
     require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("accountancy", "bills", "compta"));
    @@ -48,12 +50,21 @@ if ($user->societe_id > 0) {
     
     $mesg = '';
     
    -$account_number = GETPOST('account_number','alphanohtml');
    +$accountingaccount = new AccountingAccount($db);
    +$accountingjournal = new AccountingJournal($db);
    +
    +$accountingaccount_number = GETPOST('accountingaccount_number','alphanohtml');
    +$accountingaccount->fetch(null, $accountingaccount_number, true);
    +$accountingaccount_label = $accountingaccount->label;
    +
    +$journal_code = GETPOST('code_journal','alpha');
    +$accountingjournal->fetch(null, $journal_code);
    +$journal_label = $accountingjournal->label;
    +
     $subledger_account = GETPOST('subledger_account','alphanohtml');
     if ($subledger_account == - 1) {
     	$subledger_account = null;
     }
    -$label_compte = GETPOST('label_compte','alphanohtml');
     $label_operation= GETPOST('label_operation','alphanohtml');
     $debit = price2num(GETPOST('debit','alpha'));
     $credit = price2num(GETPOST('credit','alpha'));
    @@ -79,7 +90,7 @@ if ($action == "confirm_update") {
     		setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
     		$action='update';
     	}
    -	if (empty($account_number) || $account_number == '-1')
    +	if (empty($accountingaccount_number) || $accountingaccount_number == '-1')
     	{
     		$error++;
     		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
    @@ -95,9 +106,9 @@ if ($action == "confirm_update") {
     			$error++;
     			setEventMessages($object->error, $object->errors, 'errors');
     		} else {
    -			$object->numero_compte = $account_number;
    +			$object->numero_compte = $accountingaccount_number;
     			$object->subledger_account = $subledger_account;
    -			$object->label_compte = $label_compte;
    +			$object->label_compte = $accountingaccount_label;
     			$object->label_operation= $label_operation;
     			$object->debit = $debit;
     			$object->credit = $credit;
    @@ -138,7 +149,7 @@ else if ($action == "add") {
     		setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
     		$action='';
     	}
    -	if (empty($account_number) || $account_number == '-1')
    +	if (empty($accountingaccount_number) || $accountingaccount_number == '-1')
     	{
     		$error++;
     		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
    @@ -148,9 +159,9 @@ else if ($action == "add") {
     	if (! $error) {
     		$object = new BookKeeping($db);
     
    -		$object->numero_compte = $account_number;
    +		$object->numero_compte = $accountingaccount_number;
     		$object->subledger_account = $subledger_account;
    -		$object->label_compte = $label_compte;
    +		$object->label_compte = $accountingaccount_label;
     		$object->label_operation= $label_operation;
     		$object->debit = $debit;
     		$object->credit = $credit;
    @@ -158,7 +169,8 @@ else if ($action == "add") {
     		$object->doc_type = GETPOST('doc_type','alpha');
     		$object->piece_num = $piece_num;
     		$object->doc_ref = GETPOST('doc_ref','alpha');
    -		$object->code_journal = GETPOST('code_journal','alpha');
    +		$object->code_journal = $journal_code;
    +		$object->journal_label = $journal_label;
     		$object->fk_doc = GETPOST('fk_doc','alpha');
     		$object->fk_docdet = GETPOST('fk_docdet','alpha');
     
    @@ -211,12 +223,12 @@ else if ($action == "confirm_create") {
     
     	$object = new BookKeeping($db);
     
    -	if (! GETPOST('code_journal','alpha') || GETPOST('code_journal','alpha') == '-1') {
    +	if (! $journal_code || $journal_code == '-1') {
     		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Journal")), null, 'errors');
     		$action='create';
     		$error++;
     	}
    -	if (! GETPOST('next_num_mvt'))
    +	if (! GETPOST('next_num_mvt', 'alpha'))
     	{
     		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumPiece")), null, 'errors');
     		$error++;
    @@ -231,7 +243,8 @@ else if ($action == "confirm_create") {
     		$object->doc_type = GETPOST('doc_type','alpha');
     		$object->piece_num = GETPOST('next_num_mvt','alpha');
     		$object->doc_ref = GETPOST('doc_ref','alpha');
    -		$object->code_journal = GETPOST('code_journal','alpha');
    +		$object->code_journal = $journal_code;
    +		$object->journal_label = $journal_label;
     		$object->fk_doc = 0;
     		$object->fk_docdet = 0;
     		$object->montant = 0;
    @@ -252,7 +265,7 @@ else if ($action == "confirm_create") {
     }
     
     if ($action == 'setdate') {
    -	$datedoc = dol_mktime(0, 0, 0, GETPOST('doc_datemonth'), GETPOST('doc_dateday'), GETPOST('doc_dateyear'));
    +	$datedoc = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int'));
     	$result = $object->updateByMvt($piece_num,'doc_date',$db->idate($datedoc),$mode);
     	if ($result < 0) {
     		setEventMessages($object->error, $object->errors, 'errors');
    @@ -266,8 +279,8 @@ if ($action == 'setdate') {
     }
     
     if ($action == 'setjournal') {
    -	$journaldoc = trim(GETPOST('code_journal','alpha'));
    -	$result = $object->updateByMvt($piece_num, 'code_journal', $journaldoc, $mode);
    +	$result = $object->updateByMvt($piece_num, 'code_journal', $journal_code, $mode);
    +	$result = $object->updateByMvt($piece_num, 'journal_label', $journal_label, $mode);
     	if ($result < 0) {
     		setEventMessages($object->error, $object->errors, 'errors');
     	} else {
    @@ -311,7 +324,6 @@ if ($action == 'valid') {
     
     $html = new Form($db);
     $formaccounting = new FormAccounting($db);
    -$accountjournal = new AccountingJournal($db);
     
     llxHeader('', $langs->trans("CreateMvts"));
     
    @@ -350,13 +362,13 @@ if ($action == 'create')
     	print '<tr>';
     	print '<td class="titlefieldcreate fieldrequired">' . $langs->trans("Docdate") . '</td>';
     	print '<td>';
    -	print $html->select_date('', 'doc_date', '', '', '', "create_mvt", 1, 1);
    +	print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
     	print '</td>';
     	print '</tr>';
     
     	print '<tr>';
     	print '<td class="fieldrequired">' . $langs->trans("Codejournal") . '</td>';
    -	print '<td>' . $formaccounting->select_journal(GETPOST('code_journal'),'code_journal',0,1,array(),1,1) . '</td>';
    +	print '<td>' . $formaccounting->select_journal($journal_code,'code_journal',0,0,1,1) . '</td>';
     	print '</tr>';
     
     	print '<tr>';
    @@ -432,7 +444,7 @@ if ($action == 'create')
     			print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
     			print '<input type="hidden" name="action" value="setdate">';
     			print '<input type="hidden" name="mode" value="'.$mode.'">';
    -			$form->select_date($object->doc_date ? $object->doc_date : - 1, 'doc_date', '', '', '', "setdate");
    +			print $form->selectDate($object->doc_date ? $object->doc_date : - 1, 'doc_date', '', '', '', "setdate");
     			print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     			print '</form>';
     		} else {
    @@ -459,7 +471,7 @@ if ($action == 'create')
     			print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     			print '</form>';
     		} else {
    -		print $object->code_journal ;
    +			print $object->code_journal ;
     		}
     		print '</td>';
     		print '</tr>';
    @@ -589,7 +601,6 @@ if ($action == 'create')
     
     				print_liste_field_titre("AccountAccountingShort");
     				print_liste_field_titre("SubledgerAccount");
    -				print_liste_field_titre("LabelAccount");
     				print_liste_field_titre("LabelOperation");
     				print_liste_field_titre("Debit", "", "", "", "", 'align="right"');
     				print_liste_field_titre("Credit", "", "", "", "", 'align="right"');
    @@ -604,7 +615,7 @@ if ($action == 'create')
     
     					if ($action == 'update' && $line->id == $id) {
     						print '<td>';
    -						print $formaccounting->select_account($line->numero_compte, 'account_number', 1, array (), 1, 1, '');
    +						print $formaccounting->select_account($line->numero_compte, 'accountingaccount_number', 1, array (), 1, 1, '');
     						print '</td>';
     						print '<td>';
     						// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not
    @@ -618,7 +629,6 @@ if ($action == 'create')
     							print '<input type="text" name="subledger_account" value="'.$line->subledger_account.'">';
     						}
     						print '</td>';
    -						print '<td><input type="text" class="minwidth100" name="label_compte" value="' . $line->label_compte . '"/></td>';
     						print '<td><input type="text" class="minwidth200" name="label_operation" value="' . $line->label_operation. '"/></td>';
     						print '<td align="right"><input type="text" size="6" class="right" name="debit" value="' . price($line->debit) . '"/></td>';
     						print '<td align="right"><input type="text" size="6" class="right" name="credit" value="' . price($line->credit) . '"/></td>';
    @@ -627,9 +637,9 @@ if ($action == 'create')
     						print '<input type="submit" class="button" name="update" value="' . $langs->trans("Update") . '">';
     						print '</td>';
     					} else {
    -						print '<td>' . length_accountg($line->numero_compte) . '</td>';
    +						$accountingaccount->fetch(null, $line->numero_compte, true);
    +						print '<td>' . $accountingaccount->getNomUrl(0,1,1,'',0) . '</td>';
     						print '<td>' . length_accounta($line->subledger_account) . '</td>';
    -						print '<td>' . $line->label_compte . '</td>';
     						print '<td>' . $line->label_operation. '</td>';
     						print '<td align="right">' . price($line->debit) . '</td>';
     						print '<td align="right">' . price($line->credit) . '</td>';
    @@ -662,7 +672,7 @@ if ($action == 'create')
     				if ($action == "" || $action == 'add') {
     					print '<tr class="oddeven">';
     					print '<td>';
    -					print $formaccounting->select_account($account_number, 'account_number', 1, array (), 1, 1, '');
    +					print $formaccounting->select_account($accountingaccount_number, 'accountingaccount_number', 1, array (), 1, 1, '');
     					print '</td>';
     					print '<td>';
     					// TODO For the moment we keep a fre input text instead of a combo. The select_auxaccount has problem because it does not
    @@ -676,7 +686,6 @@ if ($action == 'create')
     						print '<input type="text" name="subledger_account" value="">';
     					}
     					print '</td>';
    -					print '<td><input type="text" class="minwidth100" name="label_compte" value=""/></td>';
     					print '<td><input type="text" class="minwidth200" name="label_operation" value=""/></td>';
     					print '<td align="right"><input type="text" size="6" class="right" name="debit" value=""/></td>';
     					print '<td align="right"><input type="text" size="6" class="right" name="credit" value=""/></td>';
    @@ -714,5 +723,6 @@ if ($action == 'create')
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
    index b0a91f7ce36..46575c21143 100644
    --- a/htdocs/accountancy/bookkeeping/list.php
    +++ b/htdocs/accountancy/bookkeeping/list.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2013-2016  Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013-2016  Florian Henry        <florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2017  Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2016-2017  Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2016-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -78,6 +79,7 @@ $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', 'alpha');
    +$search_lettering_code = GETPOST('search_lettering_code', '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);
    @@ -137,11 +139,14 @@ $arrayfields=array(
     	't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
     	't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1),
     	't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1),
    +	't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1),
     	't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1),
     	't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0),
     	't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0),
     );
     
    +if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) unset($arrayfields['t.lettering_code']);
    +
     
     /*
      * Actions
    @@ -175,6 +180,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     	$search_date_modification_end = '';
     	$search_debit = '';
     	$search_credit = '';
    +	$search_lettering_code = '';
     }
     
     // Must be after the remove filter action, before the export.
    @@ -271,6 +277,10 @@ 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 ($action == 'delbookkeeping') {
    @@ -336,7 +346,7 @@ if ($action == 'delmouvconfirm') {
     	}
     }
     
    -// Export into a file with format defined into setup
    +// Export into a file with format defined into setup (FEC, CSV, ...)
     if ($action == 'export_file') {
     
     	$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
    @@ -349,7 +359,9 @@ if ($action == 'export_file') {
     	{
     		$accountancyexport = new AccountancyExport($db);
     		$accountancyexport->export($object->lines);
    -		if (!empty($accountancyexport->errors)) {
    +
    +		if (!empty($accountancyexport->errors))
    +		{
     			setEventMessages('', $accountancyexport->errors, 'errors');
     		}
     		exit;
    @@ -465,11 +477,11 @@ if (! empty($arrayfields['t.doc_date']['checked']))
     	print '<td class="liste_titre center">';
     	print '<div class="nowrap">';
     	print $langs->trans('From') . ' ';
    -	print $form->select_date($search_date_start?$search_date_start:-1, 'search_date_start', 0, 0, 1);
    +	print $form->selectDate($search_date_start?$search_date_start:-1, 'search_date_start', 0, 0, 1);
     	print '</div>';
     	print '<div class="nowrap">';
     	print $langs->trans('to') . ' ';
    -	print $form->select_date($search_date_end?$search_date_end:-1, 'search_date_end', 0, 0, 1);
    +	print $form->selectDate($search_date_end?$search_date_end:-1, 'search_date_end', 0, 0, 1);
     	print '</div>';
     	print '</td>';
     }
    @@ -545,6 +557,13 @@ if (! empty($arrayfields['t.credit']['checked']))
     	print '<input type="text" class="flat" name="search_credit" size="4" value="'.dol_escape_htmltag($search_credit).'">';
     	print '</td>';
     }
    +// Lettering code
    +if (! empty($arrayfields['t.lettering_code']['checked']))
    +{
    +	print '<td class="liste_titre center">';
    +	print '<input type="text" size="3" class="flat" name="search_lettering_code" value="' . $search_lettering_code . '"/>';
    +	print '</td>';
    +}
     // Code journal
     if (! empty($arrayfields['t.code_journal']['checked']))
     {
    @@ -556,11 +575,11 @@ if (! empty($arrayfields['t.date_creation']['checked']))
     	print '<td class="liste_titre center">';
     	print '<div class="nowrap">';
     	print $langs->trans('From') . ' ';
    -	print $form->select_date($search_date_creation_start, 'date_creation_start', 0, 0, 1);
    +	print $form->selectDate($search_date_creation_start, 'date_creation_start', 0, 0, 1);
     	print '</div>';
     	print '<div class="nowrap">';
     	print $langs->trans('to') . ' ';
    -	print $form->select_date($search_date_creation_end, 'date_creation_end', 0, 0, 1);
    +	print $form->selectDate($search_date_creation_end, 'date_creation_end', 0, 0, 1);
     	print '</div>';
     	print '</td>';
     }
    @@ -570,11 +589,11 @@ if (! empty($arrayfields['t.tms']['checked']))
     	print '<td class="liste_titre center">';
     	print '<div class="nowrap">';
     	print $langs->trans('From') . ' ';
    -	print $form->select_date($search_date_modification_start, 'date_modification_start', 0, 0, 1);
    +	print $form->selectDate($search_date_modification_start, 'date_modification_start', 0, 0, 1);
     	print '</div>';
     	print '<div class="nowrap">';
     	print $langs->trans('to') . ' ';
    -	print $form->select_date($search_date_modification_end, 'date_modification_end', 0, 0, 1);
    +	print $form->selectDate($search_date_modification_end, 'date_modification_end', 0, 0, 1);
     	print '</div>';
     	print '</td>';
     }
    @@ -594,6 +613,7 @@ if (! empty($arrayfields['t.subledger_account']['checked']))	print_liste_field_t
     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, 'align="right"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.credit']['checked']))				print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder);
    +if (! empty($arrayfields['t.lettering_code']['checked']))		print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, 'align="center"', $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, 'align="center"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.date_creation']['checked']))		print_liste_field_titre($arrayfields['t.date_creation']['label'], $_SERVER['PHP_SELF'], "t.date_creation", "", $param, 'align="center"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.tms']['checked']))					print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER['PHP_SELF'], "t.tms", "", $param, 'align="center"', $sortfield, $sortorder);
    @@ -679,6 +699,13 @@ if ($num > 0)
     			$totalarray['totalcredit'] += $line->credit;
     		}
     
    +		// Lettering code
    +		if (! empty($arrayfields['t.lettering_code']['checked']))
    +		{
    +			print '<td align="center">' . $line->lettering_code . '</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
    +
     		// Journal code
     		if (! empty($arrayfields['t.code_journal']['checked']))
     		{
    @@ -733,7 +760,6 @@ if ($num > 0)
     				else print '<td></td>';
     		}
     		print '</tr>';
    -
     	}
     }
     
    @@ -748,6 +774,6 @@ print '</div>';
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php
    index 80a4f0db5e8..c5726901e2e 100644
    --- a/htdocs/accountancy/bookkeeping/listbyaccount.php
    +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2013-2016  Olivier Geffroy     <jeff@jeffinfo.com>
      * Copyright (C) 2013-2016  Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2013-2018  Alexandre Spangaro  <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -287,10 +288,10 @@ print '</td>';
     print '<td class="liste_titre"></td>';
     print '<td class="liste_titre" align="center">';
     print $langs->trans('From') . ': ';
    -print $form->select_date($search_date_start, 'search_date_start', 0, 0, 1);
    +print $form->selectDate($search_date_start, 'search_date_start', 0, 0, 1);
     print '<br>';
     print $langs->trans('to') . ': ';
    -print $form->select_date($search_date_end, 'search_date_end', 0, 0, 1);
    +print $form->selectDate($search_date_end, 'search_date_end', 0, 0, 1);
     print '</td>';
     print '<td class="liste_titre"><input type="text" size="7" class="flat" name="search_doc_ref" value="' . dol_escape_htmltag($search_doc_ref) . '"/></td>';
     print '<td class="liste_titre"><input type="text" size="7" class="flat" name="search_label_operation" value="' . dol_escape_htmltag($search_label_operation) . '"/></td>';
    @@ -421,5 +422,6 @@ print '</tr>';
     print "</table>";
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    similarity index 60%
    rename from htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    rename to htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    index 9bf287bf3c9..3fdda686eab 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    @@ -2,8 +2,9 @@
     /* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2005      Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Florian Henry	      <florian.henry@open-concept.pro>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    + * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018 Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018      Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -21,12 +22,11 @@
      */
     
     /**
    - * \file accounting/bookkeeping/thirdparty_lettrage.php
    - * \ingroup Advanced accountancy
    - * \brief Onglet de gestion de parametrages des ventilations
    + * \file        htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    + * \ingroup     accountancy
    + * \brief       Tab to manage customer lettering
      */
     require '../../main.inc.php';
    -
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
    @@ -34,7 +34,7 @@ require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array("compta"));
    +$langs->loadLangs(array("compta","accountancy"));
     
     $action = GETPOST('action', 'aZ09');
     $massaction = GETPOST('massaction', 'alpha');
    @@ -61,11 +61,10 @@ $search_year = GETPOST("search_year", 'int');
     $search_doc_type = GETPOST("search_doc_type", 'alpha');
     $search_doc_ref = GETPOST("search_doc_ref", 'alpha');
     
    -$lettering = GETPOST('lettering');
    +$lettering = GETPOST('lettering', 'alpha');
     if (! empty($lettering)) {
     	$action = $lettering;
     }
    -$toselect = GETPOST('toselect', 'array');
     
     // Did we click on purge search criteria ?
     // All tests are required to be compatible with all browsers
    @@ -79,16 +78,15 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
     $socid = GETPOST("socid", 'int');
     // if ($user->societe_id) $socid=$user->societe_id;
     
    +$lettering = new Lettering($db);
     $object = new Societe($db);
     $object->id = $socid;
     $result = $object->fetch($socid);
    -if ($result < 0) {
    -	setEventMessage($object->error, 'errors');
    +if ($result < 0)
    +{
    +	setEventMessages($object->error, $object->errors, 'errors');
     }
     
    -$form = new Form($db);
    -$BookKeeping = new lettering($db);
    -$formaccounting = new FormAccounting($db);
     
     /*
      * Action
    @@ -96,82 +94,49 @@ $formaccounting = new FormAccounting($db);
     
     if ($action == 'lettering') {
     
    -	$result = $BookKeeping->updateLettrage($toselect);
    +	$result = $lettering->updateLettering($toselect);
     
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    -		$error ++;
    +		setEventMessages('', $lettering->errors, 'errors');
    +		$error++;
     	}
     }
     
     if ($action == 'autolettrage') {
     
    -	$result = $BookKeeping->lettrageTiers($socid);
    +	$result = $lettering->letteringThirdparty($socid);
     
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    -		$error ++;
    +		setEventMessages('', $lettering->errors, 'errors');
    +		$error++;
     	}
     }
     
    -llxHeader('', 'Compta - Grand Livre');
     
    -/*
    - * Affichage onglets
    +	/*
    + * View
      */
    +
    +$form = new Form($db);
    +$formaccounting = new FormAccounting($db);
    +
    +$title=$object->name." - ".$langs->trans('TabLetteringCustomer');
    +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
    +llxHeader('',$title,$help_url);
    +
     $head = societe_prepare_head($object);
     
     dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
     
    -dol_fiche_head($head, 'accounting', $langs->trans("ThirdParty"), 0, 'company');
    +dol_fiche_head($head, 'lettering_customer', $langs->trans("ThirdParty"), 0, 'company');
     
    -print '<table width="100%" class="border">';
    -print '<tr><td width="30%">' . $langs->trans("ThirdPartyName") . '</td><td width="70%" colspan="3">';
    -$object->next_prev_filter = "te.fournisseur = 1";
    -print $form->showrefnav($object, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom', '', '');
    -print '</td></tr>';
    +$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
    -if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
    -{
    -	print '<tr><td>' . $langs->trans('Prefix') . '</td><td colspan="3">' . $object->prefix_comm . '</td></tr>';
    -}
    +dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom');
     
    -print '<tr>';
    -print '<td class="nowrap">' . $langs->trans("CustomerCode") . '</td><td colspan="3">';
    -print $object->code_client;
    -if ($object->check_codeclient() != 0)
    -	print ' <font class="error">(' . $langs->trans("WrongCustomerCode") . ')</font>';
    -print '</td>';
    -print '</tr>';
    +dol_fiche_end();
     
    -print '<tr>';
    -print '<td>';
    -print $form->editfieldkey("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta, $object, $user->rights->societe->creer);
    -print '</td><td colspan="3">';
    -print $form->editfieldval("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta, $object, $user->rights->societe->creer);
    -print '</td>';
    -print '</tr>';
    -
    -// Address
    -print '<tr><td valign="top">' . $langs->trans("Address") . '</td><td colspan="3">';
    -dol_print_address($object->address, 'gmap', 'thirdparty', $object->id);
    -print '</td></tr>';
    -
    -// Zip / Town
    -print '<tr><td class="nowrap">' . $langs->trans("Zip") . ' / ' . $langs->trans("Town") . '</td><td colspan="3">' . $object->zip . (($object->zip && $object->town) ? ' / ' : '') . $object->town . '</td>';
    -print '</tr>';
    -
    -// Country
    -print '<tr><td>' . $langs->trans("Country") . '</td><td colspan="3">';
    -// $img=picto_from_langcode($object->country_code);
    -$img = '';
    -if ($object->isInEEC())
    -	print $form->textwithpicto(($img ? $img . ' ' : '') . $object->country, $langs->trans("CountryIsInEEC"), 1, 0);
    -else
    -	print ($img ? $img . ' ' : '') . $object->country;
    -print '</td></tr>';
    -
    -print '</table>';
    +print '<br>';
     
     $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
     $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
    @@ -208,7 +173,7 @@ while ( $obj = $db->fetch_object($resql) ) {
     
     $sql .= $db->plimit($limit + 1, $offset);
     
    -dol_syslog("/accountancy/bookkeeping/thirdparty_lettrage.php", LOG_DEBUG);
    +dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
     $resql = $db->query($sql);
     if (! $resql) {
     	dol_print_error($db);
    @@ -217,7 +182,7 @@ if (! $resql) {
     
     $num = $db->num_rows($resql);
     
    -dol_syslog("/accountancy/bookkeeping/thirdparty_lettrage.php", LOG_DEBUG);
    +dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
     if ($resql) {
     	$i = 0;
     
    @@ -231,85 +196,76 @@ if ($resql) {
     	print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Labelcompte", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "bk.montant", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Sens", $_SERVER["PHP_SELF"], "bk.sens", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Solde", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
    -	print '<td></td>';
    +	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder);
     	print "</tr>\n";
     
     	print '<tr class="liste_titre">';
     	print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
     	print '<td><input type="text" name="search_year" value="' . $search_year . '"></td>';
     	print '<td><input type="text" name="search_doc_refe" value="' . $search_doc_ref . '"></td>';
    -	print '<td colspan="7">&nbsp;</td>';
    +	print '<td colspan="5">&nbsp;</td>';
     	print '<td align="right">';
     	$searchpicto = $form->showFilterButtons();
     	print $searchpicto;
     	print '</td>';
     	print '</tr>';
     
    -	$var = false;
     	$solde = 0;
     	$tmp = '';
     	while ( $obj = $db->fetch_object($resql) ) {
     
    -		if ($tmp != $obj->lettering_code || empty($tmp))
    -			$tmp = $obj->lettering_code;
    +		if ($tmp != $obj->lettering_code || empty($tmp))						$tmp = $obj->lettering_code;
    +		/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/	$solde += ($obj->credit - $obj->debit);
     
    -		if ($tmp != $obj->lettering_code || empty($obj->lettering_code))
    -			$var = ! $var;
    -
    -		$solde += ($obj->credit - $obj->debit);
    -
    -		print "<tr $bc[$var]>";
    +		print '<tr class="oddeven">';
     
     		if (empty($obj->lettering_code)) {
     			print '<td><a href="' . dol_buildpath('/accountancy/bookkeeping/card.php', 1) . '?piece_num=' . $obj->piece_num . '">';
     			print img_edit();
     			print '</a>&nbsp;' . $obj->doc_type . '</td>' . "\n";
    -		} else
    +		} else {
     			print '<td>' . $obj->doc_type . '</td>' . "\n";
    +		}
     
     		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
     		print '<td>' . $obj->doc_ref . '</td>';
     		print '<td>' . $obj->label_compte . '</td>';
    -		print '<td>' . price($obj->debit) . '</td>';
    -		print '<td>' . price($obj->credit) . '</td>';
    -		print '<td>' . price($obj->montant) . '</td>';
    -		print '<td>' . $obj->sens . '</td>';
    -		print '<td>' . $obj->code_journal . '</td>';
    -		print '<td>' . round($solde, 2) . '</td>';
    +		print '<td align="right">' . price($obj->debit) . '</td>';
    +		print '<td align="right">' . price($obj->credit) . '</td>';
    +		print '<td align="right">' . price(round($solde, 2)) . '</td>';
    +		print '<td align="center">' . $obj->code_journal . '</td>';
     
     		if (empty($obj->lettering_code)) {
     			print '<td class="nowrap" align="center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
     		} else
    -			print '<td>' . $obj->lettering_code . '</td>';
    +			print '<td align="center">' . $obj->lettering_code . '</td>';
     
     		print "</tr>\n";
     	}
     
     	print '<tr class="oddeven">';
    -
    -	print '<td colspan="4">Mouvement totaux</td>' . "\n";
    -	print '<td><strong>' . price($debit) . '</strong></td>';
    -	print '<td><strong>' . price($credit) . '</strong></td>';
    +	print '<td align="right" colspan="4">'.$langs->trans("Total").':</td>' . "\n";
    +	print '<td align="right"><strong>' . price($debit) . '</strong></td>';
    +	print '<td align="right"><strong>' . price($credit) . '</strong></td>';
     	print '<td colspan="5"></td>';
     	print "</tr>\n";
     
    -	print "<tr $bc[$var]>";
    -	print '<td colspan="9">Solde Comptable</td>' . "\n";
    -	print '<td><strong>' . price($credit - $debit) . '</strong></td>';
    -	print '<td colspan="5"></td>';
    +	print '<tr class="oddeven">';
    +	print '<td align="right" colspan="4">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td colspan="2">&nbsp;</td>';
    +	print '<td align="right"><strong>' . price($credit - $debit) . '</strong></td>';
    +	print '<td colspan="3"></td>';
     	print "</tr>\n";
     
     	print "</table>";
     
     	print '<input class="butAction" type="submit" value="lettering" name="lettering" id="lettering">';
    -	print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=autolettrage">' . $langs->trans('AccountancyAutoLettering') . '</a>';
    +	//print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=autolettering">' . $langs->trans('AccountancyAutoLettering') . '</a>';
     	print "</form>";
     	$db->free($resql);
     } else {
    @@ -319,4 +275,3 @@ if ($resql) {
     // End of page
     llxFooter();
     $db->close();
    -
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    similarity index 58%
    rename from htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    rename to htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    index cf278c26903..8cd51847b1e 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    @@ -2,8 +2,9 @@
     /* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2005      Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Florian Henry	      <florian.henry@open-concept.pro>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    + * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018 Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018      Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -21,14 +22,11 @@
      */
     
     /**
    - * \file accounting/bookkeeping/thirdparty_lettrage.php
    - * \ingroup Advanced accountancy
    - * \brief Tab to setup lettering
    + * \file    	htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    + * \ingroup 	Advanced accountancy
    + * \brief 		Tab to setup lettering
      */
    -
    -// Dolibarr environment
     require '../../main.inc.php';
    -
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
    @@ -36,7 +34,7 @@ require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array("compta"));
    +$langs->loadLangs(array("compta","accountancy"));
     
     $action = GETPOST('action', 'aZ09');
     $massaction = GETPOST('massaction', 'alpha');
    @@ -63,11 +61,10 @@ $search_year = GETPOST("search_year",'int');
     $search_doc_type = GETPOST("search_doc_type",'alpha');
     $search_doc_ref = GETPOST("search_doc_ref",'alpha');
     
    -$lettering = GETPOST('lettering');
    +$lettering = GETPOST('lettering', 'alpha');
     if (!empty($lettering)) {
     	$action=$lettering;
     }
    -$toselect = GETPOST('toselect','array');
     
     // Did we click on purge search criteria ?
     // All tests are required to be compatible with all browsers
    @@ -83,111 +80,62 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     $socid = GETPOST("socid", 'int');
     // if ($user->societe_id) $socid=$user->societe_id;
     
    +$lettering = new Lettering($db);
     $object = new Societe($db);
     $object->id = $socid;
     $result = $object->fetch($socid);
    -if ($result<0) {
    -	setEventMessage($object->error,'errors');
    +if ($result<0)
    +{
    +	setEventMessages($object->error, $object->errors, 'errors');
     }
     
    -$form = new Form($db);
    -$BookKeeping = new lettering($db);
    -$formaccounting = new FormAccounting($db);
     
     /*
      * Action
      */
     if ($action == 'lettering') {
     
    -	$result = $BookKeeping->updateLettrage($toselect);
    +	$result = $lettering->updateLettering($toselect);
     
    -	// var_dump($result);
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    -		$error ++;
    +		setEventMessages('', $lettering->errors, 'errors');
    +		$error++;
     	}
     }
     
     if ($action == 'autolettrage') {
     
    -	$result = $BookKeeping->lettrageTiers($socid);
    +	$result = $lettering->letteringThirdparty($socid);
     
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    -		$error ++;
    +		setEventMessages('', $lettering->errors, 'errors');
    +		$error++;
     	}
     }
     
    -$title = 'AccountancyLettrage';
    -
    -llxHeader('', $title);
    -
    -
    -$param='';
    -if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
    -if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
    -if (!empty($search_year)) $param.='&search_year='.$search_year;
    -if (!empty($socid)) $param.='&socid='.$socid;
    -if (!empty($search_doc_type)) $param.='&search_doc_type='.$search_doc_type;
    -if (!empty($search_doc_ref)) $param.='&search_doc_ref='.$search_doc_ref;
    -
     
     /*
    - * Affichage onglets
    + * View
      */
    +
    +$form = new Form($db);
    +$formaccounting = new FormAccounting($db);
    +
    +$title=$object->name." - ".$langs->trans('TabLetteringSupplier');
    +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
    +llxHeader('',$title,$help_url);
    +
     $head = societe_prepare_head($object);
     
     dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
     
    -dol_fiche_head($head, 'accounting_supplier', $langs->trans("ThirdParty"), 0, 'company');
    +dol_fiche_head($head, 'lettering_supplier', $langs->trans("ThirdParty"), 0, 'company');
     
    -print '<table width="100%" class="border">';
    -print '<tr><td width="30%">' . $langs->trans("ThirdPartyName") . '</td><td width="70%" colspan="3">';
    -$object->next_prev_filter = "te.fournisseur = 1";
    -print $form->showrefnav($object, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom', '', '');
    -print '</td></tr>';
    +$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
    -if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
    -{
    -	print '<tr><td>' . $langs->trans('Prefix') . '</td><td colspan="3">' . $object->prefix_comm . '</td></tr>';
    -}
    +dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom');
     
    -print '<tr>';
    -print '<td class="nowrap">' . $langs->trans("SupplierCode") . '</td><td colspan="3">';
    -print $object->code_fournisseur;
    -if ($object->check_codefournisseur() != 0)
    -	print ' <font class="error">(' . $langs->trans("WrongSupplierCode") . ')</font>';
    -print '</td>';
    -print '</tr>';
    -
    -print '<tr>';
    -print '<td>';
    -print $form->editfieldkey("SupplierAccountancyCode", 'supplieraccountancycode', $object->code_compta_fournisseur, $object, $user->rights->societe->creer);
    -print '</td><td colspan="3">';
    -print $form->editfieldval("SupplierAccountancyCode", 'supplieraccountancycode', $object->code_compta_fournisseur, $object, $user->rights->societe->creer);
    -print '</td>';
    -print '</tr>';
    -
    -// Address
    -print '<tr><td valign="top">' . $langs->trans("Address") . '</td><td colspan="3">';
    -dol_print_address($object->address, 'gmap', 'thirdparty', $object->id);
    -print '</td></tr>';
    -
    -// Zip / Town
    -print '<tr><td class="nowrap">' . $langs->trans("Zip") . ' / ' . $langs->trans("Town") . '</td><td colspan="3">' . $object->zip . (($object->zip && $object->town) ? ' / ' : '') . $object->town . '</td>';
    -print '</tr>';
    -
    -// Country
    -print '<tr><td>' . $langs->trans("Country") . '</td><td colspan="3">';
    -// $img=picto_from_langcode($object->country_code);
    -$img = '';
    -if ($object->isInEEC())
    -	print $form->textwithpicto(($img ? $img . ' ' : '') . $object->country, $langs->trans("CountryIsInEEC"), 1, 0);
    -else
    -	print ($img ? $img . ' ' : '') . $object->country;
    -print '</td></tr>';
    -
    -print '</table>';
    +dol_fiche_end();
     
     $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
     $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
    @@ -251,85 +199,76 @@ if ($resql) {
     	print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Labelcompte", $_SERVER["PHP_SELF"], "bk.label_compte","",$param,"",$sortfield,$sortorder);
    +	print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "bk.montant","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Sens", $_SERVER["PHP_SELF"], "bk.sens","",$param,"",$sortfield,$sortorder);
    +	print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Solde", $_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder);
    -	print '<td></td>';
    +	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder);
     	print "</tr>\n";
     
     	print '<tr class="liste_titre">';
     	print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
     	print '<td><input type="text" name="search_year" value="' . $search_year . '"></td>';
     	print '<td><input type="text" name="search_doc_refe" value="' . $search_doc_ref . '"></td>';
    -	print '<td colspan="7">&nbsp;</td>';
    +	print '<td colspan="6">&nbsp;</td>';
     	print '<td align="right">';
     	$searchpicto=$form->showFilterButtons();
     	print $searchpicto;
     	print '</td>';
     	print '</tr>';
     
    -	$var = false;
     	$solde = 0;
     	$tmp = '';
     	while ($obj = $db->fetch_object($resql)) {
     
    -		if ($tmp != $obj->lettering_code || empty($tmp))
    -			$tmp = $obj->lettering_code;
    +		if ($tmp != $obj->lettering_code || empty($tmp))						$tmp = $obj->lettering_code;
    +		/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/	$solde += ($obj->credit - $obj->debit);
     
    -			if ($tmp != $obj->lettering_code || empty($obj->lettering_code))
    -			$var = ! $var;
    -
    -		$solde += ($obj->credit - $obj->debit);
    -
    -		print "<tr $bc[$var]>";
    +		print '<tr class="oddeven">';
     
     		if (empty($obj->lettering_code)) {
     			print '<td><a href="' . dol_buildpath('/accountancy/bookkeeping/card.php', 1) . '?piece_num=' . $obj->piece_num . '">';
     			print img_edit();
     			print '</a>&nbsp;' . $obj->doc_type . '</td>' . "\n";
    -		} else
    +		} else {
     			print '<td>' . $obj->doc_type . '</td>' . "\n";
    +		}
     
     		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
     		print '<td>' . $obj->doc_ref . '</td>';
     		print '<td>' . $obj->label_compte . '</td>';
    -		print '<td>' . price($obj->debit) . '</td>';
    -		print '<td>' . price($obj->credit) . '</td>';
    -		print '<td>' . price($obj->montant) . '</td>';
    -		print '<td>' . $obj->sens . '</td>';
    -		print '<td>' . $obj->code_journal . '</td>';
    -		print '<td>' . round($solde, 2) . '</td>';
    +		print '<td align="right">' . price($obj->debit) . '</td>';
    +		print '<td align="right">' . price($obj->credit) . '</td>';
    +		print '<td align="right">' . price(round($solde, 2)) . '</td>';
    +		print '<td align="center">' . $obj->code_journal . '</td>';
     
     		if (empty($obj->lettering_code)) {
     			print '<td class="nowrap" align="center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
     		} else
    -			print '<td>' . $obj->lettering_code . '</td>';
    +			print '<td align="center">' . $obj->lettering_code . '</td>';
     
     		print "</tr>\n";
     	}
     
     	print '<tr class="oddeven">';
    -
    -	print '<td colspan="4">Mouvement totaux</td>' . "\n";
    -	print '<td><strong>' . price($debit) . '</strong></td>';
    -	print '<td><strong>' . price($credit) . '</strong></td>';
    +	print '<td align="right" colspan="4">'.$langs->trans("Total").':</td>' . "\n";
    +	print '<td align="right"><strong>' . price($debit) . '</strong></td>';
    +	print '<td align="right"><strong>' . price($credit) . '</strong></td>';
     	print '<td colspan="5"></td>';
     	print "</tr>\n";
     
    -	print "<tr $bc[$var]>";
    -	print '<td colspan="9">Solde Comptable</td>' . "\n";
    -	print '<td><strong>' . price($credit - $debit) . '</strong></td>';
    -	print '<td colspan="5"></td>';
    +	print '<tr class="oddeven">';
    +	print '<td align="right" colspan="4">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td colspan="2">&nbsp;</td>';
    +	print '<td align="right"><strong>' . price($credit - $debit) . '</strong></td>';
    +	print '<td colspan="3"></td>';
     	print "</tr>\n";
     
     	print "</table>";
     
    -	print '<input class="butAction" type="submit" value="lettering" name="lettering" id="lettering">';
    -	print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
    +	print '<input class="butAction" type="submit" value="' . $langs->trans('AccountancyLettering') . '" name="lettering" id="lettering">';
    +	//print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
     	print "</form>";
     	$db->free($resql);
     } else {
    diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php
    index 9554a79c858..e2a7b14033c 100644
    --- a/htdocs/accountancy/class/accountancycategory.class.php
    +++ b/htdocs/accountancy/class/accountancycategory.class.php
    @@ -29,27 +29,97 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
     /**
      * Class to manage categories of an accounting account
      */
    -class AccountancyCategory 	// extends CommonObject
    +class AccountancyCategory // extends CommonObject
     {
    -	public $db;							//!< To store db handler
    -	public $error;							//!< To return error code (or message)
    -	public $errors=array();				//!< To return several error codes (or messages)
    -	public $element='c_accounting_category';			//!< Id that identify managed objects
    -	public $table_element='c_accounting_category';	//!< Name of table without prefix where object is stored
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	public $id;
    +	/**
    +	 * @var string 		Error string
    +	 * @see             errors
    +	 */
    +	public $error;
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='c_accounting_category';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='c_accounting_category';
    +
    +	/**
    +     * @var int ID
    +     */
    +    public $id;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $code;
    -	public $label;
    +
    +	/**
    +     * @var string Accountancy Category label
    +     */
    +    public $label;
    +
    +    /**
    +	 * @var mixed Sample property 1
    +	 */
     	public $range_account;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $sens;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $category_type;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $formula;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $position;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $fk_country;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $active;
     
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $lines_cptbk;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $lines_display;
    +
    +	/**
    +	 * @var mixed Sample property 1
    +	 */
     	public $sdc;
     
     
    @@ -126,18 +196,18 @@ class AccountancyCategory 	// extends CommonObject
     		{
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."c_accounting_category");
     
    -			if (! $notrigger)
    -			{
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action call a trigger.
    +			// Uncomment this and change MYOBJECT to your own tag if you
    +			// want this action call a trigger.
    +			//if (! $notrigger)
    +			//{
     
    -				//// Call triggers
    -				//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -				//$interface=new Interfaces($this->db);
    -				//$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
    -				//if ($result < 0) { $error++; $this->errors=$interface->errors; }
    -				//// End call triggers
    -			}
    +			//	// Call triggers
    +			//	include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    +			//	$interface=new Interfaces($this->db);
    +			//	$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
    +			//	if ($result < 0) { $error++; $this->errors=$interface->errors; }
    +			//	// End call triggers
    +			//}
     		}
     
     		// Commit or rollback
    @@ -265,18 +335,17 @@ class AccountancyCategory 	// extends CommonObject
     
     		if (! $error)
     		{
    -			if (! $notrigger)
    -			{
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action call a trigger.
    -
    -				//// Call triggers
    -				//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -				//$interface=new Interfaces($this->db);
    -				//$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
    -				//if ($result < 0) { $error++; $this->errors=$interface->errors; }
    -				//// End call triggers
    -			}
    +			// Uncomment this and change MYOBJECT to your own tag if you
    +			// want this action call a trigger.
    +			//if (! $notrigger)
    +			//{
    +			//	// Call triggers
    +			//	include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    +			//	$interface=new Interfaces($this->db);
    +			//	$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
    +			//	if ($result < 0) { $error++; $this->errors=$interface->errors; }
    +			//	// End call triggers
    +			//}
     		}
     
     		// Commit or rollback
    @@ -321,18 +390,17 @@ class AccountancyCategory 	// extends CommonObject
     
     		if (! $error)
     		{
    -			if (! $notrigger)
    -			{
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action call a trigger.
    -
    -				//// Call triggers
    -				//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -				//$interface=new Interfaces($this->db);
    -				//$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
    -				//if ($result < 0) { $error++; $this->errors=$interface->errors; }
    -				//// End call triggers
    -			}
    +			// Uncomment this and change MYOBJECT to your own tag if you
    +			// want this action call a trigger.
    +			//if (! $notrigger)
    +			//{
    +			//	// Call triggers
    +			//	include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    +			//	$interface=new Interfaces($this->db);
    +			//	$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
    +			//	if ($result < 0) { $error++; $this->errors=$interface->errors; }
    +			//	// End call triggers
    +			//}
     		}
     
     		// Commit or rollback
    @@ -360,7 +428,8 @@ class AccountancyCategory 	// extends CommonObject
     	 * @param int $id Id
     	 * @return int <0 if KO, 0 if not found, >0 if OK
     	 */
    -	public function display($id) {
    +    public function display($id)
    +    {
     		global $conf;
     		$sql = "SELECT t.rowid, t.account_number, t.label";
     		$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as t";
    @@ -395,7 +464,8 @@ class AccountancyCategory 	// extends CommonObject
     	 *
     	 * @return int <0 if KO, 0 if not found, >0 if OK
     	 */
    -	public function getCptBK($id) {
    +    public function getCptBK($id)
    +    {
     		global $conf;
     
     		$sql = "SELECT t.numero_compte, t.label_operation, t.doc_ref";
    @@ -443,8 +513,9 @@ class AccountancyCategory 	// extends CommonObject
     	 *
     	 * @return int <0 if KO, 0 if not found, >0 if OK
     	 */
    -	public function getAccountsWithNoCategory($id) {
    -	    global $conf;
    +    public function getAccountsWithNoCategory($id)
    +    {
    +        global $conf;
     
     	    $sql = "SELECT aa.account_number as numero_compte, aa.label as label_compte";
     	    $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
    @@ -486,7 +557,8 @@ class AccountancyCategory 	// extends CommonObject
     	 *
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	public function updateAccAcc($id_cat, $cpts = array()) {
    +    public function updateAccAcc($id_cat, $cpts = array())
    +    {
     		global $conf;
     		$error = 0;
     
    @@ -549,7 +621,8 @@ class AccountancyCategory 	// extends CommonObject
     	 *
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	public function deleteCptCat($cpt_id) {
    +    public function deleteCptCat($cpt_id)
    +    {
     		$error = 0;
     
     		$sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account as aa";
    @@ -800,5 +873,4 @@ class AccountancyCategory 	// extends CommonObject
     			return -1;
     		}
     	}
    -
     }
    diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php
    index 52b5f1c411f..7b832976e89 100644
    --- a/htdocs/accountancy/class/accountancyexport.class.php
    +++ b/htdocs/accountancy/class/accountancyexport.class.php
    @@ -44,7 +44,8 @@ class AccountancyExport
     	/**
     	 * @var Type of export. Defined by $conf->global->ACCOUNTING_EXPORT_MODELCSV
     	 */
    -	public static $EXPORT_TYPE_NORMAL = 1;	 // Classic CSV
    +	public static $EXPORT_TYPE_NORMAL = 1;	 			// CSV
    +	public static $EXPORT_TYPE_CONFIGURABLE = 10;		// CSV
     	public static $EXPORT_TYPE_CEGID = 2;
     	public static $EXPORT_TYPE_COALA = 3;
     	public static $EXPORT_TYPE_BOB50 = 4;
    @@ -53,13 +54,13 @@ class AccountancyExport
     	public static $EXPORT_TYPE_EBP = 7;
     	public static $EXPORT_TYPE_COGILOG = 8;
     	public static $EXPORT_TYPE_AGIRIS = 9;
    -	public static $EXPORT_TYPE_CONFIGURABLE = 10;
    +	public static $EXPORT_TYPE_FEC = 11;
    +
     
     	/**
    -	 *
     	 * @var string[] Error codes (or messages)
     	 */
    -	public $errors = array ();
    +	public $errors = array();
     
     	/**
     	 *
    @@ -78,7 +79,8 @@ class AccountancyExport
     	 *
     	 * @param DoliDb $db Database handler
     	 */
    -	public function __construct(DoliDB &$db) {
    +	public function __construct(DoliDB &$db)
    +	{
     		global $conf;
     
     		$this->db = &$db;
    @@ -91,11 +93,13 @@ class AccountancyExport
     	 *
     	 * @return array of type
     	 */
    -	public static function getType() {
    +	public static function getType()
    +	{
     		global $langs;
     
     		return array (
    -				self::$EXPORT_TYPE_NORMAL => $langs->trans('Modelcsv_normal'),
    +				//self::$EXPORT_TYPE_NORMAL => $langs->trans('Modelcsv_normal'),
    +				self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'),
     				self::$EXPORT_TYPE_CEGID => $langs->trans('Modelcsv_CEGID'),
     				self::$EXPORT_TYPE_COALA => $langs->trans('Modelcsv_COALA'),
     				self::$EXPORT_TYPE_BOB50 => $langs->trans('Modelcsv_bob50'),
    @@ -104,27 +108,53 @@ class AccountancyExport
     				self::$EXPORT_TYPE_EBP => $langs->trans('Modelcsv_ebp'),
     				self::$EXPORT_TYPE_COGILOG => $langs->trans('Modelcsv_cogilog'),
     				self::$EXPORT_TYPE_AGIRIS => $langs->trans('Modelcsv_agiris'),
    -				self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'),
    +				self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'),
     			);
     	}
     
    +	/**
    +	 * Return string to summarize the format (Used to generated export filename)
    +	 *
    +	 * @param	int		$type		Format id
    +	 * @return 	string				Format code
    +	 */
    +	private static function getFormatCode($type)
    +	{
    +		$formatcode = array (
    +			//self::$EXPORT_TYPE_NORMAL => 'csv',
    +			self::$EXPORT_TYPE_CONFIGURABLE => 'csv',
    +			self::$EXPORT_TYPE_CEGID => 'cegid',
    +			self::$EXPORT_TYPE_COALA => 'coala',
    +			self::$EXPORT_TYPE_BOB50 => 'bob50',
    +			self::$EXPORT_TYPE_CIEL => 'ciel',
    +			self::$EXPORT_TYPE_QUADRATUS => 'quadratus',
    +			self::$EXPORT_TYPE_EBP => 'ebp',
    +			self::$EXPORT_TYPE_COGILOG => 'cogilog',
    +			self::$EXPORT_TYPE_AGIRIS => 'agiris',
    +			self::$EXPORT_TYPE_FEC => 'fec',
    +		);
    +
    +		return $formatcode[$type];
    +	}
    +
     	/**
     	 * Array with all export type available (key + label) and parameters for config
     	 *
     	 * @return array of type
     	 */
    -	public static function getTypeConfig() {
    +	public static function getTypeConfig()
    +	{
     		global $conf, $langs;
     
     		return array (
     			'param' => array(
    -				self::$EXPORT_TYPE_NORMAL => array(
    +				/*self::$EXPORT_TYPE_NORMAL => array(
     					'label' => $langs->trans('Modelcsv_normal'),
     					'ACCOUNTING_EXPORT_FORMAT' => empty($conf->global->ACCOUNTING_EXPORT_FORMAT)?'txt':$conf->global->ACCOUNTING_EXPORT_FORMAT,
     					'ACCOUNTING_EXPORT_SEPARATORCSV' => empty($conf->global->ACCOUNTING_EXPORT_SEPARATORCSV)?',':$conf->global->ACCOUNTING_EXPORT_SEPARATORCSV,
     					'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE,
     					'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE,
    -				),
    +				),*/
     				self::$EXPORT_TYPE_CEGID => array(
     					'label' => $langs->trans('Modelcsv_CEGID'),
     				),
    @@ -158,6 +188,10 @@ class AccountancyExport
     					'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE,
     					'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE,
     				),
    +				self::$EXPORT_TYPE_FEC => array(
    +					'label' => $langs->trans('Modelcsv_FEC'),
    +					'ACCOUNTING_EXPORT_FORMAT' => 'txt',
    +				),
     			),
     			'cr'=> array (
     				'1' => $langs->trans("Unix"),
    @@ -170,31 +204,30 @@ class AccountancyExport
     		);
     	}
     
    +
     	/**
    -	 * Download the export
    +	 * Function who chose which export to use with the default config, and make the export into a file
     	 *
    +	 * @param array		$TData 		data
     	 * @return void
     	 */
    -	public static function downloadFile() {
    -		global $conf;
    -		$filename = 'general_ledger';
    -		include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
    -	}
    -
    -	/**
    -	 * Function who chose which export to use with the default config
    -	 *
    -	 * @param unknown $TData data
    -	 */
    -	public function export(&$TData) {
    +	public function export(&$TData)
    +	{
     		global $conf, $langs;
    +		global $search_date_end;	// Used into /accountancy/tpl/export_journal.tpl.php
    +
    +		// Define name of file to save
    +		$filename = 'general_ledger-'.$this->getFormatCode($conf->global->ACCOUNTING_EXPORT_MODELCSV);
    +
    +		include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
     
    -		self::downloadFile();
     
     		switch ($conf->global->ACCOUNTING_EXPORT_MODELCSV) {
     			case self::$EXPORT_TYPE_NORMAL :
    -				$this->exportNormal($TData);
    +			case self::$EXPORT_TYPE_CONFIGURABLE :
    +				$this->exportConfigurable($TData);
     				break;
    +			case self::$EXPORT_TYPE_NORMAL :
     			case self::$EXPORT_TYPE_CEGID :
     				$this->exportCegid($TData);
     				break;
    @@ -219,8 +252,8 @@ class AccountancyExport
     			case self::$EXPORT_TYPE_AGIRIS :
     				$this->exportAgiris($TData);
     				break;
    -			case self::$EXPORT_TYPE_CONFIGURABLE :
    -				$this->exportConfigurable($TData);
    +			case self::$EXPORT_TYPE_FEC :
    +				$this->exportFEC($TData);
     				break;
     			default:
     				$this->errors[] = $langs->trans('accountancy_error_modelnotfound');
    @@ -228,29 +261,6 @@ class AccountancyExport
     		}
     	}
     
    -	/**
    -	 * Export format : Normal
    -	 *
    -	 * @param array $objectLines data
    -	 *
    -	 * @return void
    -	 */
    -	public function exportNormal($objectLines) {
    -		global $conf;
    -
    -		foreach ( $objectLines as $line ) {
    -			// Std export
    -			$date = dol_print_date($line->doc_date, $conf->global->ACCOUNTING_EXPORT_DATE);
    -			print $date . $this->separator;
    -			print $line->doc_ref . $this->separator;
    -			print length_accountg($line->numero_compte) . $this->separator;
    -			print length_accounta($line->subledger_account) . $this->separator;
    -			print price($line->debit) . $this->separator;
    -			print price($line->credit) . $this->separator;
    -			print $line->code_journal . $this->separator;
    -			print $this->end_line;
    -		}
    -	}
     
     	/**
     	 * Export format : CEGID
    @@ -259,7 +269,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportCegid($objectLines) {
    +	public function exportCegid($objectLines)
    +	{
     		foreach ( $objectLines as $line ) {
     			$date = dol_print_date($line->doc_date, '%d%m%Y');
     			$separator = ";";
    @@ -284,7 +295,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportCogilog($objectLines) {
    +	public function exportCogilog($objectLines)
    +	{
     		foreach ( $objectLines as $line ) {
     			$date = dol_print_date($line->doc_date, '%d%m%Y');
     			$separator = ";";
    @@ -317,7 +329,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportCoala($objectLines) {
    +	public function exportCoala($objectLines)
    +	{
     		// Coala export
     		$separator = ";";
     		$end_line = "\n";
    @@ -344,7 +357,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportBob50($objectLines) {
    +	public function exportBob50($objectLines)
    +	{
     
     		// Bob50
     		$separator = ";";
    @@ -382,7 +396,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportCiel(&$TData) {
    +	public function exportCiel(&$TData)
    +	{
     		global $conf;
     
     		$end_line ="\r\n";
    @@ -422,12 +437,13 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportQuadratus(&$TData) {
    +	public function exportQuadratus(&$TData)
    +	{
     		global $conf;
     
     		$end_line ="\r\n";
     
    -        //We should use dol_now function not time however this is wrong date to transfert in accounting
    +		//We should use dol_now function not time however this is wrong date to transfert in accounting
     		//$date_ecriture = dol_print_date(dol_now(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be ddmmyy
     		//$date_ecriture = dol_print_date(time(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be ddmmyy
     		foreach ( $TData as $data ) {
    @@ -441,8 +457,8 @@ class AccountancyExport
     			$Tab['code_journal'] = str_pad(self::trunc($data->code_journal, 2), 2);
     			$Tab['folio'] = '000';
     
    -            //We use invoice date $data->doc_date not $date_ecriture which is the transfert date
    -            //maybe we should set an option for customer who prefer to keep in accounting software the tranfert date instead of invoice date ?
    +			//We use invoice date $data->doc_date not $date_ecriture which is the transfert date
    +			//maybe we should set an option for customer who prefer to keep in accounting software the tranfert date instead of invoice date ?
     			//$Tab['date_ecriture'] = $date_ecriture;
     			$Tab['date_ecriture'] = dol_print_date($data->doc_date, '%d%m%y');
     			$Tab['filler'] = ' ';
    @@ -450,25 +466,25 @@ class AccountancyExport
     			$Tab['sens'] = $data->sens; // C or D
     			$Tab['signe_montant'] = '+';
     
    -            //elarifr le montant doit etre en centimes sans point decimal !
    +			//elarifr le montant doit etre en centimes sans point decimal !
     			$Tab['montant'] = str_pad(abs($data->montant*100), 12, '0', STR_PAD_LEFT); // TODO manage negative amount
    -		    // $Tab['montant'] = str_pad(abs($data->montant), 12, '0', STR_PAD_LEFT); // TODO manage negative amount
    +			// $Tab['montant'] = str_pad(abs($data->montant), 12, '0', STR_PAD_LEFT); // TODO manage negative amount
     			$Tab['contrepartie'] = str_repeat(' ', 8);
     
    -            // elarifr:  date format must be fixed format : 6 char ddmmyy = %d%m%yand not defined by user / dolibarr setting
    +			// elarifr:  date format must be fixed format : 6 char ddmmyy = %d%m%yand not defined by user / dolibarr setting
     			if (! empty($data->date_echeance))
     				//$Tab['date_echeance'] = dol_print_date($data->date_echeance, $conf->global->ACCOUNTING_EXPORT_DATE);
    -				$Tab['date_echeance'] = dol_print_date($data->date_echeance,  '%d%m%y' );     // elarifr:  format must be ddmmyy
    +				$Tab['date_echeance'] = dol_print_date($data->date_echeance,  '%d%m%y' );	 // elarifr:  format must be ddmmyy
     			else
     				$Tab['date_echeance'] = '000000';
     
    -            //elarifr please keep quadra named field lettrage(2) + codestat(3) instead of fake lettrage(5)
    +			//elarifr please keep quadra named field lettrage(2) + codestat(3) instead of fake lettrage(5)
     			//$Tab['lettrage'] = str_repeat(' ', 5);
     			$Tab['lettrage'] = str_repeat(' ', 2);
     			$Tab['codestat'] = str_repeat(' ', 3);
     			$Tab['num_piece'] = str_pad(self::trunc($data->piece_num, 5), 5);
     
    -            //elarifr keep correct quadra named field instead of anon filler
    +			//elarifr keep correct quadra named field instead of anon filler
     			//$Tab['filler2'] = str_repeat(' ', 20);
     			$Tab['affaire'] = str_repeat(' ', 10);
     			$Tab['quantity1'] = str_repeat(' ', 10);
    @@ -477,16 +493,16 @@ class AccountancyExport
     			$Tab['code_journal2'] = str_pad(self::trunc($data->code_journal, 3), 3);
     			$Tab['filler3'] = str_repeat(' ', 3);
     
    -            //elarifr 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
    +			//elarifr 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
     			//$Tab['libelle_ecriture2'] = str_pad(self::trunc(dol_string_unaccent($data->doc_ref) . ' ' . dol_string_unaccent($data->label_operation), 30), 30);
     			$Tab['libelle_ecriture2'] = str_pad(self::trunc(dol_string_unaccent($data->label_operation), 30), 30);
     			$Tab['codetva'] = str_repeat(' ', 2);
     
    -            //elarifr we need to keep the 10 lastest number of invoice doc_ref not the beginning part that is the unusefull almost same part
    +			//elarifr we need to keep the 10 lastest number of invoice doc_ref not the beginning part that is the unusefull almost same part
     			//$Tab['num_piece3'] = str_pad(self::trunc($data->piece_num, 10), 10);
     			$Tab['num_piece3'] = substr(self::trunc($data->doc_ref, 20), -10);
     			$Tab['filler4'] = str_repeat(' ', 73);
    @@ -505,7 +521,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportEbp($objectLines) {
    +	public function exportEbp($objectLines)
    +	{
     
     		$separator = ',';
     		$end_line = "\n";
    @@ -537,7 +554,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportAgiris($objectLines) {
    +	public function exportAgiris($objectLines)
    +	{
     
     		$separator = ';';
     		$end_line = "\n";
    @@ -574,7 +592,8 @@ class AccountancyExport
     	 *
     	 * @return void
     	 */
    -	public function exportConfigurable($objectLines) {
    +	public function exportConfigurable($objectLines)
    +	{
     		global $conf;
     
     		foreach ($objectLines as $line) {
    @@ -585,25 +604,121 @@ class AccountancyExport
     			$tab[] = $date;
     			$tab[] = $line->doc_ref;
     			$tab[] = $line->label_operation;
    -			$tab[] =  length_accountg($line->numero_compte);
    -			$tab[] =  length_accounta($line->subledger_account);
    -			$tab[] =  price($line->debit);
    -			$tab[] =  price($line->credit);
    -			$tab[] =  price($line->montant);
    -			$tab[] =  $line->code_journal;
    +			$tab[] = length_accountg($line->numero_compte);
    +			$tab[] = length_accounta($line->subledger_account);
    +			$tab[] = price($line->debit);
    +			$tab[] = price($line->credit);
    +			$tab[] = price($line->montant);
    +			$tab[] = $line->code_journal;
     
     			$separator = $this->separator;
     			print implode($separator, $tab) . $this->end_line;
     		}
     	}
     
    +	/**
    +	 * Export format : FEC
    +	 *
    +	 * @param array $objectLines data
    +	 *
    +	 * @return void
    +	 */
    +	public function exportFEC($objectLines)
    +	{
    +		$separator = "\t";
    +		$end_line = "\n";
    +
    +		print "JournalCode" . $separator;
    +		print "JournalLib" . $separator;
    +		print "EcritureNum" . $separator;
    +		print "EcritureDate" . $separator;
    +		print "CompteNum" . $separator;
    +		print "CompteLib" . $separator;
    +		print "CompAuxNum" . $separator;
    +		print "CompAuxLib" . $separator;
    +		print "PieceRef" . $separator;
    +		print "PieceDate" . $separator;
    +		print "EcritureLib" . $separator;
    +		print "Debit" . $separator;
    +		print "Credit" . $separator;
    +		print "EcritureLet" . $separator;
    +		print "DateLet" . $separator;
    +		print "ValidDate" . $separator;
    +		print "Montantdevise" . $separator;
    +		print "Idevise";
    +		print $end_line;
    +
    +		foreach ( $objectLines as $line ) {
    +			$date_creation = dol_print_date($line->date_creation, '%d%m%Y');
    +			$date_doc = dol_print_date($line->doc_date, '%d%m%Y');
    +			$date_valid = dol_print_date($line->date_validated, '%d%m%Y');
    +
    +			// FEC:JournalCode
    +			print $line->code_journal . $separator;
    +
    +			// FEC:JournalLib
    +			print $line->journal_label . $separator;
    +
    +			// FEC:EcritureNum
    +			print $line->piece_num . $separator;
    +
    +			// FEC:EcritureDate
    +			print $date_creation . $separator;
    +
    +			// FEC:CompteNum
    +			print $line->numero_compte . $separator;
    +
    +			// FEC:CompteLib
    +			print $line->label_compte . $separator;
    +
    +			// FEC:CompAuxNum
    +			print $line->subledger_account . $separator;
    +
    +			// FEC:CompAuxLib
    +			print $line->subledger_label . $separator;
    +
    +			// FEC:PieceRef
    +			print $line->doc_ref . $separator;
    +
    +			// FEC:PieceDate
    +			print $date_doc . $separator;
    +
    +			// FEC:EcritureLib
    +			print $line->label_operation . $separator;
    +
    +			// FEC:Debit
    +			print price2num($line->debit) . $separator;
    +
    +			// FEC:Credit
    +			print price2num($line->credit) . $separator;
    +
    +			// FEC:EcritureLet
    +			print $line->lettering_code . $separator;
    +
    +			// FEC:DateLet
    +			print $line->date_lettering . $separator;
    +
    +			// FEC:ValidDate
    +			print $date_valid . $separator;
    +
    +			// FEC:Montantdevise
    +			print $line->multicurrency_amount . $separator;
    +
    +			// FEC:Idevise
    +			print $line->multicurrency_code;
    +
    +			print $end_line;
    +		}
    +	}
     
     	/**
     	 *
    -	 * @param unknown $str data
    -	 * @param integer $size data
    +	 * @param string	$str 	data
    +	 * @param integer 	$size 	data
    +	 * @return string
     	 */
    -	public static function trunc($str, $size) {
    +	public static function trunc($str, $size)
    +	{
     		return dol_trunc($str, $size, 'right', 'UTF-8', 1);
     	}
     }
    diff --git a/htdocs/accountancy/class/accountancysystem.class.php b/htdocs/accountancy/class/accountancysystem.class.php
    index f14a3e7f761..b70fa7238bb 100644
    --- a/htdocs/accountancy/class/accountancysystem.class.php
    +++ b/htdocs/accountancy/class/accountancysystem.class.php
    @@ -28,22 +28,44 @@
      */
     class AccountancySystem
     {
    -	var $db;
    -	var $error;
    -	var $rowid;
    -	var $fk_pcg_version;
    -	var $pcg_type;
    -	var $pcg_subtype;
    -	var $label;
    -	var $account_number;
    -	var $account_parent;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $rowid;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_pcg_version;
    +
    +	public $pcg_type;
    +	public $pcg_subtype;
    +
    +    /**
    +     * @var string Accountancy System label
    +     */
    +    public $label;
    +
    +	public $account_number;
    +	public $account_parent;
     
     	/**
     	 * Constructor
     	 *
     	 * @param DoliDB $db handler
     	 */
    -	function __construct($db) {
    +    function __construct($db)
    +    {
     		$this->db = $db;
     	}
     
    @@ -102,7 +124,8 @@ class AccountancySystem
     	 * @param User $user making insert
     	 * @return int if KO, Id of line if OK
     	 */
    -	function create($user) {
    +    function create($user)
    +    {
     		$now = dol_now();
     
     		$sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_system";
    @@ -130,4 +153,4 @@ class AccountancySystem
     
     		return $result;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php
    index 257c2af0111..85f9ee39c61 100644
    --- a/htdocs/accountancy/class/accountingaccount.class.php
    +++ b/htdocs/accountancy/class/accountingaccount.class.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2013-2014  Florian Henry        <florian.henry@open-concept.pro>
      * Copyright (C) 2014       Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2015       Ari Elbaz (elarifr)  <github@accedinfo.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,8 +31,19 @@
      */
     class AccountingAccount extends CommonObject
     {
    +	/**
    +	 * @var string Name of element
    +	 */
     	public $element='accounting_account';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='accounting_account';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'billr';
     
     	/**
    @@ -39,37 +51,95 @@ class AccountingAccount extends CommonObject
     	 * @var int
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
     	 * @var integer
     	 */
     	public $restrictiononfksoc = 1;
     
    -	var $db;
    -	var $error;
    -	var $errors;
    -	var $id;
    -	var $rowid;
    -	var $datec; // Creation date
    -	var $fk_pcg_version;
    -	var $pcg_type;
    -	var $pcg_subtype;
    -	var $account_number;
    -	var $account_parent;
    -	var $account_category;
    -	var $label;
    -	var $fk_user_author;
    -	var $fk_user_modif;
    -	var $active;       // duplicate with status
    -	var $status;
    +	/**
    +	 * @var DoliDB Database handler.
    +	 */
    +	public $db;
     
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $rowid;
    +
    +	/**
    +     * @var string Creation date
    +     */
    +	public $datec;
    +
    +	/**
    +     * @var string pcg version
    +     */
    +	public $fk_pcg_version;
    +
    +    /**
    +     * @var string pcg type
    +     */
    +	public $pcg_type;
    +
    +    /**
    +     * @var string pcg subtype
    +     */
    +	public $pcg_subtype;
    +
    +    /**
    +     * @var string account number
    +     */
    +	public $account_number;
    +
    +    /**
    +     * @var int ID parent account
    +     */
    +	public $account_parent;
    +
    +    /**
    +     * @var int ID category account
    +     */
    +	public $account_category;
    +
    +	/**
    +	 * @var int Status
    +	 */
    +	public $status;
    +
    +    /**
    +     * @var string Label of account
    +     */
    +    public $label;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_user_author;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_user_modif;
    +
    +	/**
    +	 * @var int active (duplicate with status)
    +	 */
    +    public $active;
     
     	/**
     	 * Constructor
     	 *
     	 * @param DoliDB $db Database handle
     	 */
    -	function __construct($db) {
    +    function __construct($db)
    +    {
     		global $conf;
     
     		$this->db = $db;
    @@ -146,7 +216,8 @@ class AccountingAccount extends CommonObject
     	 * @param int $notrigger Disable triggers
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function create($user, $notrigger = 0) {
    +    function create($user, $notrigger = 0)
    +    {
     		global $conf;
     		$error = 0;
     		$now = dol_now();
    @@ -297,7 +368,8 @@ class AccountingAccount extends CommonObject
     	 *
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function checkUsage() {
    +    function checkUsage()
    +    {
     		global $langs;
     
     		$sql = "(SELECT fk_code_ventilation FROM " . MAIN_DB_PREFIX . "facturedet";
    @@ -330,7 +402,8 @@ class AccountingAccount extends CommonObject
     	 * @param int $notrigger 0=triggers after, 1=disable triggers
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function delete($user, $notrigger = 0) {
    +    function delete($user, $notrigger = 0)
    +    {
     		$error = 0;
     
     		$result = $this->checkUsage();
    @@ -391,7 +464,7 @@ class AccountingAccount extends CommonObject
     	 * @param	string  $moretitle					Add more text to title tooltip
     	 * @param	int  	$notooltip					1=Disable tooltip
          * @param	int     $save_lastsearch_value		-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
    -	 * @return	string	String with URL
    +	 * @return  string	String with URL
     	 */
     	function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle='',$notooltip=0, $save_lastsearch_value=-1)
     	{
    @@ -457,7 +530,8 @@ class AccountingAccount extends CommonObject
     	 * @param int $id of record
     	 * @return void
     	 */
    -	function info($id) {
    +    function info($id)
    +    {
     		$sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms';
     		$sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a';
     		$sql .= ' WHERE a.rowid = ' . $id;
    @@ -488,13 +562,16 @@ class AccountingAccount extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Account deactivated
     	 *
     	 * @param  int  $id         Id
     	 * @return int              <0 if KO, >0 if OK
     	 */
    -	function account_desactivate($id) {
    +    function account_desactivate($id)
    +    {
    +        // phpcs:enable
     		$result = $this->checkUsage();
     
     		if ($result > 0) {
    @@ -520,13 +597,16 @@ class AccountingAccount extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Account activated
     	 *
     	 * @param  int  $id         Id
     	 * @return int              <0 if KO, >0 if OK
     	 */
    -	function account_activate($id) {
    +    function account_activate($id)
    +    {
    +        // phpcs:enable
     		$this->db->begin();
     
     		$sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account ";
    @@ -557,6 +637,7 @@ class AccountingAccount extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -566,6 +647,7 @@ class AccountingAccount extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->loadLangs(array("users"));
     
    @@ -575,27 +657,27 @@ class AccountingAccount extends CommonObject
     			if ($statut == 1) return $langs->trans('Enabled');
     			if ($statut == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut == 1) return $langs->trans('Enabled');
     			if ($statut == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4');
     			if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($statut == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php
    index 454de6d7b84..9bd21a4a5c4 100644
    --- a/htdocs/accountancy/class/accountingjournal.class.php
    +++ b/htdocs/accountancy/class/accountingjournal.class.php
    @@ -26,16 +26,44 @@
      */
     class AccountingJournal extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='accounting_journal';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='accounting_journal';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element = '';
    -	public $ismultientitymanaged = 0;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 0;
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'generic';
     
    -	var $rowid;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $rowid;
     
     	public $code;
    -	public $label;
    +
    +	/**
    +     * @var string Accounting Journal label
    +     */
    +    public $label;
    +
     	public $nature;		// 1:various operations, 2:sale, 3:purchase, 4:bank, 5:expense-report, 8:inventory, 9: has-new
     	public $active;
     
    @@ -46,7 +74,8 @@ class AccountingJournal extends CommonObject
     	 *
     	 * @param DoliDB $db Database handle
     	 */
    -	function __construct($db) {
    +    function __construct($db)
    +    {
     		$this->db = $db;
     	}
     
    @@ -117,7 +146,8 @@ class AccountingJournal extends CommonObject
     	 *
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') {
    +    function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
    +    {
     		$sql = "SELECT rowid, code, label, nature, active";
     		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
     		// Manage filter
    @@ -245,6 +275,7 @@ class AccountingJournal extends CommonObject
     		return $this->LibType($this->nature,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return type of an accounting journal
     	 *
    @@ -254,6 +285,7 @@ class AccountingJournal extends CommonObject
     	 */
     	function LibType($nature,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$langs->loadLangs(array("accountancy"));
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index e751cf1899f..b07f76a22df 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2014-2017 Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2015-2017 Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2015-2017 Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2014-2017  Olivier Geffroy     <jeff@jeffinfo.com>
    + * Copyright (C) 2015-2017  Alexandre Spangaro  <aspangaro@zendsi.com>
    + * Copyright (C) 2015-2017  Florian Henry       <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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,9 +19,9 @@
      */
     
     /**
    - *	\file		htdocs/accountancy/class/bookkeeping.class.php
    - *	\ingroup	Advanced accountancy
    - *	\brief		File of class to manage Ledger (General Ledger and Subledger)
    + * \file        htdocs/accountancy/class/bookkeeping.class.php
    + * \ingroup     Advanced accountancy
    + * \brief       File of class to manage Ledger (General Ledger and Subledger)
      */
     
     // Class
    @@ -35,19 +36,25 @@ class BookKeeping extends CommonObject
     	 * @var string Error code (or message)
     	 */
     	public $error;
    +
     	/**
     	 * @var string[] Error codes (or messages)
     	 */
    -	public $errors = array ();
    +	public $errors = array();
    +
     	/**
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'accountingbookkeeping';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'accounting_bookkeeping';
     
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
     
     	/**
    @@ -59,14 +66,22 @@ class BookKeeping extends CommonObject
     	 * @var int ID
     	 */
     	public $id;
    -	/**
    -	 */
    +
     	public $doc_date;
     	public $date_lim_reglement;
     	public $doc_type;
     	public $doc_ref;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_doc;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_docdet;
    +
     	public $thirdparty_code;
     	public $subledger_account;
     	public $subledger_label;
    @@ -77,7 +92,12 @@ class BookKeeping extends CommonObject
     	public $credit;
     	public $montant;
     	public $sens;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
     	public $import_key;
     	public $code_journal;
     	public $journal_label;
    @@ -88,7 +108,8 @@ class BookKeeping extends CommonObject
     	 *
     	 * @param DoliDb $db Database handler
     	 */
    -	public function __construct(DoliDB $db) {
    +    public function __construct(DoliDB $db)
    +    {
     		$this->db = $db;
     	}
     
    @@ -99,7 +120,8 @@ class BookKeeping extends CommonObject
     	 * @param  bool	$notrigger	false=launch triggers after, true=disable triggers
     	 * @return int				<0 if KO, Id of created object if OK
     	 */
    -	public function create(User $user, $notrigger = false) {
    +    public function create(User $user, $notrigger = false)
    +    {
     		global $conf, $langs;
     
     		dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -328,18 +350,15 @@ class BookKeeping extends CommonObject
     			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
     		}
     
    -		if (! $error) {
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action to call a trigger.
    +		//if (! $error && ! $notrigger) {
     
    -			if (! $notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action to call a trigger.
    -
    -				// // Call triggers
    -				// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
    -				// if ($result < 0) $error++;
    -				// // End call triggers
    -			}
    -		}
    +		// // Call triggers
    +		// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
    +		// if ($result < 0) $error++;
    +		// // End call triggers
    +		//}
     
     		// Commit or rollback
     		if ($error) {
    @@ -420,7 +439,8 @@ class BookKeeping extends CommonObject
     	 * @param  string  $mode 	   Mode
     	 * @return int				 <0 if KO, Id of created object if OK
     	 */
    -	public function createStd(User $user, $notrigger = false, $mode='') {
    +    public function createStd(User $user, $notrigger = false, $mode='')
    +    {
     		global $conf;
     
     		dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -558,15 +578,15 @@ class BookKeeping extends CommonObject
     		if (! $error) {
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element . $mode);
     
    -			if (! $notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action to call a trigger.
    +			// Uncomment this and change MYOBJECT to your own tag if you
    +			// want this action to call a trigger.
    +			//if (! $notrigger) {
     
    -				// // Call triggers
    -				// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
    -				// if ($result < 0) $error++;
    -				// // End call triggers
    -			}
    +			// // Call triggers
    +			// $result=$this->call_trigger('MYOBJECT_CREATE',$user);
    +			// if ($result < 0) $error++;
    +			// // End call triggers
    +			//}
     		}
     
     		// Commit or rollback
    @@ -590,7 +610,8 @@ class BookKeeping extends CommonObject
     	 *
     	 * @return int <0 if KO, 0 if not found, >0 if OK
     	 */
    -	public function fetch($id, $ref = null, $mode='') {
    +    public function fetch($id, $ref = null, $mode='')
    +    {
     		global $conf;
     
     		dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -687,7 +708,8 @@ class BookKeeping extends CommonObject
     	 *
     	 * @return int <0 if KO, >=0 if OK
     	 */
    -	public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') {
    +    public function fetchAllByAccount($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
    +    {
     		global $conf;
     
     		dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -711,6 +733,10 @@ class BookKeeping extends CommonObject
     		$sql .= " t.credit,";
     		$sql .= " t.montant,";
     		$sql .= " t.sens,";
    +		$sql .= " t.multicurrency_amount,";
    +		$sql .= " t.multicurrency_code,";
    +		$sql .= " t.lettering_code,";
    +		$sql .= " t.date_lettering,";
     		$sql .= " t.fk_user_author,";
     		$sql .= " t.import_key,";
     		$sql .= " t.code_journal,";
    @@ -759,7 +785,8 @@ class BookKeeping extends CommonObject
     		if ($resql) {
     			$num = $this->db->num_rows($resql);
     
    -			while ( $obj = $this->db->fetch_object($resql) ) {
    +			$i = 0;
    +			while ($obj = $this->db->fetch_object($resql) && (empty($limit) || $i < min($limit, $num))) {
     				$line = new BookKeepingLine();
     
     				$line->id = $obj->rowid;
    @@ -779,6 +806,10 @@ class BookKeeping extends CommonObject
     				$line->credit = $obj->credit;
     				$line->montant = $obj->montant;
     				$line->sens = $obj->sens;
    +				$line->multicurrency_amount = $obj->multicurrency_amount;
    +				$line->multicurrency_code = $obj->multicurrency_code;
    +				$line->lettering_code = $obj->lettering_code;
    +				$line->date_lettering = $obj->date_lettering;
     				$line->fk_user_author = $obj->fk_user_author;
     				$line->import_key = $obj->import_key;
     				$line->code_journal = $obj->code_journal;
    @@ -787,6 +818,8 @@ class BookKeeping extends CommonObject
     				$line->date_creation = $obj->date_creation;
     
     				$this->lines[] = $line;
    +
    +				$i++;
     			}
     			$this->db->free($resql);
     
    @@ -811,7 +844,8 @@ class BookKeeping extends CommonObject
     	 *
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') {
    +    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
    +    {
     		global $conf;
     
     		dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -831,6 +865,7 @@ class BookKeeping extends CommonObject
     		$sql .= " t.label_operation,";
     		$sql .= " t.debit,";
     		$sql .= " t.credit,";
    +		$sql .= " t.lettering_code,";
     		$sql .= " t.montant,";
     		$sql .= " t.sens,";
     		$sql .= " t.fk_user_author,";
    @@ -883,7 +918,8 @@ class BookKeeping extends CommonObject
     		if ($resql) {
     			$num = $this->db->num_rows($resql);
     
    -			while ( $obj = $this->db->fetch_object($resql) ) {
    +			$i = 0;
    +			while ($obj = $this->db->fetch_object($resql) && (empty($limit) || $i < min($limit, $num))) {
     				$line = new BookKeepingLine();
     
     				$line->id = $obj->rowid;
    @@ -903,6 +939,7 @@ class BookKeeping extends CommonObject
     				$line->credit = $obj->credit;
     				$line->montant = $obj->montant;
     				$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;
    @@ -912,6 +949,8 @@ class BookKeeping extends CommonObject
     				$line->date_modification = $this->db->jdate($obj->date_modification);
     
     				$this->lines[] = $line;
    +
    +				$i++;
     			}
     			$this->db->free($resql);
     
    @@ -970,8 +1009,7 @@ class BookKeeping extends CommonObject
     				}
     			}
     		}
    -		$sql.= ' WHERE 1 = 1';
    -		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
    +		$sql.= ' WHERE entity IN (' . getEntity('accountancy') . ')';
     		if (count($sqlwhere) > 0) {
     			$sql .= ' AND ' . implode(' ' . $filtermode . ' ', $sqlwhere);
     		}
    @@ -991,7 +1029,7 @@ class BookKeeping extends CommonObject
     			$num = $this->db->num_rows($resql);
     
     			$i = 0;
    -			while (($obj = $this->db->fetch_object($resql)) && ($i < min($limit, $num)))
    +			while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num)))
     			{
     				$line = new BookKeepingLine();
     
    @@ -1021,7 +1059,8 @@ class BookKeeping extends CommonObject
     	 * @param  string  $mode       Mode
     	 * @return int                 <0 if KO, >0 if OK
     	 */
    -	public function update(User $user, $notrigger = false, $mode='') {
    +    public function update(User $user, $notrigger = false, $mode='')
    +    {
     		$error = 0;
     
     		dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -1124,15 +1163,15 @@ class BookKeeping extends CommonObject
     			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
     		}
     
    -		if (! $error && ! $notrigger) {
    -			// Uncomment this and change MYOBJECT to your own tag if you
    -			// want this action calls a trigger.
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action calls a trigger.
    +		//if (! $error && ! $notrigger) {
     
    -			// // Call triggers
    -			// $result=$this->call_trigger('MYOBJECT_MODIFY',$user);
    -			// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    -			// // End call triggers
    -		}
    +		// // Call triggers
    +		// $result=$this->call_trigger('MYOBJECT_MODIFY',$user);
    +		// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    +		// // End call triggers
    +		//}
     
     		// Commit or rollback
     		if ($error) {
    @@ -1190,24 +1229,23 @@ class BookKeeping extends CommonObject
     	 * @param string $mode Mode
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	public function delete(User $user, $notrigger = false, $mode='') {
    +    public function delete(User $user, $notrigger = false, $mode='')
    +    {
     		dol_syslog(__METHOD__, LOG_DEBUG);
     
     		$error = 0;
     
     		$this->db->begin();
     
    -		if (! $error) {
    -			if (! $notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action calls a trigger.
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action calls a trigger.
    +		//if (! $error && ! $notrigger) {
     
    -				// // Call triggers
    -				// $result=$this->call_trigger('MYOBJECT_DELETE',$user);
    -				// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    -				// // End call triggers
    -			}
    -		}
    +		// // Call triggers
    +		// $result=$this->call_trigger('MYOBJECT_DELETE',$user);
    +		// if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    +		// // End call triggers
    +		//}
     
     		if (! $error) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element.$mode;
    @@ -1239,7 +1277,8 @@ class BookKeeping extends CommonObject
     	 * @param  string		$importkey		Import key
     	 * @return int Result
     	 */
    -	function deleteByImportkey($importkey) {
    +    function deleteByImportkey($importkey)
    +    {
     		$this->db->begin();
     
     		// first check if line not yet in bookkeeping
    @@ -1268,7 +1307,8 @@ class BookKeeping extends CommonObject
     	 * @param  string $mode 		Mode
     	 * @return int					<0 if KO, >0 if OK
     	 */
    -	function deleteByYearAndJournal($delyear='', $journal='', $mode='') {
    +    function deleteByYearAndJournal($delyear='', $journal='', $mode='')
    +    {
     		global $conf;
     
     		if (empty($delyear) && empty($journal))
    @@ -1307,7 +1347,8 @@ class BookKeeping extends CommonObject
     	 * @param 	int 	$piecenum 	Piecenum to delete
     	 * @return 	int 				Result
     	 */
    -	function deleteMvtNum($piecenum) {
    +    function deleteMvtNum($piecenum)
    +    {
     		global $conf;
     
     		$this->db->begin();
    @@ -1341,7 +1382,8 @@ class BookKeeping extends CommonObject
     	 *
     	 * @return int New id of clone
     	 */
    -	public function createFromClone($fromid) {
    +    public function createFromClone($fromid)
    +    {
     		dol_syslog(__METHOD__, LOG_DEBUG);
     
     		global $user;
    @@ -1386,7 +1428,8 @@ class BookKeeping extends CommonObject
     	 *
     	 * @return void
     	 */
    -	public function initAsSpecimen() {
    +    public function initAsSpecimen()
    +    {
     		global $user;
     
     		$now=dol_now();
    @@ -1422,7 +1465,8 @@ class BookKeeping extends CommonObject
     	 * @param string $mode Mode
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	public function fetchPerMvt($piecenum, $mode='') {
    +    public function fetchPerMvt($piecenum, $mode='')
    +    {
     		global $conf;
     
     		$sql = "SELECT piece_num,doc_date,code_journal,journal_label,doc_ref,doc_type,date_creation";
    @@ -1486,7 +1530,8 @@ class BookKeeping extends CommonObject
     	 * @param  string  $mode       Mode
     	 * @return int                 <0 if KO, >0 if OK
     	 */
    -	function fetchAllPerMvt($piecenum, $mode='') {
    +    function fetchAllPerMvt($piecenum, $mode='')
    +    {
     		global $conf;
     
     		$sql = "SELECT rowid, doc_date, doc_type,";
    @@ -1538,13 +1583,16 @@ class BookKeeping extends CommonObject
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Export bookkeping
     	 *
     	 * @param	string	$model	Model
     	 * @return	int				Result
     	 */
    -	function export_bookkeping($model = 'ebp') {
    +    function export_bookkeping($model = 'ebp')
    +    {
    +        // phpcs:enable
     		global $conf;
     
     		$sql = "SELECT rowid, doc_date, doc_type,";
    @@ -1600,9 +1648,9 @@ class BookKeeping extends CommonObject
     	/**
     	 * Transform transaction
     	 *
    -	 * @param  number   $direction     If 0 tmp => real, if 1 real => tmp
    -	 * @param  string   $piece_num     Piece num
    -	 * @return void
    +	 * @param  number   $direction      If 0 tmp => real, if 1 real => tmp
    +	 * @param  string   $piece_num      Piece num
    +	 * @return int                      int <0 if KO, >0 if OK
     	 */
     	public function transformTransaction($direction=0,$piece_num='')
     	{
    @@ -1638,8 +1686,7 @@ class BookKeeping extends CommonObject
     				$this->errors[] = 'Error ' . $this->db->lasterror();
     				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
     			}
    -		}
    -		if ($direction==1) {
    +		} elseif ($direction==1) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element.'_tmp WHERE piece_num = '.$piece_num;
     			$resql = $this->db->query($sql);
     			if (! $resql) {
    @@ -1689,19 +1736,22 @@ class BookKeeping extends CommonObject
     		*/
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	* Return list of accounts with label by chart of accounts
     	*
    -	* @param string		$selectid	Preselected chart of accounts
    -	* @param string		$htmlname	Name of field in html form
    +	* @param string     $selectid   Preselected chart of accounts
    +	* @param string     $htmlname	Name of field in html form
     	* @param int		$showempty	Add an empty field
     	* @param array		$event		Event options
     	* @param int		$select_in	Value is a aa.rowid (0 default) or aa.account_number (1)
     	* @param int		$select_out	Set value returned by select 0=rowid (default), 1=account_number
     	* @param int		$aabase		Set accounting_account base class to display empty=all or from 1 to 8 will display only account beginning by this number
     	* @return string	String with HTML select
    -	*/
    -	function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $aabase = '') {
    +    */
    +    function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $aabase = '')
    +    {
    +        // phpcs:enable
     		global $conf;
     
     		require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
    @@ -1758,6 +1808,7 @@ class BookKeeping extends CommonObject
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Description of a root accounting account
     	 *
    @@ -1766,6 +1817,7 @@ class BookKeeping extends CommonObject
     	 */
     	function get_compte_racine($account = null)
     	{
    +        // phpcs:enable
     		global $conf;
     		$pcgver = $conf->global->CHARTOFACCOUNTS;
     
    @@ -1789,7 +1841,6 @@ class BookKeeping extends CommonObject
     			}
     
     			return $obj->label;
    -
     		} else {
     			$this->error = "Error " . $this->db->lasterror();
     			dol_syslog(__METHOD__ . " " . $this->error, LOG_ERR);
    @@ -1798,6 +1849,7 @@ class BookKeeping extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Description of accounting account
     	 *
    @@ -1806,6 +1858,7 @@ class BookKeeping extends CommonObject
     	 */
     	function get_compte_desc($account = null)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$pcgver = $conf->global->CHARTOFACCOUNTS;
    @@ -1843,12 +1896,25 @@ class BookKeeping extends CommonObject
      */
     class BookKeepingLine
     {
    +	/**
    +	 * @var int ID
    +	 */
     	public $id;
    +
     	public $doc_date = '';
     	public $doc_type;
     	public $doc_ref;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_doc;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_docdet;
    +
     	public $thirdparty_code;
     	public $subledger_account;
     	public $subledger_label;
    @@ -1859,7 +1925,12 @@ class BookKeepingLine
     	public $credit;
     	public $montant;
     	public $sens;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
     	public $import_key;
     	public $code_journal;
     	public $journal_label;
    diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
    index a67fd457e11..3122526061b 100644
    --- a/htdocs/accountancy/class/lettering.class.php
    +++ b/htdocs/accountancy/class/lettering.class.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    +/* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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,26 +19,27 @@
      */
     
     /**
    - * \file accountancy/class/bookkeeping.class.php
    - * \ingroup Advanced accountancy
    - * \brief 	File of class for lettering
    + * \file      	htdocs/accountancy/class/lettering.class.php
    + * \ingroup 	Advanced accountancy
    + * \brief 		File of class for lettering
      */
    +
     include_once DOL_DOCUMENT_ROOT . "/accountancy/class/bookkeeping.class.php";
     include_once DOL_DOCUMENT_ROOT . "/societe/class/societe.class.php";
     include_once DOL_DOCUMENT_ROOT . "/core/lib/date.lib.php";
     
     /**
    - * Class lettering
    + * Class Lettering
      */
    -class lettering extends BookKeeping
    +class Lettering extends BookKeeping
     {
     	/**
    -	 * lettrageTiers
    +	 * letteringThirdparty
     	 *
     	 * @param int $socid Thirdparty id
    -	 * @return void
    +	 * @return int 1 OK, <0 error
     	 */
    -	public function lettrageTiers($socid)
    +	public function letteringThirdparty($socid)
     	{
     		global $conf;
     
    @@ -47,6 +49,7 @@ class lettering extends BookKeeping
     		$object->id = $socid;
     		$object->fetch($socid);
     
    +
     		if ($object->code_compta == '411CUSTCODE') {
     			$object->code_compta = '';
     		}
    @@ -229,7 +232,7 @@ class lettering extends BookKeeping
     	 * @param boolean $notrigger no trigger
      	 * @return number
     	 */
    -	public function updateLettrage($ids = array(), $notrigger = false)
    +	public function updateLettering($ids = array(), $notrigger = false)
     	{
     		$error = 0;
     		$lettre = 'AAA';
    diff --git a/htdocs/accountancy/customer/card.php b/htdocs/accountancy/customer/card.php
    index 7e1387db951..677bc627c80 100644
    --- a/htdocs/accountancy/customer/card.php
    +++ b/htdocs/accountancy/customer/card.php
    @@ -159,5 +159,6 @@ if (! empty($id)) {
     	print "Error ID incorrect";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php
    index 18e23826314..4f4932fe08f 100644
    --- a/htdocs/accountancy/customer/index.php
    +++ b/htdocs/accountancy/customer/index.php
    @@ -89,7 +89,7 @@ if ($action == 'clean' || $action == 'validatehistory')
     	if (! $resql1) {
     		$error ++;
     		$db->rollback();
    -		setEventMessage($db->lasterror(), 'errors');
    +		setEventMessages($db->lasterror(), null, 'errors');
     	} else {
     		$db->commit();
     	}
    @@ -153,7 +153,7 @@ $y = $year_current;
     $buttonbind = '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?year=' . $year_current . '&action=validatehistory">' . $langs->trans("ValidateHistory") . '</a>';
     
     print_barre_liste($langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1);
    -//print_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
    +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
     
     print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
    @@ -229,7 +229,7 @@ print '<br>';
     
     
     print_barre_liste($langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
    -//print_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
    +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
     
     print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
    @@ -309,7 +309,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
     	print '<br>';
     
     	print_barre_liste($langs->trans("OtherInfo"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
    -	//print_fiche_titre($langs->trans("OtherInfo"), '', '');
    +	//print load_fiche_titre($langs->trans("OtherInfo"), '', '');
     
     	print '<div class="div-table-responsive-no-min">';
     	print '<table class="noborder" width="100%">';
    @@ -415,6 +415,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php
    index cc0ced6b067..7d8599b683c 100644
    --- a/htdocs/accountancy/customer/lines.php
    +++ b/htdocs/accountancy/customer/lines.php
    @@ -17,7 +17,6 @@
      *
      * You should have received a copy of the GNU General Public License
      * along with this program. If not, see <http://www.gnu.org/licenses/>.
    - *
      */
     
     /**
    @@ -33,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("bills","compta","accountancy","productbatch"));
    @@ -135,7 +135,6 @@ if (is_array($changeaccount) && count($changeaccount) > 0) {
     
     		$account_parent = '';   // Protection to avoid to mass apply it a second time
     	}
    -
     }
     
     
    @@ -173,7 +172,8 @@ $sql.= " fd.rowid, fd.description, fd.product_type as line_type, fd.total_ht, fd
     $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.code_client,";
     $sql.= " p.rowid as product_id, p.fk_product_type as product_type, p.ref as product_ref, p.label as product_label, p.accountancy_code_sell, aa.rowid as fk_compte, aa.account_number, aa.label as label_compte,";
     $sql.= " fd.situation_percent,";
    -$sql.= " co.label as country, s.tva_intra";
    +$sql.= " co.code as country_code, co.label as country,";
    +$sql.= " s.tva_intra";
     $parameters=array();
     $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters);    // Note that $action and $object may have been modified by hook
     $sql.=$hookmanager->resPrint;
    @@ -229,7 +229,18 @@ else if ($search_year > 0)
     	$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
     }
     if (strlen(trim($search_country))) {
    -	$sql .= natural_search("co.label", $search_country);
    +	$arrayofcode = getCountriesInEEC();
    +	$country_code_in_EEC = $country_code_in_EEC_without_me = '';
    +	foreach ($arrayofcode as $key => $value)
    +	{
    +		$country_code_in_EEC.=($country_code_in_EEC ? "," : "")."'".$value."'";
    +		if ($value != $mysoc->country_code) $country_code_in_EEC_without_me.=($country_code_in_EEC_without_me ? "," : "")."'".$value."'";
    +	}
    +	if ($search_country == 'special_allnotme')     $sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
    +	elseif ($search_country == 'special_eec')      $sql .= " AND co.code IN (".$country_code_in_EEC.")";
    +	elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
    +	elseif ($search_country == 'special_noteec')   $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
    +	else $sql .= natural_search(array("co.code","co.label"), $search_country);
     }
     if (strlen(trim($search_tvaintra))) {
     	$sql .= natural_search("s.tva_intra", $search_tvaintra);
    @@ -297,9 +308,9 @@ if ($result) {
     	print '<tr class="liste_titre_filter">';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth25" name="search_lineid" value="' . dol_escape_htmltag($search_lineid) . '""></td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
    -	print '<td class="liste_titre center">';
    -	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_day" value="'.dol_escape_htmltag($search_day).'">';
    -   	print '<input class="flat" type="text" size="1" maxlength="2" name="search_month" value="'.dol_escape_htmltag($search_month).'">';
    +	print '<td class="liste_titre center nowraponall">';
    +	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.dol_escape_htmltag($search_day).'">';
    +   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.dol_escape_htmltag($search_month).'">';
        	$formother->select_year($search_year,'search_year',1, 20, 5);
     	print '</td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
    @@ -307,7 +318,10 @@ if ($result) {
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="right flat maxwidth50" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="right flat maxwidth50" placeholder="%" name="search_vat" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
    -	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '"></td>';
    +	print '<td class="liste_titre">';
    +	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2', 1, 0, 1);
    +	//print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
    +	print '</td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="' . dol_escape_htmltag($search_tvaintra) . '"></td>';
     	print '<td class="liste_titre" align="center"><input type="text" class="flat maxwidth50" name="search_account" value="' . dol_escape_htmltag($search_account) . '"></td>';
     	print '<td class="liste_titre" align="center">';
    @@ -352,7 +366,7 @@ if ($result) {
     		print '<td>' . $objp->rowid . '</td>';
     
     		// Ref Invoice
    -		print '<td>' . $facture_static->getNomUrl(1) . '</td>';
    +		print '<td class="nowraponall">' . $facture_static->getNomUrl(1) . '</td>';
     
     		print '<td align="center">' . dol_print_date($db->jdate($objp->datef), 'day') . '</td>';
     
    @@ -370,9 +384,10 @@ if ($result) {
     		print '</td>';
     
     		print '<td align="right">' . price($objp->total_ht) . '</td>';
    +
     		print '<td align="right">' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . '</td>';
     
    -		print '<td>' . $objp->country .'</td>';
    +		print '<td>' . $langs->trans("Country".$objp->country_code) .' ('.$objp->country_code.')</td>';
     
     		print '<td>' . $objp->tva_intra . '</td>';
     
    @@ -400,6 +415,6 @@ if ($result) {
     	print $db->lasterror();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php
    index 69396131b02..74944b8f823 100644
    --- a/htdocs/accountancy/customer/list.php
    +++ b/htdocs/accountancy/customer/list.php
    @@ -34,6 +34,7 @@ require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php
     require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("bills","compta","accountancy","other","productbatch"));
    @@ -201,8 +202,9 @@ llxHeader('', $langs->trans("Ventilation"));
     if (empty($chartaccountcode))
     {
     	print $langs->trans("ErrorChartOfAccountSystemNotSelected");
    -	llxFooter();
    -	$db->close();
    +	// End of page
    +    llxFooter();
    +    $db->close();
     	exit;
     }
     
    @@ -211,7 +213,8 @@ $sql = "SELECT f.rowid as facid, f.facnumber as ref, f.datef, f.type as ftype,";
     $sql.= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
     $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_sell as code_sell, p.tva_tx as tva_tx_prod,";
     $sql.= " aa.rowid as aarowid,";
    -$sql.= " co.label as country, s.tva_intra";
    +$sql.= " co.code as country_code, co.label as country,";
    +$sql.= " s.tva_intra";
     $parameters=array();
     $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters);    // Note that $action and $object may have been modified by hook
     $sql.=$hookmanager->resPrint;
    @@ -264,7 +267,18 @@ else if ($search_year > 0)
     	$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
     }
     if (strlen(trim($search_country))) {
    -	$sql .= natural_search("co.label", $search_country);
    +	$arrayofcode = getCountriesInEEC();
    +	$country_code_in_EEC = $country_code_in_EEC_without_me = '';
    +	foreach ($arrayofcode as $key => $value)
    +	{
    +		$country_code_in_EEC.=($country_code_in_EEC ? "," : "")."'".$value."'";
    +		if ($value != $mysoc->country_code) $country_code_in_EEC_without_me.=($country_code_in_EEC_without_me ? "," : "")."'".$value."'";
    +	}
    +	if ($search_country == 'special_allnotme')     $sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
    +	elseif ($search_country == 'special_eec')      $sql .= " AND co.code IN (".$country_code_in_EEC.")";
    +	elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
    +	elseif ($search_country == 'special_noteec')   $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
    +	else $sql .= natural_search(array("co.code","co.label"), $search_country);
     }
     if (strlen(trim($search_tvaintra))) {
     	$sql .= natural_search("s.tva_intra", $search_tvaintra);
    @@ -370,7 +384,10 @@ if ($result) {
     	print '<td class="liste_titre"><input type="text" class="flat maxwidthonsmartphone" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="flat maxwidth50 right" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="flat maxwidth50 right" name="search_vat" placeholder="%" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
    -	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '"></td>';
    +	print '<td class="liste_titre">';
    +	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2', 1, 0, 1);
    +	//print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
    +	print '</td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="' . dol_escape_htmltag($search_tvaintra) . '"></td>';
     	print '<td class="liste_titre"></td>';
     	print '<td class="liste_titre"></td>';
    @@ -449,7 +466,7 @@ if ($result) {
     		print '<td>' . $objp->rowid . '</td>';
     
     		// Ref Invoice
    -		print '<td>' . $facture_static->getNomUrl(1) . '</td>';
    +		print '<td class="nowraponall">' . $facture_static->getNomUrl(1) . '</td>';
     
     		print '<td align="center">' . dol_print_date($db->jdate($objp->datef), 'day') . '</td>';
     
    @@ -524,5 +541,6 @@ jQuery(document).ready(function() {
     });
     </script>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php
    index d9b2137157d..b245e2539a7 100644
    --- a/htdocs/accountancy/expensereport/card.php
    +++ b/htdocs/accountancy/expensereport/card.php
    @@ -167,5 +167,6 @@ if (! empty($id)) {
     	print "Error ID incorrect";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/expensereport/index.php b/htdocs/accountancy/expensereport/index.php
    index 49b20730eef..837a8c36630 100644
    --- a/htdocs/accountancy/expensereport/index.php
    +++ b/htdocs/accountancy/expensereport/index.php
    @@ -86,7 +86,7 @@ if ($action == 'clean' || $action == 'validatehistory')
     	if (! $resql1) {
     		$error ++;
     		$db->rollback();
    -		setEventMessage($db->lasterror(), 'errors');
    +		setEventMessages($db->lasterror(), null, 'errors');
     	} else {
     		$db->commit();
     	}
    @@ -150,7 +150,7 @@ $buttonbind = '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?year=' .
     
     
     print_barre_liste($langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1);
    -//print_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
    +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
     
     print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
    @@ -221,7 +221,7 @@ print '<br>';
     
     
     print_barre_liste($langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
    -//print_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
    +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
     
     
     print '<div class="div-table-responsive-no-min">';
    @@ -297,7 +297,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
         print '<br>';
     
         print_barre_liste($langs->trans("OtherInfo"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
    -    //print_fiche_titre($langs->trans("OtherInfo"), '', '');
    +    //print load_fiche_titre($langs->trans("OtherInfo"), '', '');
     
     	print '<div class="div-table-responsive-no-min">';
         print '<table class="noborder" width="100%">';
    @@ -345,5 +345,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
         print '</div>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php
    index 473bc379057..b328cf73455 100644
    --- a/htdocs/accountancy/expensereport/lines.php
    +++ b/htdocs/accountancy/expensereport/lines.php
    @@ -236,8 +236,6 @@ if ($result) {
     	if ($search_day)        $param .= '&search_day='.urlencode($search_day);
     	if ($search_month)      $param .= '&search_month='.urlencode($search_month);
     	if ($search_year)       $param .= '&search_year='.urlencode($search_year);
    -	if ($search_country)	$param .= "&search_country=" . urlencode($search_country);
    -	if ($search_tvaintra)	$param .= "&search_tvaintra=" . urlencode($search_tvaintra);
     
     	print '<form action="' . $_SERVER["PHP_SELF"] . '" method="post">' . "\n";
     	print '<input type="hidden" name="action" value="ventil">';
    @@ -349,6 +347,6 @@ if ($result) {
     	print $db->lasterror();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php
    index a20f88f1c30..8057c9809f2 100644
    --- a/htdocs/accountancy/expensereport/list.php
    +++ b/htdocs/accountancy/expensereport/list.php
    @@ -180,8 +180,9 @@ llxHeader('', $langs->trans("ExpenseReportsVentilation"));
     if (empty($chartaccountcode))
     {
     	print $langs->trans("ErrorChartOfAccountSystemNotSelected");
    -	llxFooter();
    -	$db->close();
    +	// End of page
    +    llxFooter();
    +    $db->close();
     	exit;
     }
     
    @@ -422,5 +423,6 @@ jQuery(document).ready(function() {
     });
     </script>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index 9a3767bd8e4..2d34ec816e3 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -55,19 +55,19 @@ if ($conf->accounting->enabled)
     	print $langs->trans("AccountancyAreaDescIntro")."<br>\n";
     	print "<br>\n";print "<br>\n";
     
    -	print_fiche_titre('<span class="fa fa-calendar-check-o"></span> '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."<br>\n";
    +	print load_fiche_titre('<span class="fa fa-calendar-check-o"></span> '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."<br>\n";
     	print '<hr>';
     	print "<br>\n";
     
     	// STEPS
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("AccountingJournals").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("AccountingJournals").'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>'.'</a>');
     	print "<br>\n";
     
     	print "<br>\n";
    @@ -76,20 +76,20 @@ if ($conf->accounting->enabled)
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/defaultaccounts.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>'.'</a>');
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuBankAccounts").'</strong>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '<a href="'.DOL_URL_ROOT.'/compta/bank/list.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuBankAccounts").'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	$step++;
    -	$textlink = '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong>';
    +	$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=10&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong>'.'</a>';
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, $textlink);
     	print "<br>\n";
     	if (! empty($conf->tax->enabled))
     	{
    -	    $textlink = '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong>';
    +	     $textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong>'.'</a>';
     	    $step++;
     	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, $textlink);
     	    print "<br>\n";
    @@ -105,7 +105,7 @@ if ($conf->accounting->enabled)
     	if (! empty($conf->expensereport->enabled))  // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
     	{
     	    $step++;
    -	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong>');
    +	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong>'.'</a>');
     	    print "<br>\n";
     	}
     	/*
    @@ -123,7 +123,7 @@ if ($conf->accounting->enabled)
     	}*/
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("ProductsBinding").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/productaccount.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("ProductsBinding").'</strong>'.'</a>');
     	print "<br>\n";
     
     
    @@ -131,7 +131,7 @@ if ($conf->accounting->enabled)
     
     
     	print "<br>\n";
    -	print_fiche_titre('<span class="fa fa-calendar"></span> '.$langs->trans("AccountancyAreaDescActionFreq"), '', '');
    +	print load_fiche_titre('<span class="fa fa-calendar"></span> '.$langs->trans("AccountancyAreaDescActionFreq"), '', '');
     	print '<hr>';
     	print "<br>\n";
     	$step = 0;
    @@ -139,18 +139,18 @@ if ($conf->accounting->enabled)
     	$langs->loadLangs(array('bills', 'trips'));
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsCustomers"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("CustomersVentilation").'</strong>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsCustomers"), '<a href="'.DOL_URL_ROOT.'/accountancy/customer/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("CustomersVentilation").'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<a href="'.DOL_URL_ROOT.'/accountancy/supplier/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	if (! empty($conf->expensereport->enabled) || ! empty($conf->deplacement->enabled))
     	{
     		$step++;
    -		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."\n";
    -		print "<br>\n";
    +		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>'.'</a>')."\n";
    +	    print "<br>\n";
     	}
     
     	$step++;
    @@ -166,5 +166,6 @@ else
     	print $langs->trans("Module10Desc")."<br>\n";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
    index 23a7e71d325..3b86835e927 100644
    --- a/htdocs/accountancy/journal/bankjournal.php
    +++ b/htdocs/accountancy/journal/bankjournal.php
    @@ -1,13 +1,13 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur <eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger     <jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent       <jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin       <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013       Christophe Battarel <christophe.battarel@altairis.fr>
    - * Copyright (C) 2013-2018  Alexandre Spangaro  <aspangaro@zendsi.com>
    - * Copyright (C) 2013-2014  Florian Henry       <florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2014  Olivier Geffroy     <jeff@jeffinfo.com>
    - * Copyright (C) 2017       Frédéric France     <frederic.france@netlogic.fr>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2014  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2017-2018  Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -33,6 +33,7 @@ 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/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
     require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
    @@ -147,6 +148,9 @@ $paymentsalstatic = new PaymentSalary($db);
     $paymentexpensereportstatic = new PaymentExpenseReport($db);
     $paymentvariousstatic = new PaymentVarious($db);
     $paymentloanstatic = new PaymentLoan($db);
    +$accountLinestatic=new AccountLine($db);
    +
    +$accountingaccount = new AccountingAccount($db);
     
     // Get code of finance journal
     $accountingjournalstatic = new AccountingJournal($db);
    @@ -154,6 +158,7 @@ $accountingjournalstatic->fetch($id_journal);
     $journal = $accountingjournalstatic->code;
     $journal_label = $accountingjournalstatic->label;
     
    +
     dol_syslog("accountancy/journal/bankjournal.php", LOG_DEBUG);
     $result = $db->query($sql);
     if ($result) {
    @@ -370,7 +375,8 @@ if ($result) {
     					$tabpay[$obj->rowid]["paymentloanid"] = $paymentloanstatic->id;
     					//$tabtp[$obj->rowid][$account_pay_loan] += $obj->amount;
     				} else if ($links[$key]['type'] == 'banktransfert') {
    -					$tabpay[$obj->rowid]["lib"] .= ' ' . $langs->trans("BankTransfer");
    +					$accountLinestatic->fetch($links[$key]['url_id']);
    +					$tabpay[$obj->rowid]["lib"] .= ' '.$langs->trans("BankTransfer").'- ' .$accountLinestatic ->getNomUrl(1);
     					$tabtp[$obj->rowid][$account_transfer] += $obj->amount;
     					$bankaccountstatic->fetch($tabpay[$obj->rowid]['fk_bank_account']);
     					$tabpay[$obj->rowid]["soclib"] = $bankaccountstatic->getNomUrl(2);
    @@ -459,7 +465,11 @@ if (! $error && $action == 'writebookkeeping') {
     					$bookkeeping->fk_doc = $key;
     					$bookkeeping->fk_docdet = $val["fk_bank"];
     					$bookkeeping->numero_compte = $k;
    -					$bookkeeping->label_compte = $langs->trans("Bank");
    +
    +					$accountingaccount->fetch(null, $k, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
    +					$bookkeeping->label_operation = $reflabel;
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
     					$bookkeeping->debit = ($mt >= 0 ? $mt : 0);
    @@ -515,6 +525,7 @@ if (! $error && $action == 'writebookkeeping') {
     						$bookkeeping->doc_type = 'bank';
     						$bookkeeping->fk_doc = $key;
     						$bookkeeping->fk_docdet = $val["fk_bank"];
    +						$bookkeeping->label_operation = $reflabel;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
     						$bookkeeping->debit = ($mt < 0 ? - $mt : 0);
    @@ -528,22 +539,30 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
     							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_supplier') {		   // If payment is payment of supplier invoice, we get ref of invoice
     							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
     							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_expensereport') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_salary') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if (in_array($tabtype[$key], array('sc', 'payment_sc'))) {   // If payment is payment of social contribution
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
    @@ -553,27 +572,37 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_donation') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_loan') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_various') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'banktransfert') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else {
     							if ($tabtype[$key] == 'unknown')	// Unknown transaction, we will use a waiting account for thirdparty.
     							{
    @@ -581,7 +610,9 @@ if (! $error && $action == 'writebookkeeping') {
     								$bookkeeping->subledger_account = '';
     								$bookkeeping->subledger_label = '';
     								$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE;
    -								$bookkeeping->label_compte = '';
    +
    +								$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE, true);
    +								$bookkeeping->label_compte = $accountingaccount->label;
     							}
     						}
     						$bookkeeping->label_operation = $reflabel;
    @@ -850,7 +881,8 @@ if (empty($action) || $action == 'view') {
     	$description.= $langs->trans("DescJournalOnlyBindedVisible").'<br>';
     
     	$listofchoices=array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
    -	$period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
    +    $period = $form->selectDate($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0);
    +    $period .= ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
     
     	$varlink = 'id_journal=' . $id_journal;
     
    diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
    index 07982f107fd..9c39016f008 100644
    --- a/htdocs/accountancy/journal/expensereportsjournal.php
    +++ b/htdocs/accountancy/journal/expensereportsjournal.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger		<jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013-2017  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2013-2016  Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2013-2016  Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -60,6 +61,7 @@ if ($user->societe_id > 0)
     /*
      * Actions
      */
    +$accountingaccount = new AccountingAccount($db);
     
     // Get informations of journal
     $accountingjournalstatic = new AccountingJournal($db);
    @@ -207,8 +209,12 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->fk_doc = $key;
     					$bookkeeping->fk_docdet = $val["fk_expensereportdet"];
     					$bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
    -					$bookkeeping->subledger_label = $tabuser[$key]['user_accountancy_code'];
    +					$bookkeeping->subledger_label = $tabuser[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
    +
    +					$accountingaccount->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = $tabuser[$key]['name'];
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
    @@ -247,7 +253,6 @@ if ($action == 'writebookkeeping') {
     			foreach ( $tabht[$key] as $k => $mt ) {
     				if ($mt) {
     					// get compte id and label
    -					$accountingaccount = new AccountingAccount($db);
     					if ($accountingaccount->fetch(null, $k, true)) {
     						$bookkeeping = new BookKeeping($db);
     						$bookkeeping->doc_date = $val["date"];
    @@ -259,6 +264,7 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +						$bookkeeping->label_compte = $accountingaccount->label;
     						$bookkeeping->label_operation = $accountingaccount->label;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    @@ -315,6 +321,10 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->subledger_account = '';
     					$bookkeeping->subledger_label = '';
     					$bookkeeping->numero_compte = $k;
    +
    +					$accountingaccount->fetch($k, null, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]).' %';
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    @@ -399,11 +409,13 @@ if ($action == 'writebookkeeping') {
     		$param.='&date_endmonth='.$date_endmonth;
     		$param.='&date_endyear='.$date_endyear;
     		$param.='&in_bookkeeping='.$in_bookkeeping;
    +
     		header("Location: ".$_SERVER['PHP_SELF'].($param?'?'.$param:''));
     		exit;
     	}
     }
     
    +
     /*
      * View
      */
    @@ -534,7 +546,8 @@ if (empty($action) || $action == 'view') {
     	$description.= $langs->trans("DescJournalOnlyBindedVisible").'<br>';
     
     	$listofchoices=array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
    -	$period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
    +    $period = $form->selectDate($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0);
    +    $period .= ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
     
     	$varlink = 'id_journal=' . $id_journal;
     
    diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
    index 14501ae9b82..beb9891276f 100644
    --- a/htdocs/accountancy/journal/purchasesjournal.php
    +++ b/htdocs/accountancy/journal/purchasesjournal.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger		<jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013-2017  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2013-2016  Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2013-2016  Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -65,10 +66,7 @@ $parameters=array();
      */
     $reshook=$hookmanager->executeHooks('doActions',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
     
    -
    -/*
    - * Views
    - */
    +$accountingaccount = new AccountingAccount($db);
     
     // Get informations of journal
     $accountingjournalstatic = new AccountingJournal($db);
    @@ -309,8 +307,12 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->fk_docdet = 0;    // Useless, can be several lines that are source of this record to add
     					$bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
     					$bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur'];
    -					$bookkeeping->subledger_label = '';    // TODO To complete
    +					$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
    +
    +					$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("SubledgerAccount");
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
    @@ -351,7 +353,6 @@ if ($action == 'writebookkeeping') {
     			foreach ( $tabht[$key] as $k => $mt ) {
     				//if ($mt) {
     					// get compte id and label
    -					$accountingaccount = new AccountingAccount($db);
     					if ($accountingaccount->fetch(null, $k, true)) {
     						$bookkeeping = new BookKeeping($db);
     						$bookkeeping->doc_date = $val["date"];
    @@ -365,6 +366,7 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +						$bookkeeping->label_compte = $accountingaccount->label;
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $accountingaccount->label;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    @@ -425,6 +427,10 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +
    +						$accountingaccount->fetch($k, null, true);
    +						$bookkeeping->label_compte = $accountingaccount->label;
    +
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]) .' %' . ($numtax?' - Localtax '.$numtax:'');
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    @@ -726,7 +732,8 @@ if (empty($action) || $action == 'view') {
     	}
     
     	$listofchoices=array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
    -	$period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
    +    $period = $form->selectDate($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0);
    +    $period .= ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
     
     	$varlink = 'id_journal=' . $id_journal;
     
    diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
    index 3b63b761183..ee7d45d6c66 100644
    --- a/htdocs/accountancy/journal/sellsjournal.php
    +++ b/htdocs/accountancy/journal/sellsjournal.php
    @@ -1,13 +1,14 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger			<jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin			<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013       Christophe Battarel		<christophe.battarel@altairis.fr>
    - * Copyright (C) 2013-2017  Alexandre Spangaro		<aspangaro@zendsi.com>
    - * Copyright (C) 2013-2016  Florian Henry			<florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2016  Olivier Geffroy			<jeff@jeffinfo.com>
    - * Copyright (C) 2014       Raphaël Doursenaud		<rdoursenaud@gpcsolutions.fr>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -69,6 +70,8 @@ $parameters=array();
     
     $reshook=$hookmanager->executeHooks('doActions',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
     
    +$accountingaccount = new AccountingAccount($db);
    +
     // Get informations of journal
     $accountingjournalstatic = new AccountingJournal($db);
     $accountingjournalstatic->fetch($id_journal);
    @@ -316,8 +319,12 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->fk_docdet = 0;	// Useless, can be several lines that are source of this record to add
     					$bookkeeping->thirdparty_code = $companystatic->code_client;
     					$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
    -					$bookkeeping->subledger_label = '';    // TODO To complete
    +					$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
    +
    +					$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("SubledgerAccount");
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
    @@ -358,7 +365,6 @@ if ($action == 'writebookkeeping') {
     			foreach ( $tabht[$key] as $k => $mt ) {
     				//if ($mt) {
     					// get compte id and label
    -					$accountingaccount = new AccountingAccount($db);
     					if ($accountingaccount->fetch(null, $k, true)) {
     						$bookkeeping = new BookKeeping($db);
     						$bookkeeping->doc_date = $val["date"];
    @@ -372,6 +378,7 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +						$bookkeeping->label_compte = $accountingaccount->label;
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $accountingaccount->label;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
    @@ -431,6 +438,10 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +
    +						$accountingaccount->fetch($k, null, true);
    +						$bookkeeping->label_compte = $accountingaccount->label;
    +
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]) .' %' . ($numtax?' - Localtax '.$numtax:'');
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
    @@ -489,7 +500,6 @@ if ($action == 'writebookkeeping') {
     				break;  // Break in the foreach
     			}
     		}
    -
     	}
     
     	$tabpay = $tabfac;
    @@ -660,7 +670,8 @@ if (empty($action) || $action == 'view') {
     		$description .= $langs->trans("DepositsAreIncluded");
     
     	$listofchoices=array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
    -	$period = $form->select_date($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0, 1). ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
    +    $period = $form->selectDate($date_start?$date_start:-1, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end?$date_end:-1, 'date_end', 0, 0, 0, '', 1, 0);
    +    $period .= ' -  ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
     
     	$varlink = 'id_journal=' . $id_journal;
     
    diff --git a/htdocs/accountancy/supplier/card.php b/htdocs/accountancy/supplier/card.php
    index f126d00f2e9..439b8625342 100644
    --- a/htdocs/accountancy/supplier/card.php
    +++ b/htdocs/accountancy/supplier/card.php
    @@ -162,5 +162,6 @@ if (! empty($id)) {
     	print "Error ID incorrect";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php
    index 334fd347a58..d0ee7579f3b 100644
    --- a/htdocs/accountancy/supplier/index.php
    +++ b/htdocs/accountancy/supplier/index.php
    @@ -87,7 +87,7 @@ if ($action == 'clean' || $action == 'validatehistory')
     	if (! $resql1) {
     		$error ++;
     		$db->rollback();
    -		setEventMessage($db->lasterror(), 'errors');
    +		setEventMessages($db->lasterror(), null, 'errors');
     	} else {
     		$db->commit();
     	}
    @@ -150,7 +150,7 @@ $buttonbind = '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?year=' .
     
     
     print_barre_liste($langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1);
    -//print_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
    +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
     
     print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
    @@ -221,7 +221,7 @@ print '<br>';
     
     
     print_barre_liste($langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
    -//print_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
    +//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
     
     print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
    @@ -295,7 +295,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
         print '<br>';
     
         print_barre_liste($langs->trans("OtherInfo"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
    -    //print_fiche_titre($langs->trans("OtherInfo"), '', '');
    +    //print load_fiche_titre($langs->trans("OtherInfo"), '', '');
     
     	print '<div class="div-table-responsive-no-min">';
         print '<table class="noborder" width="100%">';
    @@ -342,6 +342,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange.
         print '</div>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php
    index ef54dec564d..580cf4c407c 100644
    --- a/htdocs/accountancy/supplier/lines.php
    +++ b/htdocs/accountancy/supplier/lines.php
    @@ -34,6 +34,7 @@ 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/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("compta","bills","other","accountancy","productbatch"));
    @@ -172,7 +173,9 @@ print '<script type="text/javascript">
     $sql = "SELECT f.rowid as facid, f.ref as ref, f.ref_supplier, f.libelle as invoice_label, f.datef, f.fk_soc,";
     $sql.= " l.rowid, l.fk_product, l.product_type as line_type, l.description, l.total_ht , l.qty, l.tva_tx, l.vat_src_code,";
     $sql.= " aa.label, aa.account_number, ";
    -$sql.= " p.rowid as product_id, p.fk_product_type as product_type, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, co.label as country, s.tva_intra";
    +$sql.= " p.rowid as product_id, p.fk_product_type as product_type, p.ref as product_ref, p.label as product_label, p.fk_product_type as type,";
    +$sql.= " co.code as country_code, co.label as country,";
    +$sql.= " s.tva_intra";
     $parameters=array();
     $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters);    // Note that $action and $object may have been modified by hook
     $sql.=$hookmanager->resPrint;
    @@ -221,7 +224,18 @@ else if ($search_year > 0)
     	$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
     }
     if (strlen(trim($search_country))) {
    -	$sql .= natural_search("co.label", $search_country);
    +	$arrayofcode = getCountriesInEEC();
    +	$country_code_in_EEC = $country_code_in_EEC_without_me = '';
    +	foreach ($arrayofcode as $key => $value)
    +	{
    +		$country_code_in_EEC.=($country_code_in_EEC ? "," : "")."'".$value."'";
    +		if ($value != $mysoc->country_code) $country_code_in_EEC_without_me.=($country_code_in_EEC_without_me ? "," : "")."'".$value."'";
    +	}
    +	if ($search_country == 'special_allnotme')     $sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
    +	elseif ($search_country == 'special_eec')      $sql .= " AND co.code IN (".$country_code_in_EEC.")";
    +	elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
    +	elseif ($search_country == 'special_noteec')   $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
    +	else $sql .= natural_search(array("co.code","co.label"), $search_country);
     }
     if (strlen(trim($search_tvaintra))) {
     	$sql .= natural_search("s.tva_intra", $search_tvaintra);
    @@ -299,9 +313,9 @@ if ($result) {
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth25" name="search_lineid" value="' . dol_escape_htmltag($search_lineid) . '""></td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="' . dol_escape_htmltag($search_invoice) . '"></td>';
     	print '<td class="liste_titre"></td>';
    -	print '<td class="liste_titre center">';
    -   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
    -   	print '<input class="flat" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
    +	print '<td class="liste_titre center nowraponall">';
    +   	if (! empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_day" value="'.$search_day.'">';
    +   	print '<input class="flat valignmiddle" type="text" size="1" maxlength="2" name="search_month" value="'.$search_month.'">';
        	$formother->select_year($search_year,'search_year',1, 20, 5);
     	print '</td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
    @@ -309,7 +323,10 @@ if ($result) {
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="right flat maxwidth50" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="right flat maxwidth50" name="search_vat" placeholder="%" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
    -	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '"></td>';
    +	print '<td class="liste_titre">';
    +	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2', 1, 0, 1);
    +	//	print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
    +	print '</td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="' . dol_escape_htmltag($search_tvaintra) . '"></td>';
     	print '<td class="liste_titre" align="center"><input type="text" class="flat maxwidth50" name="search_account" value="' . dol_escape_htmltag($search_account) . '"></td>';
     	print '<td class="liste_titre" align="center">';
    @@ -357,7 +374,7 @@ if ($result) {
     		print '<td>' . $objp->rowid . '</td>';
     
     		// Ref Invoice
    -		print '<td>' . $facturefournisseur_static->getNomUrl(1) . '</td>';
    +		print '<td class="nowraponall">' . $facturefournisseur_static->getNomUrl(1) . '</td>';
     
     		print '<td class="tdoverflowonsmartphone">';
     		print $objp->invoice_label;
    @@ -380,9 +397,11 @@ if ($result) {
     		print '</td>';
     
     		print '<td align="right">' . price($objp->total_ht) . '</td>';
    +
     		print '<td align="right">' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . '</td>';
     
    -		print '<td>' . $objp->country .'</td>';
    +		print '<td>' . $langs->trans("Country".$objp->country_code) .' ('.$objp->country_code.')</td>';
    +
     		print '<td>' . $objp->tva_intra . '</td>';
     
     		print '<td align="center">';
    @@ -406,7 +425,6 @@ if ($result) {
     	print $db->lasterror();
     }
     
    -
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php
    index 57fdf0ace48..5ac90068ffb 100644
    --- a/htdocs/accountancy/supplier/list.php
    +++ b/htdocs/accountancy/supplier/list.php
    @@ -34,6 +34,7 @@ require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php
     require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("bills","compta","accountancy","other","productbatch"));
    @@ -202,8 +203,9 @@ llxHeader('', $langs->trans("SuppliersVentilation"));
     if (empty($chartaccountcode))
     {
     	print $langs->trans("ErrorChartOfAccountSystemNotSelected");
    -	llxFooter();
    -	$db->close();
    +	// End of page
    +    llxFooter();
    +    $db->close();
     	exit;
     }
     
    @@ -212,7 +214,8 @@ $sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_lab
     $sql.= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
     $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_buy as code_buy, p.tva_tx as tva_tx_prod,";
     $sql.= " aa.rowid as aarowid,";
    -$sql.= " co.label as country, s.tva_intra";
    +$sql.= " co.code as country_code, co.label as country,";
    +$sql.= " s.tva_intra";
     $parameters=array();
     $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters);    // Note that $action and $object may have been modified by hook
     $sql.=$hookmanager->resPrint;
    @@ -249,9 +252,6 @@ if (strlen(trim($search_account))) {
     if (strlen(trim($search_vat))) {
         $sql .= natural_search("l.tva_tx", price2num($search_vat), 1);
     }
    -if (strlen(trim($search_tvaintra))) {
    -	$sql .= natural_search("s.tva_intra", $search_tvaintra);
    -}
     if ($search_month > 0)
     {
     	if ($search_year > 0 && empty($search_day))
    @@ -266,7 +266,21 @@ else if ($search_year > 0)
     	$sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'";
     }
     if (strlen(trim($search_country))) {
    -	$sql .= natural_search("co.label", $search_country);
    +	$arrayofcode = getCountriesInEEC();
    +	$country_code_in_EEC = $country_code_in_EEC_without_me = '';
    +	foreach ($arrayofcode as $key => $value)
    +	{
    +		$country_code_in_EEC.=($country_code_in_EEC ? "," : "")."'".$value."'";
    +		if ($value != $mysoc->country_code) $country_code_in_EEC_without_me.=($country_code_in_EEC_without_me ? "," : "")."'".$value."'";
    +	}
    +	if ($search_country == 'special_allnotme')     $sql .= " AND co.code <> '".$db->escape($mysoc->country_code)."'";
    +	elseif ($search_country == 'special_eec')      $sql .= " AND co.code IN (".$country_code_in_EEC.")";
    +	elseif ($search_country == 'special_eecnotme') $sql .= " AND co.code IN (".$country_code_in_EEC_without_me.")";
    +	elseif ($search_country == 'special_noteec')   $sql .= " AND co.code NOT IN (".$country_code_in_EEC.")";
    +	else $sql .= natural_search(array("co.code","co.label"), $search_country);
    +}
    +if (strlen(trim($search_tvaintra))) {
    +	$sql .= natural_search("s.tva_intra", $search_tvaintra);
     }
     if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
     	$sql .= " AND f.type IN (" . FactureFournisseur::TYPE_STANDARD . "," . FactureFournisseur::TYPE_REPLACEMENT . "," . FactureFournisseur::TYPE_CREDIT_NOTE . "," . FactureFournisseur::TYPE_SITUATION . ")";
    @@ -371,7 +385,10 @@ if ($result) {
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="right flat maxwidth50" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
     	print '<td class="liste_titre" align="right"><input type="text" class="right flat maxwidth50" name="search_vat" placeholder="%" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
    -	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '"></td>';
    +	print '<td class="liste_titre">';
    +	print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2', 1, 0, 1);
    +	//print '<input type="text" class="flat maxwidth50" name="search_country" value="' . dol_escape_htmltag($search_country) . '">';
    +	print '</td>';
     	print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_tvaintra" value="' . dol_escape_htmltag($search_tvaintra) . '"></td>';
     	print '<td class="liste_titre"></td>';
     	print '<td class="liste_titre"></td>';
    @@ -452,7 +469,7 @@ if ($result) {
     		print '<td>' . $objp->rowid . '</td>';
     
     		// Ref Invoice
    -		print '<td>' . $facturefourn_static->getNomUrl(1) . '</td>';
    +		print '<td class="nowraponall">' . $facturefourn_static->getNomUrl(1) . '</td>';
     
     		print '<td class="tdoverflowonsmartphone">';
     		print $objp->invoice_label;
    @@ -532,5 +549,6 @@ jQuery(document).ready(function() {
     });
     </script>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/accountancy/tpl/export_journal.tpl.php b/htdocs/accountancy/tpl/export_journal.tpl.php
    index 773f7a7ff68..d0d902770c0 100644
    --- a/htdocs/accountancy/tpl/export_journal.tpl.php
    +++ b/htdocs/accountancy/tpl/export_journal.tpl.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2015  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2016  Charlie Benke		<charlie@patas-monkey.com>
    +/* Copyright (C) 2015-2018  Alexandre Spangaro	<aspangaro@zendsi.com>
    + * Copyright (C) 2016       Charlie Benke		<charlie@patas-monkey.com>
      *
      * 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
    @@ -27,11 +27,40 @@ $code = $conf->global->MAIN_INFO_ACCOUNTANT_CODE;
     $prefix = $conf->global->ACCOUNTING_EXPORT_PREFIX_SPEC;
     $format = $conf->global->ACCOUNTING_EXPORT_FORMAT;
     $nodateexport = $conf->global->ACCOUNTING_EXPORT_NO_DATE_IN_FILENAME;
    +$siren = $conf->global->MAIN_INFO_SIREN;
     
     $date_export = "_" . dol_print_date(dol_now(), '%Y%m%d%H%M%S');
    +$endaccountingperiod = dol_print_date(dol_now(), '%Y%m%d');
     
     header('Content-Type: text/csv');
     
    -$completefilename = ($code?$code . "_":"") . ($prefix?$prefix . "_":"") . $filename . ($nodateexport?"":$date_export) . "." . $format;
    +
    +if ($conf->global->ACCOUNTING_EXPORT_MODELCSV == "11") // Specific filename for FEC model export
    +{
    +
    +	// FEC format is defined here: https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000027804775&cidTexte=LEGITEXT000006069583&dateTexte=20130802&oldAction=rechCodeArticle
    +	if (empty($search_date_end))
    +	{
    +		// TODO Get the max date into bookeeping table
    +		$search_date_end = dol_now();
    +	}
    +	$datetouseforfilename = $search_date_end;
    +	$tmparray=dol_getdate($datetouseforfilename);
    +	$fiscalmonth=empty($conf->global->SOCIETE_FISCAL_MONTH_START)?1:$conf->global->SOCIETE_FISCAL_MONTH_START;
    +	// Define end of month to use
    +	if ($tmparray['mon'] <= $fiscalmonth) $tmparray['mon']=$fiscalmonth;
    +	else {
    +		$tmparray['mon']  = $fiscalmonth;
    +		$tmparray['year']++;
    +	}
    +
    +	$endaccountingperiod = dol_print_date(dol_get_last_day($tmparray['year'], $tmparray['mon']), 'dayxcard');
    +
    +	$completefilename = $siren . "FEC" . $endaccountingperiod . "." . $format;
    +}
    +else
    +{
    +	$completefilename = ($code?$code . "_":"") . ($prefix?$prefix . "_":"") . $filename . ($nodateexport?"":$date_export) . "." . $format;
    +}
     
     header('Content-Disposition: attachment;filename=' . $completefilename);
    diff --git a/htdocs/adherents/admin/adherent.php b/htdocs/adherents/admin/adherent.php
    index 4511ee0e8a7..ba43b6d47a6 100644
    --- a/htdocs/adherents/admin/adherent.php
    +++ b/htdocs/adherents/admin/adherent.php
    @@ -33,8 +33,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     
    -$langs->load("admin");
    -$langs->load("members");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","members"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -265,7 +265,6 @@ form_constantes($constantes, 0, $helptext);
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/admin/adherent_emails.php b/htdocs/adherents/admin/adherent_emails.php
    index 88514d83da3..60e0b2c3b48 100644
    --- a/htdocs/adherents/admin/adherent_emails.php
    +++ b/htdocs/adherents/admin/adherent_emails.php
    @@ -33,8 +33,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     
    -$langs->load("admin");
    -$langs->load("members");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","members"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -160,7 +160,6 @@ form_constantes($constantes, 0, $helptext);
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/admin/adherent_extrafields.php b/htdocs/adherents/admin/adherent_extrafields.php
    index cfdea50538f..0ec1968ab34 100644
    --- a/htdocs/adherents/admin/adherent_extrafields.php
    +++ b/htdocs/adherents/admin/adherent_extrafields.php
    @@ -28,8 +28,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
    -$langs->load("members");
    -$langs->load("admin");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","members"));
     
     $extrafields = new ExtraFields($db);
     $form = new Form($db);
    @@ -113,6 +113,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/admin/adherent_type_extrafields.php b/htdocs/adherents/admin/adherent_type_extrafields.php
    index 2c849628ab9..3a5226d00f4 100644
    --- a/htdocs/adherents/admin/adherent_type_extrafields.php
    +++ b/htdocs/adherents/admin/adherent_type_extrafields.php
    @@ -31,8 +31,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
    -$langs->load("members");
    -$langs->load("admin");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","members"));
     
     $extrafields = new ExtraFields($db);
     $form = new Form($db);
    @@ -116,6 +116,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php
    index 3f8c62eb153..91df8e59ea5 100644
    --- a/htdocs/adherents/admin/website.php
    +++ b/htdocs/adherents/admin/website.php
    @@ -19,7 +19,7 @@
      */
     
     /**
    - *     	\file       htdocs/adherents/admin/public.php
    + *     	\file       htdocs/adherents/admin/website.php
      *		\ingroup    member
      *		\brief      File of main public page for member module
      *		\author	    Laurent Destailleur
    @@ -31,8 +31,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     
    -$langs->load("members");
    -$langs->load("admin");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","members"));
     
     $action=GETPOST('action', 'alpha');
     
    @@ -241,7 +241,6 @@ if (! empty($conf->global->MEMBER_ENABLE_PUBLIC))
     	print '<a target="_blank" href="'.$urlwithroot.'/public/members/new.php'.$entity_qr.'">'.$urlwithroot.'/public/members/new.php'.$entity_qr.'</a>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php
    index 2b663ecf2bc..f22070107ca 100644
    --- a/htdocs/adherents/agenda.php
    +++ b/htdocs/adherents/agenda.php
    @@ -33,8 +33,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     
    -$langs->load("companies");
    -$langs->load("members");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members"));
     
     $id = GETPOST('id','int')?GETPOST('id','int'):GETPOST('rowid','int');
     
    @@ -175,8 +175,6 @@ if ($object->id > 0)
         }
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/canvas/actions_adherentcard_common.class.php b/htdocs/adherents/canvas/actions_adherentcard_common.class.php
    index f49d1cecb99..b84534af37a 100644
    --- a/htdocs/adherents/canvas/actions_adherentcard_common.class.php
    +++ b/htdocs/adherents/canvas/actions_adherentcard_common.class.php
    @@ -28,10 +28,10 @@
     abstract class ActionsAdherentCardCommon
     {
         /**
    -     * Database handler
    -     * @var DoliDB
    +     * @var DoliDB Database handler.
          */
    -    var $db;
    +    public $db;
    +
         var $dirmodule;
         var $targetmodule;
         var $canvas;
    @@ -41,10 +41,16 @@ abstract class ActionsAdherentCardCommon
     	var $tpl = array();
     	//! Object container
     	var $object;
    -	//! Error string
    -	var $error;
    -	//! Error array
    -	var $errors=array();
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
     
     	/**
    @@ -69,7 +75,8 @@ abstract class ActionsAdherentCardCommon
         	//}
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Set content of ->tpl array, to use into template
          *
          *  @param	string		$action    Type of action
    @@ -78,6 +85,7 @@ abstract class ActionsAdherentCardCommon
          */
         function assign_values(&$action, $id)
         {
    +        // phpcs:enable
             global $conf, $langs, $user, $canvas;
             global $form, $formcompany, $objsoc;
     
    @@ -226,6 +234,7 @@ abstract class ActionsAdherentCardCommon
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          *  Assign POST values into object
          *
    @@ -233,6 +242,7 @@ abstract class ActionsAdherentCardCommon
          */
         private function assign_post()
         {
    +        // phpcs:enable
             global $langs, $mysoc;
     
             $this->object->old_name 			= 	$_POST["old_name"];
    @@ -271,5 +281,4 @@ abstract class ActionsAdherentCardCommon
                 }
             }
         }
    -
     }
    diff --git a/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php b/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php
    index 451f46f899f..c841f83b297 100644
    --- a/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php
    +++ b/htdocs/adherents/canvas/default/actions_adherentcard_default.class.php
    @@ -1,7 +1,7 @@
     <?php
     /* Copyright (C) 2010-2012	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2011		Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2012       Philippe Grand      <philippe.grand@atoo-net.com>
    + * Copyright (C) 2012-2018  Philippe Grand      <philippe.grand@atoo-net.com>
      *
      * 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
    @@ -20,20 +20,20 @@
     /**
      *	\file       htdocs/adherents/canvas/default/actions_adherentcard_default.class.php
      *	\ingroup    member
    - *	\brief      Fichier de la classe Thirdparty adherent card controller (default canvas)
    + *	\brief      File of class Thirdparty member card controller (default canvas)
      */
     include_once DOL_DOCUMENT_ROOT.'/adherents/canvas/actions_adherentcard_common.class.php';
     
     /**
      *	\class      ActionsAdherentCardDefault
    - *	\brief      Classe permettant la gestion des adherents par defaut
    + *	\brief      Class allowing the management of the members by default
      */
     class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
     {
     	/**
          *	Constructor
          *
    -     *	@param	DoliDB	$db				Handler acces base de donnees
    +     *	@param	DoliDB	$db				Handler acces data base
          *	@param	string	$dirmodule		Name of directory of module
          *	@param	string	$targetmodule	Name of directory of module where canvas is stored
          *	@param	string	$canvas			Name of canvas
    @@ -51,7 +51,7 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
     	/**
     	 * 	Return the title of card
     	 *
    -	 * 	@param	string	$action		Code action
    +	 * 	@param	string	$action		Action code
     	 * 	@return	string				Title
     	 */
     	private function getTitle($action)
    @@ -67,6 +67,7 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Assign custom values for canvas
     	 *
    @@ -76,6 +77,7 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
     	 */
     	function assign_values(&$action, $id)
     	{
    +        // phpcs:enable
     		global $limit, $offset, $sortfield, $sortorder;
     		global $conf, $db, $langs, $user;
     		global $form;
    @@ -117,10 +119,10 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
     		{
     	        $this->LoadListDatas($limit, $offset, $sortfield, $sortorder);
     		}
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Fetch datas list and save into ->list_datas
     	 *
    @@ -132,6 +134,7 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
     	 */
     	function LoadListDatas($limit, $offset, $sortfield, $sortorder)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
             //$this->getFieldList();
    @@ -139,4 +142,3 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
             $this->list_datas = array();
     	}
     }
    -
    diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
    index a3df6705df9..e7b36b77ad9 100644
    --- a/htdocs/adherents/card.php
    +++ b/htdocs/adherents/card.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
    - * Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2018 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2012      Marcos García        <marcosgdf@gmail.com>
    - * Copyright (C) 2012-2018 Philippe Grand       <philippe.grand@atoo-net.com>
    - * Copyright (C) 2015-2016 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
    +/* Copyright (C) 2001-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
    + * Copyright (C) 2004-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2018  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2012-2018  Philippe Grand          <philippe.grand@atoo-net.com>
    + * Copyright (C) 2015-2016  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -300,6 +301,8 @@ if (empty($reshook))
     			$object->phone_mobile= trim(GETPOST("phone_mobile",'alpha'));
     			$object->email       = preg_replace('/\s+/', '', GETPOST("member_email",'alpha'));
     			$object->skype       = trim(GETPOST("skype",'alpha'));
    +			$object->twitter     = trim(GETPOST("twitter",'alpha'));
    +			$object->facebook    = trim(GETPOST("facebook",'alpha'));
     			$object->birth       = $birthdate;
     
     			$object->typeid      = GETPOST("typeid",'int');
    @@ -442,6 +445,8 @@ if (empty($reshook))
     		$phone_perso=GETPOST("phone_perso",'alpha');
     		$phone_mobile=GETPOST("phone_mobile",'alpha');
     		$skype=GETPOST("member_skype",'alpha');
    +		$twitter=GETPOST("member_twitter",'alpha');
    +		$facebook=GETPOST("member_facebook",'alpha');
     		$email=preg_replace('/\s+/', '', GETPOST("member_email",'alpha'));
     		$login=GETPOST("member_login",'alpha');
     		$pass=GETPOST("password",'alpha');
    @@ -466,7 +471,11 @@ if (empty($reshook))
     		$object->phone       = $phone;
     		$object->phone_perso = $phone_perso;
     		$object->phone_mobile= $phone_mobile;
    +
     		$object->skype       = $skype;
    +		$object->twitter     = $twitter;
    +		$object->facebook    = $facebook;
    +
     		$object->email       = $email;
     		$object->login       = $login;
     		$object->pass        = $pass;
    @@ -621,8 +630,9 @@ if (empty($reshook))
     				// Set output language
     				$outputlangs = new Translate('', $conf);
     				$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +				// Load traductions files requiredby by page
     				$outputlangs->loadLangs(array("main", "members"));
    -				// Get email content fro mtemplae
    +				// Get email content from template
     				$arraydefaultmessage=null;
     				$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_MEMBER_VALIDATION;
     
    @@ -694,8 +704,9 @@ if (empty($reshook))
     					// Set output language
     					$outputlangs = new Translate('', $conf);
     					$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +					// Load traductions files requiredby by page
     					$outputlangs->loadLangs(array("main", "members"));
    -					// Get email content fro mtemplae
    +					// Get email content from template
     					$arraydefaultmessage=null;
     					$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_CANCELATION;
     
    @@ -778,7 +789,6 @@ if (empty($reshook))
     	$mode='emailfrommember';
     	$trackid='mem'.$object->id;
     	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
    -
     }
     
     
    @@ -977,14 +987,26 @@ else
     		print '<tr><td>'.$langs->trans("PhoneMobile").'</td><td><input type="text" name="phone_mobile" size="20" value="'.(GETPOST('phone_mobile','alpha')?GETPOST('phone_mobile','alpha'):$object->phone_mobile).'"></td></tr>';
     
     	    // Skype
    -	    if (! empty($conf->skype->enabled))
    +	    if (! empty($conf->socialnetworks->enabled))
     	    {
     			print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="member_skype" size="40" value="'.(GETPOST('member_skype','alpha')?GETPOST('member_skype','alpha'):$object->skype).'"></td></tr>';
     	    }
     
    -		// Birthday
    +	    // Twitter
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Twitter").'</td><td><input type="text" name="member_twitter" size="40" value="'.(GETPOST('member_twitter','alpha')?GETPOST('member_twitter','alpha'):$object->twitter).'"></td></tr>';
    +	    }
    +
    +	    // Facebook
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Facebook").'</td><td><input type="text" name="member_facebook" size="40" value="'.(GETPOST('member_facebook','alpha')?GETPOST('member_facebook','alpha'):$object->facebook).'"></td></tr>';
    +	    }
    +
    +	    // Birthday
     		print "<tr><td>".$langs->trans("Birthday")."</td><td>\n";
    -		$form->select_date(($object->birth ? $object->birth : -1),'birth','','',1,'formsoc');
    +		print $form->selectDate(($object->birth ? $object->birth : -1),'birth','','',1,'formsoc');
     		print "</td></tr>\n";
     
     		// Public profil
    @@ -1215,14 +1237,26 @@ else
     		print '<tr><td>'.$langs->trans("PhoneMobile").'</td><td><input type="text" name="phone_mobile" size="20" value="'.(isset($_POST["phone_mobile"])?GETPOST("phone_mobile"):$object->phone_mobile).'"></td></tr>';
     
     	    // Skype
    -	    if (! empty($conf->skype->enabled))
    +	    if (! empty($conf->socialnetworks->enabled))
     	    {
    -			    print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" class="minwidth100" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
    +			print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" class="minwidth100" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
     	    }
     
    -		// Birthday
    +	    // Twitter
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Twitter").'</td><td><input type="text" name="twitter" class="minwidth100" value="'.(isset($_POST["twitter"])?GETPOST("twitter"):$object->twitter).'"></td></tr>';
    +	    }
    +
    +	    // Facebook
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Facebook").'</td><td><input type="text" name="facebook" class="minwidth100" value="'.(isset($_POST["facebook"])?GETPOST("facebook"):$object->facebook).'"></td></tr>';
    +	    }
    +
    +	    // Birthday
     		print "<tr><td>".$langs->trans("Birthday")."</td><td>\n";
    -		$form->select_date(($object->birth ? $object->birth : -1),'birth','','',1,'formsoc');
    +		print $form->selectDate(($object->birth ? $object->birth : -1),'birth','','',1,'formsoc');
     		print "</td></tr>\n";
     
     		// Public profil
    @@ -1285,7 +1319,6 @@ else
     		print '</div>';
     
     		print '</form>';
    -
     	}
     
     	if ($id > 0 && $action != 'edit')
    @@ -1387,6 +1420,7 @@ else
     			// Set output language
     			$outputlangs = new Translate('', $conf);
     			$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +			// Load traductions files requiredby by page
     			$outputlangs->loadLangs(array("main", "members"));
     			// Get email content from template
     			$arraydefaultmessage=null;
    @@ -1447,8 +1481,9 @@ else
     			// Set output language
     			$outputlangs = new Translate('', $conf);
     			$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +			// Load traductions files requiredby by page
     			$outputlangs->loadLangs(array("main", "members"));
    -			// Get email content fro mtemplae
    +			// Get email content from template
     			$arraydefaultmessage=null;
     			$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_CANCELATION;
     
    @@ -1821,7 +1856,6 @@ else
     						print '<div class="inline-block divButAction"><a class="butAction" href="card.php?rowid='.$object->id.'&action=add_spip">'.$langs->trans("AddIntoSpip")."</a></div>\n";
     					}
     				}
    -
     			}
     		}
     		print '</div>';
    @@ -1900,6 +1934,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/cartes/carte.php b/htdocs/adherents/cartes/carte.php
    index be3a13d8771..c50de6f8c81 100644
    --- a/htdocs/adherents/cartes/carte.php
    +++ b/htdocs/adherents/cartes/carte.php
    @@ -208,7 +208,6 @@ if ((! empty($foruserid) || ! empty($foruserlogin) || ! empty($mode)) && ! $mesg
                 	$mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("DescADHERENT_CARD_TYPE"));
                 }
                 if (! $mesg) $result=members_card_pdf_create($db, $arrayofmembers, $model, $outputlangs);
    -
             }
             elseif ($mode == 'label')
             {
    @@ -310,6 +309,6 @@ print '<br><input class="button" type="submit" value="'.$langs->trans("BuildDoc"
     print '</form>';
     print '<br>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
    index a5ca1691096..3df36ef3eda 100644
    --- a/htdocs/adherents/class/adherent.class.php
    +++ b/htdocs/adherents/class/adherent.class.php
    @@ -7,7 +7,7 @@
      * Copyright (C) 2009-2017	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2014-2016	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
      * Copyright (C) 2015		Marcos García			<marcosgdf@gmail.com>
    - * Copyright (C) 2015		Frederic France			<frederic.france@free.fr>
    + * Copyright (C) 2015-2018  Frédéric France			<frederic.france@netlogic.fr>
      * Copyright (C) 2015		Raphaël Doursenaud		<rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2016		Juanjo Menent			<jmenent@2byte.es>
      *
    @@ -41,72 +41,125 @@ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
      */
     class Adherent extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='member';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='adherent';
    -	public $ismultientitymanaged = 1;  // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     
    -	var $mesgs;
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
     
    -	var $login;
    +	public $mesgs;
    +
    +	public $login;
     
     	//! Clear password in memory
    -	var $pass;
    +	public $pass;
     	//! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
    -	var $pass_indatabase;
    +	public $pass_indatabase;
     	//! Encrypted password in database (always defined)
    -	var $pass_indatabase_crypted;
    +	public $pass_indatabase_crypted;
     
    -	var $societe;
    -	var $company;
    -	var $address;
    -	var $zip;
    -	var $town;
    +	public $societe;
     
    -	var $state_id;              // Id of department
    -	var $state_code;            // Code of department
    -	var $state;                 // Label of department
    +	/**
    +	 * @var Societe $company {@type Societe}
    +	 */
    +	public $company;
     
    -	var $email;
    -	var $skype;
    -	var $phone;
    -	var $phone_perso;
    -	var $phone_mobile;
    +	/**
    +	 * @var string Address
    +	 */
    +	public $address;
     
    -	var $morphy;
    -	var $public;
    -	var $statut;			// -1:brouillon, 0:resilie, >=1:valide,paye
    -	var $photo;
    +	public $zip;
    +	public $town;
     
    -	var $datec;
    -	var $datem;
    -	var $datevalid;
    -	var $birth;
    +	public $state_id;              // Id of department
    +	public $state_code;            // Code of department
    +	public $state;                 // Label of department
     
    -	var $note_public;
    -	var $note_private;
    +	public $email;
     
    -	var $typeid;			// Id type adherent
    -	var $type;				// Libelle type adherent
    -	var $need_subscription;
    +	public $skype;
    +	public $twitter;
    +	public $facebook;
     
    -	var $user_id;
    -	var $user_login;
    +    /**
    +     * @var string Phone number
    +     */
    +	public $phone;
     
    -	var $fk_soc;
    +    /**
    +     * @var string Private Phone number
    +     */
    +	public $phone_perso;
     
    -	var $datefin;	// From member table
    +    /**
    +     * @var string Mobile phone number
    +     */
    +	public $phone_mobile;
    +
    +    /**
    +     * @var string Fax number
    +     */
    +    public $fax;
    +
    +    /**
    +     * @var string Function
    +     */
    +    public $poste;
    +
    +	public $morphy;
    +	public $public;
    +	public $statut;			// -1:brouillon, 0:resilie, >=1:valide,paye
    +	public $photo;
    +
    +	public $datec;
    +	public $datem;
    +	public $datevalid;
    +
    +	public $birth;
    +
    +	public $note_public;
    +	public $note_private;
    +
    +	public $typeid;			// Id type adherent
    +	public $type;				// Libelle type adherent
    +	public $need_subscription;
    +
    +	public $user_id;
    +	public $user_login;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +    public $fk_soc;
    +
    +	public $datefin;	// From member table
     
     	// Fields loaded by fetch_subscriptions()
    -	var $first_subscription_date;
    -	var $first_subscription_amount;
    -	var $last_subscription_date;
    -	var $last_subscription_date_start;
    -	var $last_subscription_date_end;
    -	var $last_subscription_amount;
    -	var $subscriptions=array();
    +	public $first_subscription_date;
    +	public $first_subscription_amount;
    +	public $last_subscription_date;
    +	public $last_subscription_date_start;
    +	public $last_subscription_date_end;
    +	public $last_subscription_amount;
    +	public $subscriptions=array();
     
    -	var $oldcopy;		// To contains a clone of this when we need to save old properties of object
    +	public $oldcopy;		// To contains a clone of this when we need to save old properties of object
     
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
     
     	/**
    @@ -125,6 +178,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Function sending an email to the current member with the text supplied in parameter.
     	 *
    @@ -143,6 +197,7 @@ class Adherent extends CommonObject
     	 */
     	function send_an_email($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='', $moreinheader='')
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		// Detect if message is HTML
    @@ -438,6 +493,8 @@ class Adherent extends CommonObject
     		$sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null");
     		$sql.= ", email = '".$this->db->escape($this->email)."'";
     		$sql.= ", skype = '".$this->db->escape($this->skype)."'";
    +		$sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
    +		$sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
     		$sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null");
     		$sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
     		$sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
    @@ -544,6 +601,8 @@ class Adherent extends CommonObject
     
     						$luser->email=$this->email;
     						$luser->skype=$this->skype;
    +						$luser->twitter=$this->twitter;
    +						$luser->facebook=$this->facebook;
     						$luser->office_phone=$this->phone;
     						$luser->user_mobile=$this->phone_mobile;
     
    @@ -583,6 +642,8 @@ class Adherent extends CommonObject
     						$lthirdparty->town=$this->town;
     						$lthirdparty->email=$this->email;
     						$lthirdparty->skype=$this->skype;
    +						$lthirdparty->twitter=$this->twitter;
    +						$lthirdparty->facebook=$this->facebook;
     						$lthirdparty->phone=$this->phone;
     						$lthirdparty->state_id=$this->state_id;
     						$lthirdparty->country_id=$this->country_id;
    @@ -633,6 +694,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Update denormalized last subscription date.
     	 * 	This function is called when we delete a subscription for example.
    @@ -642,6 +704,7 @@ class Adherent extends CommonObject
     	 */
     	function update_end_date($user)
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		// Search for last subscription id and end date
    @@ -686,7 +749,6 @@ class Adherent extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -988,6 +1050,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Method to load member from its login
     	 *
    @@ -996,6 +1059,7 @@ class Adherent extends CommonObject
     	 */
     	function fetch_login($login)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
    @@ -1017,6 +1081,7 @@ class Adherent extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Method to load member from its name
     	 *
    @@ -1026,6 +1091,7 @@ class Adherent extends CommonObject
     	 */
     	function fetch_name($firstname,$lastname)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
    @@ -1065,7 +1131,7 @@ class Adherent extends CommonObject
     
     		$sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
     		$sql.= " d.note_public,";
    -		$sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
    +		$sql.= " d.email, d.skype, d.twitter, d.facebook, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
     		$sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
     		$sql.= " d.datec as datec,";
     		$sql.= " d.tms as datem,";
    @@ -1137,7 +1203,10 @@ class Adherent extends CommonObject
     				$this->phone_perso		= $obj->phone_perso;
     				$this->phone_mobile		= $obj->phone_mobile;
     				$this->email			= $obj->email;
    +
     				$this->skype			= $obj->skype;
    +				$this->twitter			= $obj->twitter;
    +				$this->facebook			= $obj->facebook;
     
     				$this->photo			= $obj->photo;
     				$this->statut			= $obj->statut;
    @@ -1188,6 +1257,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to get member subscriptions data
     	 *				first_subscription_date, first_subscription_date_start, first_subscription_date_end, first_subscription_amount
    @@ -1197,6 +1267,7 @@ class Adherent extends CommonObject
     	 */
     	function fetch_subscriptions()
     	{
    +        // phpcs:enable
     		global $langs;
     
     		require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
    @@ -1744,6 +1815,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Function to add member into external tools mailing-list, spip, etc.
     	 *
    @@ -1751,6 +1823,7 @@ class Adherent extends CommonObject
     	 */
     	function add_to_abo()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
    @@ -1801,6 +1874,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Function to delete a member from external tools like mailing-list, spip, etc.
     	 *
    @@ -1808,6 +1882,7 @@ class Adherent extends CommonObject
     	 */
     	function del_to_abo()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
    @@ -1980,6 +2055,7 @@ class Adherent extends CommonObject
     		return $this->LibStatut($this->statut,$this->need_subscription,$this->datefin,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -1991,79 +2067,73 @@ class Adherent extends CommonObject
     	 */
     	function LibStatut($statut,$need_subscription,$date_end_subscription,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load("members");
     		if ($mode == 0)
     		{
     			if ($statut == -1) return $langs->trans("MemberStatusDraft");
    -			if ($statut >= 1)
    -			{
    +			elseif ($statut >= 1) {
     				if (! $date_end_subscription)            return $langs->trans("MemberStatusActive");
     				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate");
     				else                                     return $langs->trans("MemberStatusPaid");
     			}
    -			if ($statut == 0)  return $langs->trans("MemberStatusResiliated");
    +			elseif ($statut == 0)  return $langs->trans("MemberStatusResiliated");
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut == -1) return $langs->trans("MemberStatusDraftShort");
    -			if ($statut >= 1)
    -			{
    +			elseif ($statut >= 1) {
     				if (! $date_end_subscription)            return $langs->trans("MemberStatusActiveShort");
     				elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort");
     				else                                     return $langs->trans("MemberStatusPaidShort");
     			}
    -			if ($statut == 0)  return $langs->trans("MemberStatusResiliatedShort");
    +			elseif ($statut == 0)  return $langs->trans("MemberStatusResiliatedShort");
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraftShort");
    -			if ($statut >= 1)
    -			{
    +			elseif ($statut >= 1) {
     				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActiveShort");
     				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLateShort");
     				else                                     return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaidShort");
     			}
    -			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort");
    +			elseif ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort");
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0');
    -			if ($statut >= 1)
    -			{
    +			elseif ($statut >= 1) {
     				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'),'statut1');
     				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
     				else                                     return img_picto($langs->trans('MemberStatusPaid'),'statut4');
     			}
    -			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5');
    +			elseif ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraft");
    -			if ($statut >= 1)
    -			{
    +			elseif ($statut >= 1) {
     				if (! $date_end_subscription)            return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActive");
     				elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLate");
     				else                                     return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaid");
     			}
     			if ($statut == 0)  return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliated");
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
    -			if ($statut >= 1)
    -			{
    +			elseif ($statut >= 1) {
     				if (! $date_end_subscription)            return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
     				elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
     				else                                     return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
     			}
     			if ($statut == 0)  return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
    -			if ($statut >= 1)
    -			{
    +			if ($statut >= 1) {
     				if (! $date_end_subscription)            return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActive").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
     				elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLate").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
     				else                                     return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaid").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
    @@ -2073,6 +2143,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb de tableau de bord
     	 *
    @@ -2080,9 +2151,10 @@ class Adherent extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf;
     
    -		$this->nb=array();
    +		$this->nb = array();
     
     		$sql = "SELECT count(a.rowid) as nb";
     		$sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
    @@ -2105,9 +2177,9 @@ class Adherent extends CommonObject
     			$this->error=$this->db->error();
     			return -1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -2116,6 +2188,7 @@ class Adherent extends CommonObject
     	 */
     	function load_board($user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
    @@ -2226,7 +2299,9 @@ class Adherent extends CommonObject
     		$this->country = 'France';
     		$this->morphy = 1;
     		$this->email = 'specimen@specimen.com';
    -		$this->skype = 'tom.hanson';
    +		$this->skype = 'skypepseudo';
    +		$this->twitter = 'twitterpseudo';
    +		$this->facebook = 'facebookpseudo';
     		$this->phone        = '0999999999';
     		$this->phone_perso  = '0999999998';
     		$this->phone_mobile = '0999999997';
    @@ -2255,6 +2330,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
     	 *
    @@ -2266,6 +2342,7 @@ class Adherent extends CommonObject
     	 */
     	function _load_ldap_dn($info,$mode=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$dn='';
     		if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN;
    @@ -2275,6 +2352,7 @@ class Adherent extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Initialise tableau info (tableau des attributs LDAP)
     	 *
    @@ -2282,6 +2360,7 @@ class Adherent extends CommonObject
     	 */
     	function _load_ldap_info()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$info=array();
    @@ -2329,6 +2408,8 @@ class Adherent extends CommonObject
     		if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN))						$info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town;
     		if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY))			$info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code;
     		if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE))					$info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype;
    +		if ($this->twitter && ! empty($conf->global->LDAP_MEMBER_FIELD_TWITTER))				$info[$conf->global->LDAP_MEMBER_FIELD_TWITTER] = $this->twitter;
    +		if ($this->facebook && ! empty($conf->global->LDAP_MEMBER_FIELD_FACEBOOK))				$info[$conf->global->LDAP_MEMBER_FIELD_FACEBOOK] = $this->facebook;
     		if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE))					$info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone;
     		if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO))		$info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso;
     		if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE))			$info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile;
    @@ -2428,7 +2509,6 @@ class Adherent extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -2472,6 +2552,7 @@ class Adherent extends CommonObject
     	 * Existing categories are left untouch.
     	 *
     	 * @param int[]|int $categories Category or categories IDs
    +     * @return void
     	 */
     	public function setCategories($categories)
     	{
    @@ -2656,7 +2737,6 @@ class Adherent extends CommonObject
     								$nbok++;
     
     								// TODO Add event email sent for member
    -
     							}
     						}
     						else
    @@ -2691,5 +2771,4 @@ class Adherent extends CommonObject
     
     		return 0;
     	}
    -
     }
    diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php
    index ca8372c04ed..20a85c7bf3e 100644
    --- a/htdocs/adherents/class/adherent_type.class.php
    +++ b/htdocs/adherents/class/adherent_type.class.php
    @@ -32,10 +32,26 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class AdherentType extends CommonObject
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element = 'adherent_type';
    +
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element = 'adherent_type';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'group';
    -	public $ismultientitymanaged = 1;  // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
     
     	/**
     	 * @var string
    @@ -43,19 +59,27 @@ class AdherentType extends CommonObject
     	 * @see label
     	 */
     	public $libelle;
    -	/** @var string Label */
    -	public $label;
    +
    +	/**
    +     * @var string Adherent type label
    +     */
    +    public $label;
    +
     	/**
     	 * @var int Subsription required (0 or 1)
     	 * @since 5.0
     	 */
     	public $subscription;
    +
     	/** @var string 	Public note */
     	public $note;
    +
     	/** @var integer	Can vote */
     	public $vote;
    +
     	/** @var string Email sent during validation */
     	public $mail_valid;
    +
     	/** @var array Array of members */
     	public $members=array();
     
    @@ -282,6 +306,7 @@ class AdherentType extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of members' type
     	 *
    @@ -289,6 +314,7 @@ class AdherentType extends CommonObject
     	 */
     	function liste_array()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$adherenttypes = array();
    @@ -413,6 +439,7 @@ class AdherentType extends CommonObject
     		return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
     	 *
    @@ -424,6 +451,7 @@ class AdherentType extends CommonObject
     	 */
     	function _load_ldap_dn($info,$mode=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$dn='';
     		if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS_TYPES."=".$info[$conf->global->LDAP_KEY_MEMBERS_TYPES].",".$conf->global->LDAP_MEMBER_TYPE_DN;
    @@ -433,6 +461,7 @@ class AdherentType extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Initialize the info array (array of LDAP values) that will be used to call LDAP functions
     	 *
    @@ -440,6 +469,7 @@ class AdherentType extends CommonObject
     	 */
     	function _load_ldap_info()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$info=array();
    @@ -547,5 +577,4 @@ class AdherentType extends CommonObject
     
     		return '';
     	}
    -
     }
    diff --git a/htdocs/adherents/class/adherentstats.class.php b/htdocs/adherents/class/adherentstats.class.php
    index 59c51cb1d21..eb722b987a9 100644
    --- a/htdocs/adherents/class/adherentstats.class.php
    +++ b/htdocs/adherents/class/adherentstats.class.php
    @@ -32,6 +32,9 @@ include_once DOL_DOCUMENT_ROOT . '/adherents/class/subscription.class.php';
      */
     class AdherentStats extends Stats
     {
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element;
     
         var $socid;
    @@ -178,5 +181,4 @@ class AdherentStats extends Stats
     
     		return $this->_getAllByYear($sql);
     	}
    -
     }
    diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php
    index 217ab47c0ab..8591dd13195 100644
    --- a/htdocs/adherents/class/api_members.class.php
    +++ b/htdocs/adherents/class/api_members.class.php
    @@ -91,7 +91,8 @@ class Members extends DolibarrApi
          *
          * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $typeid = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $typeid = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -293,7 +294,8 @@ class Members extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -407,5 +409,4 @@ class Members extends DolibarrApi
     
     		return $result;
     	}
    -
     }
    diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php
    index 1a8e93e0609..ecf7f45d371 100644
    --- a/htdocs/adherents/class/api_memberstypes.class.php
    +++ b/htdocs/adherents/class/api_memberstypes.class.php
    @@ -31,7 +31,7 @@ class MembersTypes extends DolibarrApi
          * @var array   $FIELDS     Mandatory fields, checked when create and update object
          */
         static $FIELDS = array(
    -        'label'
    +        'label',
         );
     
         /**
    @@ -86,7 +86,8 @@ class MembersTypes extends DolibarrApi
          *
          * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -271,7 +272,8 @@ class MembersTypes extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -318,5 +320,4 @@ class MembersTypes extends DolibarrApi
     
             return $object;
         }
    -
     }
    diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php
    index 3ae4f6f39d5..ed403167dd4 100644
    --- a/htdocs/adherents/class/api_subscriptions.class.php
    +++ b/htdocs/adherents/class/api_subscriptions.class.php
    @@ -34,7 +34,7 @@ class Subscriptions extends DolibarrApi
             'fk_adherent',
             'dateh',
             'datef',
    -        'amount'
    +        'amount',
         );
     
         /**
    @@ -85,7 +85,8 @@ class Subscriptions extends DolibarrApi
          *
          * @throws RestException
          */
    -    function index($sortfield = "dateadh", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
    +    function index($sortfield = "dateadh", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php
    index 1c4007780b9..7b8f453c94c 100644
    --- a/htdocs/adherents/class/subscription.class.php
    +++ b/htdocs/adherents/class/subscription.class.php
    @@ -32,17 +32,37 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class Subscription extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='subscription';
    -	public $table_element='subscription';
    -    public $picto='payment';
     
    -	var $datec;				// Date creation
    -	var $datem;				// Date modification
    -	var $dateh;				// Subscription start date (date subscription)
    -	var $datef;				// Subscription end date
    -	var $fk_adherent;
    -	var $amount;
    -	var $fk_bank;
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='subscription';
    +
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto='payment';
    +
    +	public $datec;				// Date creation
    +	public $datem;				// Date modification
    +	public $dateh;				// Subscription start date (date subscription)
    +	public $datef;				// Subscription end date
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_adherent;
    +
    +	public $amount;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_bank;
     
     
     	/**
    @@ -355,6 +375,7 @@ class Subscription extends CommonObject
     	    return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -363,6 +384,7 @@ class Subscription extends CommonObject
     	 */
     	function LibStatut($statut)
     	{
    +        // phpcs:enable
     	    global $langs;
     	    $langs->load("members");
     	    return '';
    @@ -394,7 +416,6 @@ class Subscription extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php
    index 8e12dec056e..7e46b7864f8 100644
    --- a/htdocs/adherents/document.php
    +++ b/htdocs/adherents/document.php
    @@ -33,9 +33,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     
    -$langs->load("members");
    -$langs->load("companies");
    -$langs->load('other');
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members","other"));
    +
     
     $id=GETPOST('id','int');
     $action=GETPOST('action','alpha');
    @@ -91,7 +91,7 @@ if ($id > 0)
     	if ($result > 0)
     	{
     
    -		// Construit liste des fichiers
    +		// Build file list
     		$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     		$totalsize=0;
     		foreach($filearray as $key => $file)
    @@ -170,6 +170,6 @@ else
     	print $langs->trans("ErrorRecordNotFound");
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/htpasswd.php b/htdocs/adherents/htpasswd.php
    index 5814ed3bf70..adc3d32eea4 100644
    --- a/htdocs/adherents/htpasswd.php
    +++ b/htdocs/adherents/htpasswd.php
    @@ -86,7 +86,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php
    index c9e3d1936c6..931e9323904 100644
    --- a/htdocs/adherents/index.php
    +++ b/htdocs/adherents/index.php
    @@ -29,8 +29,8 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
     
    -$langs->load("companies");
    -$langs->load("members");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members"));
     
     // Security check
     $result=restrictedArea($user,'adherent');
    @@ -435,6 +435,6 @@ print "</div>";
     
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/ldap.php b/htdocs/adherents/ldap.php
    index 1f9f348d564..5b830623a4b 100644
    --- a/htdocs/adherents/ldap.php
    +++ b/htdocs/adherents/ldap.php
    @@ -29,10 +29,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     
    -$langs->load("companies");
    -$langs->load("members");
    -$langs->load("ldap");
    -$langs->load("admin");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members","ldap","admin"));
     
     $rowid = GETPOST('id','int');
     $action = GETPOST('action','aZ09');
    @@ -221,5 +219,6 @@ else
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php
    index 3a1dd04443f..51e1a8b244e 100644
    --- a/htdocs/adherents/list.php
    +++ b/htdocs/adherents/list.php
    @@ -48,6 +48,7 @@ $search=GETPOST("search",'alpha');
     $search_ref=GETPOST("search_ref",'alpha');
     $search_lastname=GETPOST("search_lastname",'alpha');
     $search_firstname=GETPOST("search_firstname",'alpha');
    +$search_civility=GETPOST("search_civility",'alpha');
     $search_login=GETPOST("search_login",'alpha');
     $search_address=GETPOST("search_address",'alpha');
     $search_zip=GETPOST("search_zip",'alpha');
    @@ -105,6 +106,7 @@ $fieldstosearchall = array(
     if($db->type == 'pgsql') unset($fieldstosearchall['d.rowid']);
     $arrayfields=array(
     	'd.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
    +	'd.civility'=>array('label'=>$langs->trans("Civility"), 'checked'=>0),
     	'd.lastname'=>array('label'=>$langs->trans("Lastname"), 'checked'=>1),
     	'd.firstname'=>array('label'=>$langs->trans("Firstname"), 'checked'=>1),
     	'd.company'=>array('label'=>$langs->trans("Company"), 'checked'=>1),
    @@ -121,7 +123,7 @@ $arrayfields=array(
     	'state.nom'=>array('label'=>$langs->trans("State"), 'checked'=>0),
     	'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0),
     	/*'d.note_public'=>array('label'=>$langs->trans("NotePublic"), 'checked'=>0),
    -    'd.note_private'=>array('label'=>$langs->trans("NotePrivate"), 'checked'=>0),*/
    +	'd.note_private'=>array('label'=>$langs->trans("NotePrivate"), 'checked'=>0),*/
     	'd.datefin'=>array('label'=>$langs->trans("EndSubscription"), 'checked'=>1, 'position'=>500),
     	'd.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
     	'd.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
    @@ -160,6 +162,7 @@ if (empty($reshook))
     		$search_ref="";
     		$search_lastname="";
     		$search_firstname="";
    +		$search_civility="";
     		$search_login="";
     		$search_company="";
     		$search_type="";
    @@ -203,7 +206,7 @@ $memberstatic=new Adherent($db);
     $now=dol_now();
     
     $sql = "SELECT d.rowid, d.login, d.lastname, d.firstname, d.societe as company, d.fk_soc,";
    -$sql.= " d.datefin, d.address, d.zip, d.town, d.state_id, d.country,";
    +$sql.= " d.civility, d.datefin, d.address, d.zip, d.town, d.state_id, d.country,";
     $sql.= " d.email, d.phone, d.phone_perso, d.phone_mobile, d.skype, d.birth, d.public, d.photo,";
     $sql.= " d.fk_adherent_type as type_id, d.morphy, d.statut, d.datec as date_creation, d.tms as date_update,";
     $sql.= " t.libelle as type, t.subscription,";
    @@ -234,6 +237,7 @@ if ($search_ref)
     	if (is_numeric($search_ref)) $sql.= " AND (d.rowid = ".$db->escape($search_ref).")";
     	else $sql.=" AND 1 = 2";    // Always wrong
     }
    +if ($search_civility) $sql.= natural_search("d.civility", $search_civility);
     if ($search_firstname) $sql.= natural_search("d.firstname", $search_firstname);
     if ($search_lastname) $sql.= natural_search(array("d.firstname", "d.lastname", "d.societe"), $search_lastname);
     if ($search_login) $sql.= natural_search("d.login", $search_login);
    @@ -322,6 +326,7 @@ if ($sall != "") $param.="&sall=".urlencode($sall);
     if ($statut != "") $param.="&statut=".urlencode($statut);
     if ($search_ref)   $param.="&search_ref=".urlencode($search_ref);
     if ($search_nom)   $param.="&search_nom=".urlencode($search_nom);
    +if ($search_civility) $param.="&search_civility=".urlencode($search_civility);
     if ($search_firstname) $param.="&search_firstname=".urlencode($search_firstname);
     if ($search_lastname)  $param.="&search_lastname=".urlencode($search_lastname);
     if ($search_login)   $param.="&search_login=".urlencode($search_login);
    @@ -427,37 +432,36 @@ if (! empty($arrayfields['d.ref']['checked']))
     	print '<input class="flat maxwidth50" type="text" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
     	print '</td>';
     }
    -
    +if (! empty($arrayfields['d.civility']['checked']))
    +{
    +	print '<td class="liste_titre" align="left">';
    +	print '<input class="flat maxwidth25" type="text" name="search_civility" value="'.dol_escape_htmltag($search_civility).'"></td>';
    +}
     if (! empty($arrayfields['d.firstname']['checked']))
     {
     	print '<td class="liste_titre" align="left">';
     	print '<input class="flat maxwidth50" type="text" name="search_firstname" value="'.dol_escape_htmltag($search_firstname).'"></td>';
     }
    -
     if (! empty($arrayfields['d.lastname']['checked']))
     {
     	print '<td class="liste_titre" align="left">';
     	print '<input class="flat maxwidth50" type="text" name="search_lastname" value="'.dol_escape_htmltag($search_lastname).'"></td>';
     }
    -
     if (! empty($arrayfields['d.company']['checked']))
     {
     	print '<td class="liste_titre" align="left">';
     	print '<input class="flat maxwidth50" type="text" name="search_company" value="'.dol_escape_htmltag($search_company).'"></td>';
     }
    -
     if (! empty($arrayfields['d.login']['checked']))
     {
     	print '<td class="liste_titre" align="left">';
     	print '<input class="flat maxwidth50" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'"></td>';
     }
    -
     if (! empty($arrayfields['d.morphy']['checked']))
     {
     	print '<td class="liste_titre" align="left">';
     	print '</td>';
     }
    -
     if (! empty($arrayfields['t.libelle']['checked']))
     {
     	print '<td class="liste_titre">';
    @@ -568,6 +572,7 @@ print "</tr>\n";
     print '<tr class="liste_titre">';
     if (! empty($conf->global->MAIN_SHOW_TECHNICAL_ID))       print_liste_field_titre("ID",$_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder);
     if (! empty($arrayfields['d.ref']['checked']))            print_liste_field_titre($arrayfields['d.ref']['label'],$_SERVER["PHP_SELF"],'d.rowid','',$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['d.civility']['checked']))       print_liste_field_titre($arrayfields['d.civility']['label'],$_SERVER["PHP_SELF"],'d.civility','',$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['d.firstname']['checked']))      print_liste_field_titre($arrayfields['d.firstname']['label'],$_SERVER["PHP_SELF"],'d.firstname','',$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['d.lastname']['checked']))       print_liste_field_titre($arrayfields['d.lastname']['label'],$_SERVER["PHP_SELF"],'d.lastname','',$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['d.company']['checked']))        print_liste_field_titre($arrayfields['d.company']['label'],$_SERVER["PHP_SELF"],'d.societe','',$param,'',$sortfield,$sortorder);
    @@ -577,7 +582,7 @@ if (! empty($arrayfields['t.libelle']['checked']))        print_liste_field_titr
     if (! empty($arrayfields['d.address']['checked']))        print_liste_field_titre($arrayfields['d.address']['label'],$_SERVER["PHP_SELF"],'d.address','',$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['d.zip']['checked']))            print_liste_field_titre($arrayfields['d.zip']['label'],$_SERVER["PHP_SELF"],'d.zip','',$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['d.town']['checked']))           print_liste_field_titre($arrayfields['d.town']['label'],$_SERVER["PHP_SELF"],'d.town','',$param,'',$sortfield,$sortorder);
    -if (! empty($arrayfields['state.nom']['checked']))        print_liste_field_titre($arrayfields['state.town']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['state.nom']['checked']))        print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder);
     if (! empty($arrayfields['d.phone']['checked']))          print_liste_field_titre($arrayfields['d.phone']['label'],$_SERVER["PHP_SELF"],'d.phone','',$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['d.phone_perso']['checked']))    print_liste_field_titre($arrayfields['d.phone_perso']['label'],$_SERVER["PHP_SELF"],'d.phone_perso','',$param,'',$sortfield,$sortorder);
    @@ -605,6 +610,7 @@ while ($i < min($num, $limit))
     	$datefin=$db->jdate($obj->datefin);
     	$memberstatic->id=$obj->rowid;
     	$memberstatic->ref=$obj->rowid;
    +	$memberstatic->civility_id=$obj->civility;
     	$memberstatic->lastname=$obj->lastname;
     	$memberstatic->firstname=$obj->firstname;
     	$memberstatic->statut=$obj->statut;
    @@ -630,10 +636,17 @@ while ($i < min($num, $limit))
     	// Ref
     	if (! empty($arrayfields['d.ref']['checked']))
     	{
    -   		print "<td>";
    +		print "<td>";
     		print $memberstatic->getNomUrl(-1, 0, 'card', 'ref');
     		print "</td>\n";
     	}
    +	// Civility
    +	if (! empty($arrayfields['d.civility']['checked']))
    +	{
    +		print "<td>";
    +		print $obj->civility;
    +		print "</td>\n";
    +	}
     	// Firstname
     	if (! empty($arrayfields['d.firstname']['checked']))
     	{
    @@ -658,12 +671,12 @@ while ($i < min($num, $limit))
     	// Login
     	if (! empty($arrayfields['d.login']['checked']))
     	{
    -	   print "<td>".$obj->login."</td>\n";
    +		print "<td>".$obj->login."</td>\n";
     	}
     	// Moral/Physique
     	if (! empty($arrayfields['d.morphy']['checked']))
     	{
    -	   print "<td>".$memberstatic->getmorphylib($obj->morphy)."</td>\n";
    +		print "<td>".$memberstatic->getmorphylib($obj->morphy)."</td>\n";
     	}
     	// Type label
     	if (! empty($arrayfields['t.libelle']['checked']))
    @@ -827,6 +840,6 @@ print '</form>';
     
     if ($num > $limit || $page) print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic.png', 0, '', '', $limit, 1);
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php
    index 1b887406df3..c12c45de8b7 100644
    --- a/htdocs/adherents/note.php
    +++ b/htdocs/adherents/note.php
    @@ -28,9 +28,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     
    -$langs->load("companies");
    -$langs->load("members");
    -$langs->load("bills");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members","bills"));
     
     $action=GETPOST('action','alpha');
     $id=GETPOST('id','int');
    @@ -117,9 +116,8 @@ if ($id)
     
     
         dol_fiche_end();
    -
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/stats/byproperties.php b/htdocs/adherents/stats/byproperties.php
    index ded3dec120e..defbde2dce2 100644
    --- a/htdocs/adherents/stats/byproperties.php
    +++ b/htdocs/adherents/stats/byproperties.php
    @@ -44,8 +44,8 @@ $year = strftime("%Y", time());
     $startyear=$year-2;
     $endyear=$year;
     
    -$langs->load("members");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members"));
     
     
     /*
    @@ -143,7 +143,6 @@ print '</table>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/stats/geo.php b/htdocs/adherents/stats/geo.php
    index 1c6944c2a0a..2175569b7ce 100644
    --- a/htdocs/adherents/stats/geo.php
    +++ b/htdocs/adherents/stats/geo.php
    @@ -45,8 +45,8 @@ $year = strftime("%Y", time());
     $startyear=$year-2;
     $endyear=$year;
     
    -$langs->load("members");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members"));
     
     
     /*
    @@ -309,8 +309,6 @@ if ($mode)
     
     dol_fiche_end();
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/stats/index.php b/htdocs/adherents/stats/index.php
    index 083d81d6db6..69958f60d76 100644
    --- a/htdocs/adherents/stats/index.php
    +++ b/htdocs/adherents/stats/index.php
    @@ -46,8 +46,8 @@ $year = strftime("%Y", time());
     $startyear=$year-2;
     $endyear=$year;
     
    -$langs->load("members");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members"));
     
     
     /*
    @@ -167,6 +167,7 @@ print '<br><br>';
     $data = $stats->getAllByYear();
     
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -207,6 +208,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    @@ -229,7 +231,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php
    index b0b450b10a1..9c505477309 100644
    --- a/htdocs/adherents/subscription.php
    +++ b/htdocs/adherents/subscription.php
    @@ -1,9 +1,10 @@
     <?php
    -/* Copyright (C) 2001-2004	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    - * Copyright (C) 2002-2003	Jean-Louis Bergamo		<jlb@j1b.org>
    - * Copyright (C) 2004-2018	Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2012-2017	Regis Houssin			<regis.houssin@capnetworks.com>
    - * Copyright (C) 2015-2016	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
    +/* Copyright (C) 2001-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
    + * Copyright (C) 2004-2018  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2012-2017  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2015-2016  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -358,8 +359,9 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && !
                 	// Set output language
                 	$outputlangs = new Translate('', $conf);
                 	$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +            	// Load traductions files requiredby by page
                 	$outputlangs->loadLangs(array("main", "members"));
    -            	// Get email content fro mtemplae
    +            	// Get email content from template
                 	$arraydefaultmessage=null;
                 	$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_SUBSCRIPTION;
     
    @@ -897,7 +899,7 @@ if ($rowid > 0)
                     $datefrom=dol_time_plus_duree($object->datefin,1,'d');
                 }
             }
    -        print $form->select_date($datefrom,'','','','',"subscription",1,1,1);
    +        print $form->selectDate($datefrom, '', '', '', '', "subscription", 1, 1);
             print "</td></tr>";
     
             // Date end subscription
    @@ -910,7 +912,7 @@ if ($rowid > 0)
                 $dateto=-1;		// By default, no date is suggested
             }
             print '<tr><td>'.$langs->trans("DateEndSubscription").'</td><td>';
    -        print $form->select_date($dateto,'end','','','',"subscription",1,0,1);
    +        print $form->selectDate($dateto, 'end', '', '', '', "subscription", 1, 0);
             print "</td></tr>";
     
             if ($adht->subscription)
    @@ -1011,7 +1013,7 @@ if ($rowid > 0)
     
                     // Date of payment
                     print '<tr class="bankswitchclass"><td class="fieldrequired">'.$langs->trans("DatePayment").'</td><td>';
    -                print $form->select_date(isset($paymentdate)?$paymentdate:-1,'payment',0,0,1,'subscription',1,1,1);
    +                print $form->selectDate(isset($paymentdate)?$paymentdate:-1, 'payment', 0, 0, 1, 'subscription', 1, 1);
                     print "</td></tr>\n";
     
                     print '<tr class="bankswitchclass2"><td>'.$langs->trans('Numero');
    @@ -1054,8 +1056,9 @@ if ($rowid > 0)
                 // Set output language
                 $outputlangs = new Translate('', $conf);
                 $outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +            // Load traductions files requiredby by page
                 $outputlangs->loadLangs(array("main", "members"));
    -            // Get email content fro mtemplae
    +            // Get email content from template
                 $arraydefaultmessage=null;
                 $labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_SUBSCRIPTION;
     
    @@ -1110,7 +1113,6 @@ else
         print $langs->trans("ErrorRecordNotFound");
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/subscription/card.php b/htdocs/adherents/subscription/card.php
    index f905225a396..94950f02b05 100644
    --- a/htdocs/adherents/subscription/card.php
    +++ b/htdocs/adherents/subscription/card.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2007-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2007-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -29,10 +30,8 @@ if (! empty($conf->banque->enabled)) {
     	require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     }
     
    -$langs->load("companies");
    -$langs->load("bills");
    -$langs->load("members");
    -$langs->load("users");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members","bills","users"));
     
     $adh = new Adherent($db);
     $object = new Subscription($db);
    @@ -211,13 +210,13 @@ if ($user->rights->adherent->cotisation->creer && $action == 'edit')
     
         // Date start subscription
         print '<tr><td>'.$langs->trans("DateSubscription").'</td><td class="valeur" colspan="2">';
    -	$form->select_date($object->dateh,'datesub',1,1,0,'update',1);
    +	print $form->selectDate($object->dateh, 'datesub', 1, 1, 0, 'update', 1);
     	print '</td>';
         print '</tr>';
     
         // Date end subscription
         print '<tr><td>'.$langs->trans("DateEndSubscription").'</td><td class="valeur" colspan="2">';
    -	$form->select_date($object->datef,'datesubend',0,0,0,'update',1);
    +	print $form->selectDate($object->datef, 'datesubend', 0, 0, 0, 'update', 1);
     	print '</td>';
         print '</tr>';
     
    @@ -417,7 +416,6 @@ if ($rowid && $action != 'edit')
         print '</div></div></div>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/subscription/info.php b/htdocs/adherents/subscription/info.php
    index 05856c35f75..eb8f8e4eab3 100644
    --- a/htdocs/adherents/subscription/info.php
    +++ b/htdocs/adherents/subscription/info.php
    @@ -28,10 +28,8 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
     
    -$langs->load("companies");
    -$langs->load("bills");
    -$langs->load("members");
    -$langs->load("users");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","members","bills","users"));
     
     if (!$user->rights->adherent->lire)
     	accessforbidden();
    @@ -76,5 +74,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php
    index 21ba01088e4..91e5b2f8837 100644
    --- a/htdocs/adherents/subscription/list.php
    +++ b/htdocs/adherents/subscription/list.php
    @@ -381,6 +381,6 @@ else
         dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php
    index 56363599c10..7e69d4fbc98 100644
    --- a/htdocs/adherents/type.php
    +++ b/htdocs/adherents/type.php
    @@ -694,7 +694,6 @@ if ($rowid > 0)
     		{
     		    dol_print_error($db);
     		}
    -
     	}
     
     	/* ************************************************************************** */
    @@ -787,7 +786,6 @@ if ($rowid > 0)
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/adherents/type_ldap.php b/htdocs/adherents/type_ldap.php
    index 7edb42e6c76..c18074130aa 100644
    --- a/htdocs/adherents/type_ldap.php
    +++ b/htdocs/adherents/type_ldap.php
    @@ -29,9 +29,8 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/ldap.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ldap.lib.php';
     
    -$langs->load("members");
    -$langs->load("admin");
    -$langs->load("ldap");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","members","ldap"));
     
     $id = GETPOST('rowid', 'int');
     $action = GETPOST('action','alpha');
    @@ -187,5 +186,6 @@ else
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php
    index 6fedfa6d2cb..7f41927b478 100644
    --- a/htdocs/admin/agenda.php
    +++ b/htdocs/admin/agenda.php
    @@ -202,6 +202,6 @@ print "</form>\n";
     
     print "<br>";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/agenda_extrafields.php b/htdocs/admin/agenda_extrafields.php
    index fadb144b883..887fba847e4 100644
    --- a/htdocs/admin/agenda_extrafields.php
    +++ b/htdocs/admin/agenda_extrafields.php
    @@ -85,7 +85,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -98,7 +98,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -117,6 +117,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/agenda_extsites.php b/htdocs/admin/agenda_extsites.php
    index 906ecd8d092..236483f5ed4 100644
    --- a/htdocs/admin/agenda_extsites.php
    +++ b/htdocs/admin/agenda_extsites.php
    @@ -238,7 +238,6 @@ print '</div>';
     
     print "</form>\n";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php
    index 2d20d285720..8215bdbe0b1 100644
    --- a/htdocs/admin/agenda_other.php
    +++ b/htdocs/admin/agenda_other.php
    @@ -356,7 +356,7 @@ print '<tr class="oddeven">'."\n";
     print '<td>'.$langs->trans("AGENDA_DEFAULT_VIEW").'</td>'."\n";
     print '<td align="center">&nbsp;</td>'."\n";
     print '<td align="right">'."\n";
    -$tmplist=array('show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser"));
    +$tmplist=array(''=>'&nbsp;', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser"));
     print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $conf->global->AGENDA_DEFAULT_VIEW);
     print '</td></tr>'."\n";
     
    @@ -399,6 +399,6 @@ print '</form>';
     
     print "<br>";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/agenda_reminder.php b/htdocs/admin/agenda_reminder.php
    index e78a8e089ed..269880236cb 100644
    --- a/htdocs/admin/agenda_reminder.php
    +++ b/htdocs/admin/agenda_reminder.php
    @@ -247,6 +247,6 @@ print '</form>';
     
     print "<br>";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/agenda_xcal.php b/htdocs/admin/agenda_xcal.php
    index 481a850790e..d76d95da47a 100644
    --- a/htdocs/admin/agenda_xcal.php
    +++ b/htdocs/admin/agenda_xcal.php
    @@ -198,6 +198,6 @@ if (! empty($conf->use_javascript_ajax))
     	print '</script>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php
    index a4e9e4bb210..497d4748da8 100644
    --- a/htdocs/admin/bank.php
    +++ b/htdocs/admin/bank.php
    @@ -420,7 +420,7 @@ if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE) {
         print '</a>';
         print '</td>';
     }
    -else 
    +else
     {
         print '<td align="center">' . "\n";
         print '<a href="' . $_SERVER["PHP_SELF"] . '?action=setreportlastnumreleve">' . img_picto($langs->trans("Disabled"),
    @@ -432,6 +432,6 @@ print "</tr>\n";
     print '</table>';
     dol_fiche_end();
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/bank_extrafields.php b/htdocs/admin/bank_extrafields.php
    index 19446092923..3b95c158f27 100644
    --- a/htdocs/admin/bank_extrafields.php
    +++ b/htdocs/admin/bank_extrafields.php
    @@ -82,7 +82,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -95,7 +95,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -114,6 +114,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php
    index a7a863c4725..6a356843d6b 100644
    --- a/htdocs/admin/barcode.php
    +++ b/htdocs/admin/barcode.php
    @@ -75,7 +75,6 @@ else if ($action == 'update')
     else if ($action == 'updateengine')
     {
         // TODO Update engines.
    -
     }
     
     if ($action && $action != 'setcoder' && $action != 'setModuleOptions')
    @@ -306,7 +305,7 @@ if (! empty($conf->product->enabled))
     	print '<tr class="oddeven">';
     	print '<td>'.$langs->trans("SetDefaultBarcodeTypeProducts").'</td>';
     	print '<td width="60" align="right">';
    -	$formbarcode->select_barcode_type($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE,"PRODUIT_DEFAULT_BARCODE_TYPE",1);
    +	print $formbarcode->selectBarcodeType($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE, "PRODUIT_DEFAULT_BARCODE_TYPE", 1);
     	print '</td></tr>';
     }
     
    @@ -317,7 +316,7 @@ if (! empty($conf->societe->enabled))
     	print '<tr class="oddeven">';
     	print '<td>'.$langs->trans("SetDefaultBarcodeTypeThirdParties").'</td>';
     	print '<td width="60" align="right">';
    -	print $formbarcode->select_barcode_type($conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY,"GENBARCODE_BARCODETYPE_THIRDPARTY",1);
    +	print $formbarcode->selectBarcodeType($conf->global->GENBARCODE_BARCODETYPE_THIRDPARTY, "GENBARCODE_BARCODETYPE_THIRDPARTY", 1);
     	print '</td></tr>';
     }
     
    @@ -405,5 +404,6 @@ if ($conf->produit->enabled)
     
     print "<br>";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php
    index 04fd76e96fc..9f3453f7587 100644
    --- a/htdocs/admin/boxes.php
    +++ b/htdocs/admin/boxes.php
    @@ -488,7 +488,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     print '</form>';
     print "\n".'<!-- End Other Const -->'."\n";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/chequereceipts.php b/htdocs/admin/chequereceipts.php
    index df628ecc87f..f85018c03b8 100644
    --- a/htdocs/admin/chequereceipts.php
    +++ b/htdocs/admin/chequereceipts.php
    @@ -217,7 +217,6 @@ foreach ($dirmodels as $reldir)
     							print '</td>';
     
     							print "</tr>\n";
    -
     						}
     					}
     				}
    @@ -280,6 +279,6 @@ dol_fiche_end();
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/clicktodial.php b/htdocs/admin/clicktodial.php
    index c2cfaf9f72a..34a641137dc 100644
    --- a/htdocs/admin/clicktodial.php
    +++ b/htdocs/admin/clicktodial.php
    @@ -140,6 +140,6 @@ if (! empty($conf->global->CLICKTODIAL_URL))
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php
    index cee12e4b08e..64df9194197 100644
    --- a/htdocs/admin/commande.php
    +++ b/htdocs/admin/commande.php
    @@ -679,7 +679,6 @@ print "</td></tr>\n";
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php
    index 9b312e7e228..cc564bfb08e 100644
    --- a/htdocs/admin/company.php
    +++ b/htdocs/admin/company.php
    @@ -50,6 +50,7 @@ $error=0;
     // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
     $hookmanager->initHooks(array('admincompany','globaladmin'));
     
    +
     /*
      * Actions
      */
    @@ -74,6 +75,8 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     		activateModulesRequiredByCountry($mysoc->country_code);
     	}
     
    +	$db->begin();
    +
     	dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", GETPOST("nom",'nohtml'),'chaine',0,'',$conf->entity);
     	dolibarr_set_const($db, "MAIN_INFO_SOCIETE_ADDRESS", GETPOST("MAIN_INFO_SOCIETE_ADDRESS",'nohtml'),'chaine',0,'',$conf->entity);
     	dolibarr_set_const($db, "MAIN_INFO_SOCIETE_TOWN", GETPOST("MAIN_INFO_SOCIETE_TOWN",'nohtml'),'chaine',0,'',$conf->entity);
    @@ -172,11 +175,24 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     
     	dolibarr_set_const($db, "SOCIETE_FISCAL_MONTH_START", GETPOST("SOCIETE_FISCAL_MONTH_START",'int'),'chaine',0,'',$conf->entity);
     
    -	dolibarr_set_const($db, "FACTURE_TVAOPTION", GETPOST("optiontva",'aZ09'),'chaine',0,'',$conf->entity);
    +	// Sale tax options
    +	$usevat = GETPOST("optiontva",'aZ09');
    +	$uselocaltax1 = GETPOST("optionlocaltax1",'aZ09');
    +	$uselocaltax2 = GETPOST("optionlocaltax2",'aZ09');
    +	if ($uselocaltax1 == 'localtax1on' && ! $usevat)
    +	{
    +		setEventMessages($langs->trans("IfYouUseASecondTaxYouMustSetYouUseTheMainTax"), null, 'errors');
    +		$error++;
    +	}
    +	if ($uselocaltax2 == 'localtax2on' && ! $usevat)
    +	{
    +		setEventMessages($langs->trans("IfYouUseAThirdTaxYouMustSetYouUseTheMainTax"), null, 'errors');
    +		$error++;
    +	}
     
    -	// Local taxes
    -	dolibarr_set_const($db, "FACTURE_LOCAL_TAX1_OPTION", GETPOST("optionlocaltax1",'aZ09'),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "FACTURE_LOCAL_TAX2_OPTION", GETPOST("optionlocaltax2",'aZ09'),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "FACTURE_TVAOPTION", $usevat,'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "FACTURE_LOCAL_TAX1_OPTION", $uselocaltax1,'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "FACTURE_LOCAL_TAX2_OPTION", $uselocaltax2,'chaine',0,'',$conf->entity);
     
     	if($_POST["optionlocaltax1"]=="localtax1on")
     	{
    @@ -188,7 +204,7 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     		{
     			dolibarr_set_const($db, "MAIN_INFO_VALUE_LOCALTAX1", GETPOST('lt1','aZ09'),'chaine',0,'',$conf->entity);
     		}
    -		dolibarr_set_const($db,"MAIN_INFO_LOCALTAX_CALC1",  GETPOST("clt1",'aZ09'),'chaine',0,'',$conf->entity);
    +		dolibarr_set_const($db,"MAIN_INFO_LOCALTAX_CALC1", GETPOST("clt1",'aZ09'),'chaine',0,'',$conf->entity);
     	}
     	if($_POST["optionlocaltax2"]=="localtax2on")
     	{
    @@ -200,7 +216,16 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     		{
     			dolibarr_set_const($db, "MAIN_INFO_VALUE_LOCALTAX2", GETPOST('lt2','aZ09'),'chaine',0,'',$conf->entity);
     		}
    -		dolibarr_set_const($db,"MAIN_INFO_LOCALTAX_CALC2",  GETPOST("clt2",'aZ09'),'chaine',0,'',$conf->entity);
    +		dolibarr_set_const($db,"MAIN_INFO_LOCALTAX_CALC2", GETPOST("clt2",'aZ09'),'chaine',0,'',$conf->entity);
    +	}
    +
    +	if (! $error)
    +	{
    +		$db->commit();
    +	}
    +	else
    +	{
    +		$db->rollback();
     	}
     
     	if ($action != 'updateedit' && ! $error)
    @@ -397,7 +422,7 @@ if ($action == 'edit' || $action == 'updateedit')
     		print '<a href="'.$_SERVER["PHP_SELF"].'?action=removelogo">'.img_delete($langs->trans("Delete")).'</a>';
     		if (file_exists($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini)) {
     			print ' &nbsp; ';
    -			print '<img src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('/thumbs/'.$mysoc->logo_mini).'">';
    +			print '<img src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_mini).'">';
     		}
     	} else {
     		print '<img height="30" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">';
    @@ -585,7 +610,7 @@ if ($action == 'edit' || $action == 'updateedit')
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label for=\"use_vat\">".$langs->trans("VATIsUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -594,7 +619,7 @@ if ($action == 'edit' || $action == 'updateedit')
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label for=\"no_vat\">".$langs->trans("VATIsNotUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -765,7 +790,13 @@ else
     
     	// Web
     
    -	print '<tr class="oddeven"><td>'.$langs->trans("Web").'</td><td>' . dol_print_url($conf->global->MAIN_INFO_SOCIETE_WEB,'_blank',80) . '</td></tr>';
    +	print '<tr class="oddeven"><td>'.$langs->trans("Web").'</td><td>';
    +	$arrayofurl = preg_split('/\s/', $conf->global->MAIN_INFO_SOCIETE_WEB);
    +	foreach($arrayofurl as $urltoshow)
    +	{
    +		if ($urltoshow) print dol_print_url($urltoshow,'_blank',80);
    +	}
    +	print '</td></tr>';
     
     	// Barcode
     	if (! empty($conf->barcode->enabled))
    @@ -791,7 +822,7 @@ else
     	}
     	else if ($mysoc->logo_mini && is_file($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini))
     	{
    -		print '<img class="img_logo" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('/thumbs/'.$mysoc->logo_mini).'">';
    +		print '<img class="img_logo" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_mini).'">';
     	}
     	else
     	{
    @@ -1017,7 +1048,7 @@ else
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label for=\"use_vat\">".$langs->trans("VATIsUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -1027,7 +1058,7 @@ else
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label=\"no_vat\">".$langs->trans("VATIsNotUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -1153,7 +1184,6 @@ else
     	print '</div>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/compta.php b/htdocs/admin/compta.php
    index 8e17541bfef..214c30dc544 100644
    --- a/htdocs/admin/compta.php
    +++ b/htdocs/admin/compta.php
    @@ -164,5 +164,6 @@ print "</table>\n";
     print '<br><br><div style="text-align:center"><input type="submit" class="button" value="'.$langs->trans('Modify').'" name="button"></div>';
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/confexped.php b/htdocs/admin/confexped.php
    index e4691a42e78..9e6745e6c29 100644
    --- a/htdocs/admin/confexped.php
    +++ b/htdocs/admin/confexped.php
    @@ -147,5 +147,6 @@ print '</table>';
     
     print '</div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/const.php b/htdocs/admin/const.php
    index 9dd68c16326..be5f785f9e4 100644
    --- a/htdocs/admin/const.php
    +++ b/htdocs/admin/const.php
    @@ -314,7 +314,6 @@ if ($conf->use_javascript_ajax)
     
     print "</form>\n";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php
    index 74f7acb04f3..60be9e062ba 100644
    --- a/htdocs/admin/contract.php
    +++ b/htdocs/admin/contract.php
    @@ -509,7 +509,6 @@ print '</form>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/dav.php b/htdocs/admin/dav.php
    index ea4bbf97af0..e882a56e2b8 100644
    --- a/htdocs/admin/dav.php
    +++ b/htdocs/admin/dav.php
    @@ -143,6 +143,6 @@ $message.=img_picto('','object_globe.png').' '.$langs->trans("WebDavServer",'Web
     $message.='<br>';
     print $message;
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php
    index 84271cff38f..4d75ab44235 100644
    --- a/htdocs/admin/defaultvalues.php
    +++ b/htdocs/admin/defaultvalues.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2017		Laurent Destailleur	<eldy@users.sourceforge.net>
    +/* Copyright (C) 2017-2018	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2017-2018	Regis Houssin		<regis.houssin@capnetworks.com>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -17,8 +17,13 @@
      */
     
     /**
    - *       \file       htdocs/admin/defaultvalues.php
    - *       \brief      Page to set default values used used in a create form
    + *       \file      htdocs/admin/defaultvalues.php
    + *       \brief     Page to set default values used used in a create form
    + *       			Default values are stored into $user->default_values[url]['createform']['querystring'|'_noquery_'][paramkey]=paramvalue
    + *       			Default filters are stored into $user->default_values[url]['filters']['querystring'|'_noquery_'][paramkey]=paramvalue
    + *       			Default sort order are stored into $user->default_values[url]['sortorder']['querystring'|'_noquery_'][paramkey]=paramvalue
    + *       			Default focus are stored into $user->default_values[url]['focus']['querystring'|'_noquery_'][paramkey]=paramvalue
    + *       			Mandatory fields are stored into $user->default_values[url]['mandatory']['querystring'|'_noquery_'][paramkey]=paramvalue
      */
     
     require '../main.inc.php';
    @@ -230,9 +235,9 @@ if ($mode == 'sortorder')
     {
         print info_admin($langs->trans("WarningSettingSortOrder")).'<br>';
     }
    -if ($mode == 'focus')
    +if ($mode == 'mandatory')
     {
    -    print info_admin($langs->trans("FeatureNotYetAvailable")).'<br>';
    +	print info_admin($langs->trans("FeatureSupportedOnTextFieldsOnly")).'<br>';
     }
     
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    @@ -261,7 +266,7 @@ else
     }
     print_liste_field_titre($textkey,$_SERVER["PHP_SELF"],'param','',$param,'',$sortfield,$sortorder);
     // Value
    -if ($mode != 'focus')
    +if ($mode != 'focus' && $mode != 'mandatory')
     {
         if ($mode != 'sortorder')
         {
    @@ -294,14 +299,14 @@ print "\n";
     print '<tr class="oddeven">';
     // Page
     print '<td>';
    -print '<input type="text" class="flat minwidth200 maxwidthonsmartphone" name="defaulturl" value="">';
    +print '<input type="text" class="flat minwidth200 maxwidthonsmartphone" name="defaulturl" value="'.dol_escape_htmltag(GETPOST('defaulturl','alphanohtml')).'">';
     print '</td>'."\n";
     // Field
     print '<td>';
    -print '<input type="text" class="flat maxwidth100onsmartphone" name="defaultkey" value="">';
    +print '<input type="text" class="flat maxwidth100onsmartphone" name="defaultkey" value="'.dol_escape_htmltag(GETPOST('defaultkey','alphanohtml')).'">';
     print '</td>';
     // Value
    -if ($mode != 'focus')
    +if ($mode != 'focus' && $mode != 'mandatory')
     {
         print '<td>';
         print '<input type="text" class="flat maxwidth100onsmartphone" name="defaultvalue" value="">';
    @@ -311,15 +316,16 @@ if ($mode != 'focus')
     if (! empty($conf->multicompany->enabled) && !$user->entity)
     {
     	print '<td>';
    -	print '<input type="text" class="flat" size="1" name="entity" value="'.$conf->entity.'">';
    +	print '<input type="text" class="flat" size="1" disabled name="entity" value="'.$conf->entity.'">';	// We see environment, but to change it we must switch on other entity
     	print '</td>';
    -	print '<td align="center">';
     }
     else
     {
     	print '<td align="center">';
     	print '<input type="hidden" name="entity" value="'.$conf->entity.'">';
    +	print '</td>';
     }
    +print '<td align="center">';
     $disabled='';
     if (empty($conf->global->MAIN_ENABLE_DEFAULT_VALUES)) $disabled=' disabled="disabled"';
     print '<input type="submit" class="button"'.$disabled.' value="'.$langs->trans("Add").'" name="add">';
    @@ -363,7 +369,7 @@ if ($result)
     		print '</td>'."\n";
     
     		// Value
    -		if ($mode != 'focus')
    +		if ($mode != 'focus' && $mode != 'mandatory')
     		{
         		print '<td>';
         		/*print '<input type="hidden" name="const['.$i.'][rowid]" value="'.$obj->rowid.'">';
    @@ -376,6 +382,9 @@ if ($result)
         		print '</td>';
     		}
     
    +		// Multicompany
    +		print '<td></td>';
    +
     		// Actions
     		print '<td align="center">';
     		if ($action != 'edit' || GETPOST('rowid') != $obj->rowid)
    @@ -412,7 +421,6 @@ dol_fiche_end();
     
     print "</form>\n";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/delais.php b/htdocs/admin/delais.php
    index ae3c43c5b24..add4e2aec80 100644
    --- a/htdocs/admin/delais.php
    +++ b/htdocs/admin/delais.php
    @@ -122,6 +122,13 @@ $modules=array(
     		),
     );
     
    +$labelmeteo = array(0=>$langs->trans("No"), 1=>$langs->trans("Yes"), 2=>$langs->trans("OnMobileOnly"));
    +
    +
    +/*
    + * Actions
    + */
    +
     if ($action == 'update')
     {
     	foreach($modules as $module => $delays)
    @@ -148,7 +155,6 @@ if ($action == 'update')
     	for($i=0; $i<4; $i++) {
         	if(isset($_POST['MAIN_METEO'.$plus.'_LEVEL'.$i])) dolibarr_set_const($db, 'MAIN_METEO'.$plus.'_LEVEL'.$i, GETPOST('MAIN_METEO'.$plus.'_LEVEL'.$i, 'int'),'chaine',0,'',$conf->entity);
         }
    -
     }
     
     
    @@ -201,9 +207,10 @@ if ($action == 'edit')
     	print '<table class="noborder" width="100%">';
     	print '<tr class="liste_titre"><td>'.$langs->trans("Parameter").'</td><td class="center" width="120px">'.$langs->trans("Value").'</td></tr>';
     
    -	$var=false;
     	print '<tr class="oddeven">';
    -	print '<td>'.$langs->trans("MAIN_DISABLE_METEO").'</td><td class="center">' .$form->selectyesno('MAIN_DISABLE_METEO',(empty($conf->global->MAIN_DISABLE_METEO)?0:1),1) . '</td></tr>';
    +	print '<td>'.$langs->trans("MAIN_DISABLE_METEO").'</td><td class="center">';
    +	print $form->selectarray('MAIN_DISABLE_METEO', $labelmeteo, (empty($conf->global->MAIN_DISABLE_METEO)?0:$conf->global->MAIN_DISABLE_METEO));
    +	print '</td></tr>';
     
     	print '</table>';
     }
    @@ -241,10 +248,11 @@ else
     	print '<tr class="liste_titre"><td>'.$langs->trans("Parameter").'</td><td class="center" width="120px">'.$langs->trans("Value").'</td></tr>';
     
     	print '<tr class="oddeven">';
    -	print '<td>'.$langs->trans("MAIN_DISABLE_METEO").'</td><td class="center">' . yn($conf->global->MAIN_DISABLE_METEO) . '</td></tr>';
    +	print '<td>'.$langs->trans("MAIN_DISABLE_METEO").'</td><td class="center">';
    +	print $labelmeteo[$conf->global->MAIN_DISABLE_METEO];
    +	print '</td></tr>';
     
     	print '</table>';
    -
     }
     
     print '<br>';
    @@ -262,7 +270,6 @@ if($action == 'edit') {
     	print '<input type="hidden" id="MAIN_USE_METEO_WITH_PERCENTAGE" name="MAIN_USE_METEO_WITH_PERCENTAGE" value="'.$conf->global->MAIN_USE_METEO_WITH_PERCENTAGE.'" />';
     
     	print '<br><br>';
    -
     } else {
     	if(empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) print $langs->trans('MeteoStdModEnabled');
     	else print $langs->trans('MeteoPercentageModEnabled');
    @@ -352,7 +359,6 @@ if ($action == 'edit') {
     	</script>
     
     	<?php
    -
     } else {
     
     	if(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) {
    @@ -375,7 +381,6 @@ if ($action == 'edit') {
     		print '&gt; '.$conf->global->MAIN_METEO_PERCENTAGE_LEVEL3.'&nbsp;%</td>';
     		print '</div>';
     		print '</div>';
    -
     	} else {
     
     		print '<div>';
    @@ -396,7 +401,6 @@ if ($action == 'edit') {
     		print '&gt; '.$level3;
     		print '</div>';
     		print '</div>';
    -
     	}
     }
     
    @@ -406,14 +410,13 @@ if($action == 'edit') {
     
     	print '<br><div class="center"><input type="submit" class="button" value="'.$langs->trans("Save").'"></div>';
     	print '<br></form>';
    -
     } else {
     
     	// Boutons d'action
     	print '<br><div class="tabsAction">';
     	print '<a class="butAction" href="delais.php?action=edit">'.$langs->trans("Modify").'</a></div>';
    -
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
    index 32995bce38f..4d5471b1aa8 100644
    --- a/htdocs/admin/dict.php
    +++ b/htdocs/admin/dict.php
    @@ -456,7 +456,7 @@ $tabhelp[8]  = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->
     $tabhelp[9]  = array('code'=>$langs->trans("EnterAnyCode"), 'unicode'=>$langs->trans("UnicodeCurrency"));
     $tabhelp[10] = array('code'=>$langs->trans("EnterAnyCode"), 'taux'=>$langs->trans("SellTaxRate"), 'recuperableonly'=>$langs->trans("RecuperableOnly"), 'localtax1_type'=>$langs->trans("LocalTaxDesc"), 'localtax2_type'=>$langs->trans("LocalTaxDesc"));
     $tabhelp[11] = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList"));
    -$tabhelp[12] = array('code'=>$langs->trans("EnterAnyCode"), 'type_cdr'=>$langs->trans("TypeCdr"));
    +$tabhelp[12] = array('code'=>$langs->trans("EnterAnyCode"), 'type_cdr'=>$langs->trans("TypeCdr", $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset"), $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset")));
     $tabhelp[13] = array('code'=>$langs->trans("EnterAnyCode"));
     $tabhelp[14] = array('code'=>$langs->trans("EnterAnyCode"));
     $tabhelp[15] = array('code'=>$langs->trans("EnterAnyCode"));
    @@ -592,7 +592,7 @@ if ($id == 10)
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha'))
     {
         $search_country_id = '';
         $search_code = '';
    @@ -705,7 +705,6 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
                 {
                     $obj = $db->fetch_object($result);
                     $newid=($obj->newid + 1);
    -
                 } else {
                     dol_print_error($db);
                 }
    @@ -950,8 +949,8 @@ if (empty($id))
     {
         print $langs->trans("DictionaryDesc");
         print " ".$langs->trans("OnlyActiveElementsAreShown")."<br>\n";
    +    print '<br>';
     }
    -print "<br>\n";
     
     
     $param = '&id='.urlencode($id);
    @@ -1016,6 +1015,13 @@ if ($id)
         print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
         print '<input type="hidden" name="from" value="'.dol_escape_htmltag(GETPOST('from','alpha')).'">';
     
    +    if ($id == 10 && empty($conf->global->FACTURE_TVAOPTION))
    +    {
    +    	print info_admin($langs->trans("VATIsUsedIsOff", $langs->transnoentities("Setup"), $langs->transnoentities("CompanyFoundation")));
    +    }
    +
    +    print "<br>\n";
    +
         // Form to add a new line
         if ($tabname[$id])
         {
    @@ -1735,7 +1741,7 @@ else
     
     print '<br>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/dolistore/ajax/image.php b/htdocs/admin/dolistore/ajax/image.php
    index 14d05a036e8..c1bb4e997dc 100644
    --- a/htdocs/admin/dolistore/ajax/image.php
    +++ b/htdocs/admin/dolistore/ajax/image.php
    @@ -20,22 +20,11 @@ if (!defined('REQUIRE_JQUERY_BLOCKUI')) define('REQUIRE_JQUERY_BLOCKUI', 1);
     
     
     /**
    - *      \file       htdocs/commande/info.php
    - *      \ingroup    commande
    - * 		\brief      Page des informations d'une commande
    + *      \file       htdocs/admin/dolistore/ajax/image.php
    + *      \ingroup    admin
    + *      \brief      Page des informations dolistore
      */
    -$res = 0;
    -if (!$res && file_exists("../main.inc.php")) $res = @include("../main.inc.php");
    -if (!$res && file_exists("../../main.inc.php")) $res = @include("../../main.inc.php");
    -if (!$res && file_exists("../../../main.inc.php")) $res = @include("../../../main.inc.php");
    -if (!$res && file_exists("../../../../main.inc.php")) $res = @include("../../../../main.inc.php");
    -if (!$res && file_exists("../../../dolibarr/htdocs/main.inc.php"))
    -        $res = @include("../../../dolibarr/htdocs/main.inc.php");     // Used on dev env only
    -if (!$res && file_exists("../../../../dolibarr/htdocs/main.inc.php"))
    -        $res = @include("../../../../dolibarr/htdocs/main.inc.php");   // Used on dev env only
    -if (!$res && file_exists("../../../../../dolibarr/htdocs/main.inc.php"))
    -        $res = @include("../../../../../dolibarr/htdocs/main.inc.php");   // Used on dev env only
    -if (!$res) die("Include of main fails");
    +require "../../../main.inc.php";
     
     // CORE
     
    @@ -52,8 +41,10 @@ $quality    = GETPOST('quality', 'alpha');
     
     try {
         $url = $conf->global->MAIN_MODULE_DOLISTORE_API_SRV.'/api/images/products/'.$id_product.'/'.$id_image.'/'.$quality;
    -    $api        = new PrestaShopWebservice($conf->global->MAIN_MODULE_DOLISTORE_API_SRV,
    -        $conf->global->MAIN_MODULE_DOLISTORE_API_KEY, $dolistore->debug_api);
    +    $api = new PrestaShopWebservice(
    +        $conf->global->MAIN_MODULE_DOLISTORE_API_SRV,
    +        $conf->global->MAIN_MODULE_DOLISTORE_API_KEY, $dolistore->debug_api
    +    );
         //echo $url;
         $request = $api->executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'GET'));
         header('Content-type:image');
    @@ -65,4 +56,3 @@ try {
         else if ($trace[0]['args'][0] == 401) die('Bad auth key');
         else die('Can not access to '.$conf->global->MAIN_MODULE_DOLISTORE_API_SRV);
     }
    -
    diff --git a/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php b/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php
    index de3ca683519..c8fcd061689 100644
    --- a/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php
    +++ b/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php
    @@ -53,7 +53,7 @@ class PrestaShopWebservice
     	 * PrestaShopWebservice constructor. Throw an exception when CURL is not installed/activated
     	 * <code>
     	 * <?php
    -	 * require_once('./PrestaShopWebservice.php');
    +	 * require_once './PrestaShopWebservice.php';
     	 * try
     	 * {
     	 * 	$ws = new PrestaShopWebservice('http://mystore.com/', 'ZQ88PRJX5VWQHCWE4EE7SQ7HPNX00RAJ', false);
    @@ -69,7 +69,8 @@ class PrestaShopWebservice
     	 * @param string $key Authentification key
     	 * @param mixed $debug Debug mode Activated (true) or deactivated (false)
     	*/
    -	function __construct($url, $key, $debug = true) {
    +    function __construct($url, $key, $debug = true)
    +    {
     		if (!extension_loaded('curl'))
     		  throw new PrestaShopWebserviceException('Please activate the PHP extension \'curl\' to allow use of PrestaShop webservice library');
     		$this->url = $url;
    @@ -82,6 +83,7 @@ class PrestaShopWebservice
     	 * Take the status code and throw an exception if the server didn't return 200 or 201 code
     	 *
     	 * @param int $status_code Status code of an HTTP return
    +     * @return void
     	 */
     	protected function checkStatusCode($status_code)
     	{
    @@ -175,7 +177,6 @@ class PrestaShopWebservice
     		{
     			$this->printDebug('HTTP REQUEST HEADER', curl_getinfo($session, CURLINFO_HEADER_OUT));
     			$this->printDebug('HTTP RESPONSE HEADER', $header);
    -
     		}
     		$status_code = curl_getinfo($session, CURLINFO_HTTP_CODE);
     		if ($status_code === 0)
    @@ -279,7 +280,7 @@ class PrestaShopWebservice
     	 * </p>
     	 * <code>
     	 * <?php
    -	 * require_once('./PrestaShopWebservice.php');
    +	 * require_once './PrestaShopWebservice.php';
     	 * try
     	 * {
     	 * $ws = new PrestaShopWebservice('http://mystore.com/', 'ZQ88PRJX5VWQHCWE4EE7SQ7HPNX00RAJ', false);
    @@ -383,7 +384,7 @@ class PrestaShopWebservice
     		else
     			throw new PrestaShopWebserviceException('Bad parameters given');
     
    -		$request = self::executeRequest($url,  array(CURLOPT_CUSTOMREQUEST => 'PUT', CURLOPT_POSTFIELDS => $xml));
    +		$request = self::executeRequest($url, array(CURLOPT_CUSTOMREQUEST => 'PUT', CURLOPT_POSTFIELDS => $xml));
     		self::checkStatusCode($request['status_code']);// check the response validity
     		return self::parseXML($request['response']);
     	}
    diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php
    index 660886c835d..859b9140f86 100644
    --- a/htdocs/admin/dolistore/class/dolistore.class.php
    +++ b/htdocs/admin/dolistore/class/dolistore.class.php
    @@ -25,9 +25,18 @@ include_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/PSWebServiceLibrary.class
      */
     class Dolistore
     {
    -	// params
    -	public $start;       // beginning of pagination
    -	public $end;         // end of pagination
    +    /**
    +     * beginning of pagination
    +     * @var int
    +     */
    +
    +     public $start;
    +    /**
    +     * end of pagination
    +     * @var int
    +     */
    +    public $end;
    +
     	public $per_page;    // pagination: display per page
     	public $categorie;   // the current categorie
     	public $search;      // the search keywords
    @@ -154,6 +163,7 @@ class Dolistore
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return tree of Dolistore categories. $this->categories must have been loaded before.
     	 *
    @@ -162,6 +172,7 @@ class Dolistore
     	 */
     	function get_categories($parent = 0)
     	{
    +        // phpcs:enable
     		if (!isset($this->categories)) die('not possible');
     		if ($parent != 0) {
     			$html = '<ul>';
    @@ -201,6 +212,7 @@ class Dolistore
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return list of product formated for output
     	 *
    @@ -208,6 +220,7 @@ class Dolistore
     	 */
     	function get_products()
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     		$html       = "";
     		$parity     = "pair";
    @@ -282,18 +295,41 @@ class Dolistore
     		return $html;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     * get previous link
    +     *
    +     * @param   string    $text     symbol previous
    +     * @return  string              html previous link
    +     */
     	function get_previous_link($text = '<<')
     	{
    +        // phpcs:enable
     		return '<a href="'.$this->get_previous_url().'" class="button">'.$text.'</a>';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     * get next link
    +     *
    +     * @param   string    $text     symbol next
    +     * @return  string              html next link
    +     */
     	function get_next_link($text = '>>')
     	{
    +        // phpcs:enable
     		return '<a href="'.$this->get_next_url().'" class="button">'.$text.'</a>';
     	}
     
    -	function get_previous_url()
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +   /**
    +     * get previous url
    +     *
    +     * @return string    previous url
    +     */
    +    function get_previous_url()
     	{
    +        // phpcs:enable
     		$param_array = array();
     		if ($this->start < $this->per_page) {
     			$sub = 0;
    @@ -309,8 +345,15 @@ class Dolistore
     		return $this->url."&".$param;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     * get next url
    +     *
    +     * @return string    next url
    +     */
     	function get_next_url()
     	{
    +        // phpcs:enable
     		$param_array = array();
     		if (count($this->products) < $this->per_page) {
     			$add = 0;
    @@ -326,8 +369,17 @@ class Dolistore
     		return $this->url."&".$param;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     * version compare
    +     *
    +     * @param   string  $v1     version 1
    +     * @param   string  $v2     version 2
    +     * @return int              result of compare
    +     */
     	function version_compare($v1, $v2)
     	{
    +        // phpcs:enable
     		$v1       = explode('.', $v1);
     		$v2       = explode('.', $v2);
     		$ret      = 0;
    @@ -355,4 +407,3 @@ class Dolistore
     		return $ret;
     	}
     }
    -
    diff --git a/htdocs/admin/dolistore/css/dolistore.css b/htdocs/admin/dolistore/css/dolistore.css
    index bba808a21a0..fb4dc2d5bb1 100644
    --- a/htdocs/admin/dolistore/css/dolistore.css
    +++ b/htdocs/admin/dolistore/css/dolistore.css
    @@ -6,10 +6,10 @@ div.divsearchfield {
     }
     
     .margeCoteGauche,.margeCote{
    -    padding-right: 20px!important;   
    +    padding-right: 20px!important;
     }
     .margeCote,.margeCoteDroite{
    -    padding-left: 20px!important;    
    +    padding-left: 20px!important;
     }
     .nomargesupinf{
         margin-top: 0;
    @@ -26,13 +26,13 @@ div.divsearchfield {
         width: 100%;
     }
     .tree{
    -    margin: 0px 0px 0px 0px; 
    +    margin: 0px 0px 0px 0px;
         padding:0px;
         list-style: none; line-height: 2em; font-family: Arial;
     }
     .tree li{
         font-size: 16px;
    -    position: relative;list-style: none; 
    +    position: relative;list-style: none;
     }
     .tree li:before{
         position: absolute;
    @@ -65,7 +65,7 @@ div.divsearchfield {
     .tree li.root:after{
         display: none;
     }
    -.tree li:last-child:after{ 
    +.tree li:last-child:after{
         display: none
     }
     .blockUI {
    @@ -159,7 +159,7 @@ textarea.row4{
     
     .reviewList {
         max-height: 150px;
    -    overflow-y: scroll; 
    +    overflow-y: scroll;
     }
     
     .reviewRow{
    diff --git a/htdocs/admin/ecm.php b/htdocs/admin/ecm.php
    index dc2f3e489f7..3126f432938 100644
    --- a/htdocs/admin/ecm.php
    +++ b/htdocs/admin/ecm.php
    @@ -109,5 +109,6 @@ print '</td></tr>';
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/events.php b/htdocs/admin/events.php
    index 1d1ec548853..dd3b1c5bff7 100644
    --- a/htdocs/admin/events.php
    +++ b/htdocs/admin/events.php
    @@ -94,7 +94,7 @@ print "</tr>\n";
     foreach ($eventstolog as $key => $arr)
     {
     	if ($arr['id'])
    -	{		
    +	{
     		print '<tr class="oddeven">';
     		print '<td>'.$arr['id'].'</td>';
     		print '<td>';
    @@ -114,6 +114,6 @@ print "</div>";
     
     print "</form>\n";
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php
    index eb18f904229..c851010635e 100644
    --- a/htdocs/admin/expedition.php
    +++ b/htdocs/admin/expedition.php
    @@ -507,5 +507,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/expedition_extrafields.php b/htdocs/admin/expedition_extrafields.php
    index af49e5bf064..b7c8ddffa71 100644
    --- a/htdocs/admin/expedition_extrafields.php
    +++ b/htdocs/admin/expedition_extrafields.php
    @@ -87,7 +87,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -100,7 +100,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -119,6 +119,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/expeditiondet_extrafields.php b/htdocs/admin/expeditiondet_extrafields.php
    index 5567e9480e8..cc5a9bddfa5 100644
    --- a/htdocs/admin/expeditiondet_extrafields.php
    +++ b/htdocs/admin/expeditiondet_extrafields.php
    @@ -88,7 +88,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -101,7 +101,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -120,6 +120,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php
    index 1002b146113..78287f71eab 100644
    --- a/htdocs/admin/expensereport.php
    +++ b/htdocs/admin/expensereport.php
    @@ -513,7 +513,6 @@ print '</form>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/expensereport_extrafields.php b/htdocs/admin/expensereport_extrafields.php
    index 8db81edb869..3fedf935405 100644
    --- a/htdocs/admin/expensereport_extrafields.php
    +++ b/htdocs/admin/expensereport_extrafields.php
    @@ -83,7 +83,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -96,7 +96,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -115,6 +115,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/expensereport_ik.php b/htdocs/admin/expensereport_ik.php
    index db7100d5928..d3937a98ba7 100644
    --- a/htdocs/admin/expensereport_ik.php
    +++ b/htdocs/admin/expensereport_ik.php
    @@ -179,6 +179,7 @@ echo '</table>';
     echo '</form>';
     
     dol_fiche_end();
    -llxFooter();
     
    +// End of page
    +llxFooter();
     $db->close();
    diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php
    index b1d65b8635b..7b2baf0ed94 100644
    --- a/htdocs/admin/expensereport_rules.php
    +++ b/htdocs/admin/expensereport_rules.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2012      Mikael Carlavan        <contact@mika-carl.fr>
    - * Copyright (C) 2017      ATM Consulting         <contact@atm-consulting.fr>
    - * Copyright (C) 2017      Pierre-Henry Favre     <phf@atm-consulting.fr>
    +/* Copyright (C) 2012       Mikael Carlavan         <contact@mika-carl.fr>
    + * Copyright (C) 2017       ATM Consulting          <contact@atm-consulting.fr>
    + * Copyright (C) 2017       Pierre-Henry Favre      <phf@atm-consulting.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -182,8 +183,8 @@ if ($action != 'edit')
     
     	echo '<td>'.$form->selectExpense('', 'fk_c_type_fees', 0, 1, 1).'</td>';
     	echo '<td>'.$form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0).'</td>';
    -	echo '<td>'.$form->select_date(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0, 1).'</td>';
    -	echo '<td>'.$form->select_date(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0, 1).'</td>';
    +	echo '<td>'.$form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0).'</td>';
    +	echo '<td>'.$form->selectDate(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0).'</td>';
     	echo '<td><input type="text" value="" name="amount" class="amount" />'.$conf->currency.'</td>';
     	echo '<td>'.$form->selectyesno('restrictive', 0, 1).'</td>';
     	echo '<td align="right"><input type="submit" class="button" value="'.$langs->trans('Add').'" /></td>';
    @@ -270,7 +271,7 @@ foreach ($rules as $rule)
     	echo '<td>';
     	if ($action == 'edit' && $object->id == $rule->id)
     	{
    -		echo $form->select_date(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0, 1);
    +		print $form->selectDate(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0);
     	}
     	else
     	{
    @@ -282,7 +283,7 @@ foreach ($rules as $rule)
     	echo '<td>';
     	if ($action == 'edit' && $object->id == $rule->id)
     	{
    -		echo $form->select_date(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0, 1);
    +		print $form->selectDate(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0);
     	}
     	else
     	{
    @@ -354,6 +355,7 @@ echo '<script type="text/javascript"> $(function() {
     }); </script>';
     
     dol_fiche_end();
    -llxFooter();
     
    +// End of page
    +llxFooter();
     $db->close();
    diff --git a/htdocs/admin/export.php b/htdocs/admin/export.php
    index b6f12a723ff..292c3604799 100644
    --- a/htdocs/admin/export.php
    +++ b/htdocs/admin/export.php
    @@ -6,7 +6,7 @@
      * Copyright (C) 2004		Eric Seigne				<eric.seigne@ryxeo.com>
      * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2011-2012	Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2011-2015	Philippe Grand			<philippe.grand@atoo-net.com>
    + * Copyright (C) 2011-2018	Philippe Grand			<philippe.grand@atoo-net.com>
      *
      * 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
    @@ -32,9 +32,7 @@ require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array('admin', 'exports'));
    -
    -$langs->load('other');
    +$langs->loadLangs(array('admin', 'exports', 'other'));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -73,7 +71,7 @@ dol_fiche_head(
     
     // Setup page goes here
     $form=new Form($db);
    -$var=false;
    +
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("ExportModel").'</td>'."\n";
    @@ -82,8 +80,7 @@ print '<td align="center" width="100"></td>'."\n";
     
     
     // Example with a yes / no select
    -$var=!$var;
    -print '<tr '.$bc[$var].'>';
    +print '<tr class="oddeven">';
     print '<td>'.$langs->trans("set_EXPORTS_SHARE_MODELS").'</td>';
     print '<td align="center" width="20">&nbsp;</td>';
     print '<td align="center" width="100">';
    @@ -94,9 +91,8 @@ echo ajax_constantonoff('EXPORTS_SHARE_MODELS');
     print '</form>';
     print '</td></tr>';
     
    -
     print '</table>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/external_rss.php b/htdocs/admin/external_rss.php
    index 2862a94c207..970971c8d29 100644
    --- a/htdocs/admin/external_rss.php
    +++ b/htdocs/admin/external_rss.php
    @@ -325,6 +325,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php
    index f00d125a4d5..5cb093cc443 100644
    --- a/htdocs/admin/facture.php
    +++ b/htdocs/admin/facture.php
    @@ -238,6 +238,30 @@ if ($action == 'setforcedate')
         }
     }
     
    +if ($action == 'setDefaultPDFModulesByType')
    +{
    +    $invoicetypemodels =  GETPOST('invoicetypemodels');
    +    
    +    if(!empty($invoicetypemodels) && is_array($invoicetypemodels))
    +    {
    +        $error = 0;
    +        
    +        foreach ($invoicetypemodels as $type => $value)
    +        {
    +            $res = dolibarr_set_const($db, 'FACTURE_ADDON_PDF_'.intval($type),$value,'chaine',0,'',$conf->entity);
    +            if (! $res > 0) $error++;
    +        }
    +        
    +        if (! $error)
    +        {
    +            setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +        }
    +        else
    +        {
    +            setEventMessages($langs->trans("Error"), null, 'errors');
    +        }
    +    }
    +}
     
     
     /*
    @@ -410,7 +434,6 @@ foreach ($dirmodels as $reldir)
                                 print '</td>';
     
                                 print "</tr>\n";
    -
                             }
                         }
                     }
    @@ -465,6 +488,8 @@ print "</tr>\n";
     
     clearstatcache();
     
    +$activatedModels = array();
    +
     foreach ($dirmodels as $reldir)
     {
         foreach (array('','/doc') as $valdir)
    @@ -580,6 +605,47 @@ foreach ($dirmodels as $reldir)
     }
     print '</table>';
     
    +if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) // Hidden conf
    +{
    +    /*
    +     *  Document templates generators
    +     */
    +    print '<br>';
    +    print load_fiche_titre($langs->trans("BillsPDFModulesAccordindToInvoiceType"),'','');
    +    print '<form action="'.$_SERVER["PHP_SELF"].'#default-pdf-modules-by-type-table" method="POST">';
    +    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
    +    print '<input type="hidden" name="action" value="setDefaultPDFModulesByType" >';
    +    print '<table id="default-pdf-modules-by-type-table" class="noborder" width="100%">';
    +    print '<tr class="liste_titre">';
    +    print '<td>'.$langs->trans("Type").'</td>';
    +    print '<td>'.$langs->trans("Name").'</td>';
    +    print '<td align="right"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
    +    print "</tr>\n";
    +    
    +    $listtype=array(
    +        Facture::TYPE_STANDARD=>$langs->trans("InvoiceStandard"),
    +        Facture::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"),
    +        Facture::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"),
    +        Facture::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"),
    +    );
    +    if (! empty($conf->global->INVOICE_USE_SITUATION))
    +    {
    +        $listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation");
    +    }
    +    
    +    foreach ($listtype as $type => $trans)
    +    {
    +        $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type;
    +        $current = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF;
    +        print '<tr >';
    +        print '<td>'.$trans.'</td>';
    +        print '<td colspan="2" >'.$form->selectarray('invoicetypemodels['.$type.']', ModelePDFFactures::liste_modeles($db), $current,0,0, 0).'</td>';
    +        print "</tr>\n";
    +    }
    +    
    +    print '</table>';
    +    print "</form>";
    +}
     
     /*
      *  Modes de reglement
    @@ -662,6 +728,7 @@ if ($resql)
         $i = 0;
         while ($i < $num)
         {
    +
             $row = $db->fetch_row($resql);
     
             print '<option value="'.$row[0].'"';
    @@ -782,7 +849,6 @@ print '</table>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/fckeditor.php b/htdocs/admin/fckeditor.php
    index 19d4a4cc772..bed1d4d9bcb 100644
    --- a/htdocs/admin/fckeditor.php
    +++ b/htdocs/admin/fckeditor.php
    @@ -234,6 +234,6 @@ else
          */
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php
    index a216f2d4ab7..c714c0c6c1b 100644
    --- a/htdocs/admin/fichinter.php
    +++ b/htdocs/admin/fichinter.php
    @@ -6,7 +6,7 @@
      * Copyright (C) 2005-2014 Regis Houssin                <regis.houssin@capnetworks.com>
      * Copyright (C) 2008      Raphael Bertrand (Resultic)  <raphael.bertrand@resultic.fr>
      * Copyright (C) 2011-2013 Juanjo Menent			    <jmenent@2byte.es>
    - * Copyright (C) 2011-2017 Philippe Grand			    <philippe.grand@atoo-net.com>
    + * Copyright (C) 2011-2018 Philippe Grand			    <philippe.grand@atoo-net.com>
      *
      * 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
    @@ -560,7 +560,6 @@ print "</td></tr>\n";
     print '</form>';
     
     //Use draft Watermark
    -
     print "<form method=\"post\" action=\"".$_SERVER["PHP_SELF"]."\">";
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     print "<input type=\"hidden\" name=\"action\" value=\"set_FICHINTER_DRAFT_WATERMARK\">";
    @@ -635,12 +634,10 @@ print '</td>';
     print '</tr>';
     print '</form>';
     
    -
    -
    -
     print '</table>';
     
     print '<br>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/geoipmaxmind.php b/htdocs/admin/geoipmaxmind.php
    index 9c944324527..9f154591f0f 100644
    --- a/htdocs/admin/geoipmaxmind.php
    +++ b/htdocs/admin/geoipmaxmind.php
    @@ -153,6 +153,6 @@ if ($geoip)
     	$geoip->close();
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php
    new file mode 100644
    index 00000000000..81becbaa37c
    --- /dev/null
    +++ b/htdocs/admin/holiday.php
    @@ -0,0 +1,523 @@
    +<?php
    +/* Copyright (C) 2011-2013      Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2011-2018      Philippe Grand	    <philippe.grand@atoo-net.com>
    + * Copyright (C) 2018		    Charlene Benke		<charlie@patas-monkey.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *	\file       htdocs/admin/contract.php
    + *	\ingroup    contract
    + *	\brief      Setup page of module Contracts
    + */
    +
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/holiday.lib.php';
    +
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin", "errors", "holiday"));
    +
    +if (!$user->admin) accessforbidden();
    +
    +$action = GETPOST('action','alpha');
    +$value = GETPOST('value','alpha');
    +$label = GETPOST('label','alpha');
    +$scandir = GETPOST('scan_dir','alpha');
    +$type='contract';
    +
    +if (empty($conf->global->HOLIDAY_ADDON))
    +{
    +    $conf->global->HOLIDAY_ADDON='mod_holiday_madona';
    +}
    +
    +
    +/*
    + * Actions
    + */
    +
    +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
    +
    +if ($action == 'updateMask')
    +{
    +    $maskconst = GETPOST('maskconstholidaty','alpha');
    +    $maskvalue =  GETPOST('maskholiday','alpha');
    +    if ($maskconst) $res = dolibarr_set_const($db,$maskconst,$maskvalue,'chaine',0,'',$conf->entity);
    +
    +    if (! $res > 0) $error++;
    +
    + 	if (! $error)
    +    {
    +        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        setEventMessages($langs->trans("Error"), null, 'errors');
    +    }
    +}
    +
    +else if ($action == 'specimen') // For contract
    +{
    +	$modele= GETPOST('module','alpha');
    +
    +	$contract = new Contrat($db);
    +	$contract->initAsSpecimen();
    +
    +	// Search template files
    +	$file=''; $classname=''; $filefound=0;
    +	$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
    +	foreach($dirmodels as $reldir)
    +	{
    +	    $file=dol_buildpath($reldir."core/modules/holiday/doc/pdf_".$modele.".modules.php",0);
    +		if (file_exists($file))
    +		{
    +			$filefound=1;
    +			$classname = "pdf_".$modele;
    +			break;
    +		}
    +	}
    +
    +	if ($filefound)
    +	{
    +		require_once $file;
    +
    +		$module = new $classname($db);
    +
    +		if ($module->write_file($contract,$langs) > 0)
    +		{
    +			header("Location: ".DOL_URL_ROOT."/document.php?modulepart=holiday&file=SPECIMEN.pdf");
    +			return;
    +		}
    +		else
    +		{
    +			setEventMessages($obj->error, $obj->errors, 'errors');
    +			dol_syslog($obj->error, LOG_ERR);
    +		}
    +	}
    +	else
    +	{
    +		setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
    +		dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
    +	}
    +}
    +
    +// Activate a model
    +else if ($action == 'set')
    +{
    +	$ret = addDocumentModel($value, $type, $label, $scandir);
    +}
    +
    +else if ($action == 'del')
    +{
    +	$ret = delDocumentModel($value, $type);
    +	if ($ret > 0)
    +	{
    +        if ($conf->global->HOLIDAY_ADDON_PDF == "$value") dolibarr_del_const($db, 'HOLIDAY_ADDON_PDF',$conf->entity);
    +	}
    +}
    +
    +// Set default model
    +else if ($action == 'setdoc')
    +{
    +	if (dolibarr_set_const($db, "HOLIDAY_ADDON_PDF",$value,'chaine',0,'',$conf->entity))
    +	{
    +		// La constante qui a ete lue en avant du nouveau set
    +		// on passe donc par une variable pour avoir un affichage coherent
    +		$conf->global->HOLIDAY_ADDON_PDF = $value;
    +	}
    +
    +	// On active le modele
    +	$ret = delDocumentModel($value, $type);
    +	if ($ret > 0)
    +	{
    +		$ret = addDocumentModel($value, $type, $label, $scandir);
    +	}
    +}
    +
    +else if ($action == 'setmod')
    +{
    +	// TODO Verifier si module numerotation choisi peut etre active
    +	// par appel methode canBeActivated
    +
    +	dolibarr_set_const($db, "HOLIDAY_ADDON",$value,'chaine',0,'',$conf->entity);
    +}
    +
    +else if ($action == 'set_other')
    +{
    +	$freetext= GETPOST('HOLIDAY_FREE_TEXT','none');	// No alpha here, we want exact string
    +	$res1 = dolibarr_set_const($db, "HOLIDAY_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity);
    +
    +	$draft= GETPOST('HOLIDAY_DRAFT_WATERMARK','alpha');
    +	$res2 = dolibarr_set_const($db, "HOLIDAY_DRAFT_WATERMARK",trim($draft),'chaine',0,'',$conf->entity);
    +
    +	if (! $res1 > 0 || ! $res2 > 0) $error++;
    +
    + 	if (! $error)
    +    {
    +        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        setEventMessages($langs->trans("Error"), null, 'errors');
    +    }
    +}
    +
    +
    +/*
    + * View
    + */
    +
    +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
    +
    +llxHeader();
    +
    +$form=new Form($db);
    +
    +$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
    +print load_fiche_titre($langs->trans("HolidaySetup"),$linkback,'title_setup');
    +
    +$head=holiday_admin_prepare_head();
    +
    +dol_fiche_head($head, 'holiday', $langs->trans("Holidays"), -1, 'holiday');
    +
    +/*
    + * Holiday Numbering model
    + */
    +
    +print load_fiche_titre($langs->trans("HolidaysNumberingModules"),'','');
    +
    +print '<table class="noborder" width="100%">';
    +print '<tr class="liste_titre">';
    +print '<td width="100">'.$langs->trans("Name").'</td>';
    +print '<td>'.$langs->trans("Description").'</td>';
    +print '<td>'.$langs->trans("Example").'</td>';
    +print '<td align="center" width="60">'.$langs->trans("Status").'</td>';
    +print '<td align="center" width="16">'.$langs->trans("ShortInfo").'</td>';
    +print "</tr>\n";
    +
    +clearstatcache();
    +
    +foreach ($dirmodels as $reldir)
    +{
    +	$dir = dol_buildpath($reldir."core/modules/holiday/");
    +
    +	if (is_dir($dir))
    +	{
    +		$handle = opendir($dir);
    +		if (is_resource($handle))
    +		{
    +			$var=true;
    +
    +			while (($file = readdir($handle))!==false)
    +			{
    +				if (substr($file, 0, 12) == 'mod_holiday_' && substr($file, dol_strlen($file)-3, 3) == 'php')
    +				{
    +					$file = substr($file, 0, dol_strlen($file)-4);
    +
    +					require_once $dir.$file.'.php';
    +
    +					$module = new $file($db);
    +
    +					// Show modules according to features level
    +					if ($module->version == 'development'  && $conf->global->MAIN_FEATURES_LEVEL < 2) continue;
    +					if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue;
    +
    +					if ($module->isEnabled())
    +					{
    +
    +						print '<tr class="oddeven"><td>'.$module->nom."</td><td>\n";
    +						print $module->info();
    +						print '</td>';
    +
    +						// Show example of numbering model
    +						print '<td class="nowrap">';
    +						$tmp=$module->getExample();
    +						if (preg_match('/^Error/',$tmp)) { $langs->load("errors"); print '<div class="error">'.$langs->trans($tmp).'</div>'; }
    +						elseif ($tmp=='NotConfigured') print $langs->trans($tmp);
    +						else print $tmp;
    +						print '</td>'."\n";
    +
    +						print '<td align="center">';
    +						if ($conf->global->HOLIDAY_ADDON == "$file")
    +						{
    +							print img_picto($langs->trans("Activated"),'switch_on');
    +						}
    +						else
    +						{
    +							print '<a href="'.$_SERVER["PHP_SELF"].'?action=setmod&amp;value='.$file.'">';
    +							print img_picto($langs->trans("Disabled"),'switch_off');
    +							print '</a>';
    +						}
    +						print '</td>';
    +
    +						$holiday=new Holiday($db);
    +						$holiday->initAsSpecimen();
    +
    +						// Info
    +						$htmltooltip='';
    +						$htmltooltip.=''.$langs->trans("Version").': <b>'.$module->getVersion().'</b><br>';
    +						$nextval=$module->getNextValue($mysoc,$contract);
    +                        if ("$nextval" != $langs->trans("NotAvailable")) {  // Keep " on nextval
    +                            $htmltooltip.=''.$langs->trans("NextValue").': ';
    +                            if ($nextval) {
    +                                if (preg_match('/^Error/',$nextval) || $nextval=='NotConfigured')
    +                                    $nextval = $langs->trans($nextval);
    +                                $htmltooltip.=$nextval.'<br>';
    +                            } else {
    +                                $htmltooltip.=$langs->trans($module->error).'<br>';
    +                            }
    +                        }
    +
    +						print '<td align="center">';
    +						print $form->textwithpicto('',$htmltooltip,1,0);
    +						print '</td>';
    +
    +						print '</tr>';
    +					}
    +				}
    +			}
    +			closedir($handle);
    +		}
    +	}
    +}
    +
    +print '</table><br>';
    +
    +
    +
    +if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
    +{
    +
    +/*
    + *  Documents models for Holidays
    + */
    +
    +print load_fiche_titre($langs->trans("TemplatePDFHolidays"),'','');
    +
    +// Defini tableau def des modeles
    +$def = array();
    +$sql = "SELECT nom";
    +$sql.= " FROM ".MAIN_DB_PREFIX."document_model";
    +$sql.= " WHERE type = '".$type."'";
    +$sql.= " AND entity = ".$conf->entity;
    +$resql=$db->query($sql);
    +if ($resql)
    +{
    +	$i = 0;
    +	$num_rows=$db->num_rows($resql);
    +	while ($i < $num_rows)
    +	{
    +		$array = $db->fetch_array($resql);
    +		array_push($def, $array[0]);
    +		$i++;
    +	}
    +}
    +else
    +{
    +	dol_print_error($db);
    +}
    +
    +
    +print '<table class="noborder" width="100%">';
    +print '<tr class="liste_titre">';
    +print '<td>'.$langs->trans("Name").'</td>';
    +print '<td>'.$langs->trans("Description").'</td>';
    +print '<td align="center" width="60">'.$langs->trans("Status")."</td>\n";
    +print '<td align="center" width="60">'.$langs->trans("Default")."</td>\n";
    +print '<td align="center" width="80">'.$langs->trans("ShortInfo").'</td>';
    +print '<td align="center" width="80">'.$langs->trans("Preview").'</td>';
    +print "</tr>\n";
    +
    +clearstatcache();
    +
    +foreach ($dirmodels as $reldir)
    +{
    +    foreach (array('','/doc') as $valdir)
    +    {
    +    	$dir = dol_buildpath($reldir."core/modules/holiday".$valdir);
    +
    +        if (is_dir($dir))
    +        {
    +            $handle=opendir($dir);
    +            if (is_resource($handle))
    +            {
    +                while (($file = readdir($handle))!==false)
    +                {
    +                    $filelist[]=$file;
    +                }
    +                closedir($handle);
    +                arsort($filelist);
    +
    +                foreach($filelist as $file)
    +                {
    +                    if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file))
    +                    {
    +
    +                    	if (file_exists($dir.'/'.$file))
    +                    	{
    +                    		$name = substr($file, 4, dol_strlen($file) -16);
    +	                        $classname = substr($file, 0, dol_strlen($file) -12);
    +
    +	                        require_once $dir.'/'.$file;
    +	                        $module = new $classname($db);
    +
    +	                        $modulequalified=1;
    +	                        if ($module->version == 'development'  && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0;
    +	                        if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0;
    +
    +	                        if ($modulequalified)
    +	                        {
    +	                            print '<tr class="oddeven"><td width="100">';
    +	                            print (empty($module->name)?$name:$module->name);
    +	                            print "</td><td>\n";
    +	                            if (method_exists($module,'info')) print $module->info($langs);
    +	                            else print $module->description;
    +	                            print '</td>';
    +
    +	                            // Active
    +	                            if (in_array($name, $def))
    +	                            {
    +	                            	print '<td align="center">'."\n";
    +	                            	print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'">';
    +	                            	print img_picto($langs->trans("Enabled"),'switch_on');
    +	                            	print '</a>';
    +	                            	print '</td>';
    +	                            }
    +	                            else
    +	                            {
    +	                                print '<td align="center">'."\n";
    +	                                print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>';
    +	                                print "</td>";
    +	                            }
    +
    +	                            // Defaut
    +	                            print '<td align="center">';
    +	                            if ($conf->global->HOLIDAY_ADDON_PDF == $name)
    +	                            {
    +	                                print img_picto($langs->trans("Default"),'on');
    +	                            }
    +	                            else
    +	                            {
    +	                                print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&amp;scan_dir='.$module->scandir.'&amp;label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
    +	                            }
    +	                            print '</td>';
    +
    +	                           // Info
    +		    					$htmltooltip =    ''.$langs->trans("Name").': '.$module->name;
    +					    		$htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown"));
    +			                    if ($module->type == 'pdf')
    +			                    {
    +			                        $htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
    +			                    }
    +					    		$htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
    +					    		$htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1);
    +					    		$htmltooltip.='<br>'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1);
    +					    		$htmltooltip.='<br>'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1);
    +					    		$htmltooltip.='<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1);
    +					    		$htmltooltip.='<br>'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1);
    +
    +
    +	                            print '<td align="center">';
    +	                            print $form->textwithpicto('',$htmltooltip,1,0);
    +	                            print '</td>';
    +
    +	                            // Preview
    +	                            print '<td align="center">';
    +	                            if ($module->type == 'pdf')
    +	                            {
    +	                                print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'contract').'</a>';
    +	                            }
    +	                            else
    +	                            {
    +	                                print img_object($langs->trans("PreviewNotAvailable"),'generic');
    +	                            }
    +	                            print '</td>';
    +
    +	                            print "</tr>\n";
    +	                        }
    +                    	}
    +                    }
    +                }
    +            }
    +        }
    +    }
    +}
    +
    +print '</table>';
    +print "<br>";
    +
    +
    +/*
    + * Other options
    + */
    +
    +print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
    +print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +print '<input type="hidden" name="action" value="set_other">';
    +
    +print load_fiche_titre($langs->trans("OtherOptions"),'','');
    +print '<table class="noborder" width="100%">';
    +print '<tr class="liste_titre">';
    +print '<td>'.$langs->trans("Parameter").'</td>';
    +print '<td align="center" width="60">'.$langs->trans("Value").'</td>';
    +print "</tr>\n";
    +
    +$substitutionarray=pdf_getSubstitutionArray($langs, array('objectamount'), null, 2);
    +$substitutionarray['__(AnyTranslationKey)__']=$langs->trans("Translation");
    +$htmltext = '<i>'.$langs->trans("AvailableVariables").':<br>';
    +foreach($substitutionarray as $key => $val)	$htmltext.=$key.'<br>';
    +$htmltext.='</i>';
    +
    +print '<tr class="oddeven"><td colspan="2">';
    +print $form->textwithpicto($langs->trans("FreeLegalTextOnHolidays"), $langs->trans("AddCRIfTooLong").'<br><br>'.$htmltext, 1, 'help', '', 0, 2, 'tooltiphelp');
    +print '<br>';
    +$variablename='HOLIDAY_FREE_TEXT';
    +if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT))
    +{
    +    print '<textarea name="'.$variablename.'" class="flat" cols="120">'.$conf->global->$variablename.'</textarea>';
    +}
    +else
    +{
    +    include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    +    $doleditor=new DolEditor($variablename, $conf->global->$variablename,'',80,'dolibarr_notes');
    +    print $doleditor->Create();
    +}
    +print '</td></tr>'."\n";
    +
    +//Use draft Watermark
    +
    +print '<tr class="oddeven"><td>';
    +print $form->textwithpicto($langs->trans("WatermarkOnDraftHolidayCards"), $htmltext, 1, 'help', '', 0, 2, 'watermarktooltip').'<br>';
    +print '</td><td>';
    +print '<input size="50" class="flat" type="text" name="HOLIDAY_DRAFT_WATERMARK" value="'.$conf->global->HOLIDAY_DRAFT_WATERMARK.'">';
    +print '</td></tr>'."\n";
    +
    +print '</table>';
    +
    +print '<div class="center">';
    +print '<input type="submit" class="button" value="'.$langs->trans("Save").'">';
    +print '</div>';
    +
    +print '</form>';
    +}
    +
    +
    +dol_fiche_end();
    +
    +// End of page
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php
    index 50edc32d55f..8861d1abb68 100644
    --- a/htdocs/admin/ihm.php
    +++ b/htdocs/admin/ihm.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2004-2015	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2005-2017	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2016		Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
      *
      * 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
    @@ -79,10 +80,10 @@ if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACK
     
     if ($action == 'update')
     {
    -	dolibarr_set_const($db, "MAIN_LANG_DEFAULT",				$_POST["MAIN_LANG_DEFAULT"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MULTILANGS",					$_POST["MAIN_MULTILANGS"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_LANG_DEFAULT", $_POST["MAIN_LANG_DEFAULT"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MULTILANGS", $_POST["MAIN_MULTILANGS"],'chaine',0,'',$conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_THEME",						$_POST["main_theme"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_THEME", $_POST["main_theme"],'chaine',0,'',$conf->entity);
     
     	$val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE');
     	if (! $val) dolibarr_del_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', $conf->entity);
    @@ -133,21 +134,24 @@ if ($action == 'update')
     	if (GETPOST('THEME_ELDY_USE_HOVER') == '') dolibarr_set_const($db, "THEME_ELDY_USE_HOVER", '0', 'chaine', 0, '', $conf->entity);    // If empty, we set to '0' ('000000' is for black)
     	else dolibarr_set_const($db, "THEME_ELDY_USE_HOVER", $_POST["THEME_ELDY_USE_HOVER"], 'chaine', 0, '', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT",			$_POST["main_size_liste_limit"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT",		$_POST["main_size_shortliste_limit"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_DISABLE_JAVASCRIPT",			$_POST["main_disable_javascript"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_BUTTON_HIDE_UNAUTHORIZED",	$_POST["MAIN_BUTTON_HIDE_UNAUTHORIZED"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_START_WEEK",					$_POST["MAIN_START_WEEK"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_DAYS",		$_POST["MAIN_DEFAULT_WORKING_DAYS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_HOURS",		$_POST["MAIN_DEFAULT_WORKING_HOURS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_SHOW_LOGO",					$_POST["MAIN_SHOW_LOGO"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION",		$_POST["MAIN_FIRSTNAME_NAME_POSITION"],'chaine',0,'',$conf->entity);
    +	if (GETPOST('THEME_ELDY_USE_CHECKED') == '') dolibarr_set_const($db, "THEME_ELDY_USE_CHECKED", '0', 'chaine', 0, '', $conf->entity);
    +	else dolibarr_set_const($db, "THEME_ELDY_USE_CHECKED", $_POST["THEME_ELDY_USE_CHECKED"], 'chaine', 0, '', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_HELPCENTER_DISABLELINK",		$_POST["MAIN_HELPCENTER_DISABLELINK"],'chaine',0,'',0);	// Param for all entities
    -	dolibarr_set_const($db, "MAIN_MOTD",						dol_htmlcleanlastbr($_POST["main_motd"]),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_HOME",						dol_htmlcleanlastbr($_POST["main_home"]),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_HELP_DISABLELINK",			$_POST["MAIN_HELP_DISABLELINK"],'chaine',0,'',0);	    // Param for all entities
    -	dolibarr_set_const($db, "MAIN_BUGTRACK_ENABLELINK",         $_POST["MAIN_BUGTRACK_ENABLELINK"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", $_POST["main_size_liste_limit"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", $_POST["main_size_shortliste_limit"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_DISABLE_JAVASCRIPT", $_POST["main_disable_javascript"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_BUTTON_HIDE_UNAUTHORIZED", $_POST["MAIN_BUTTON_HIDE_UNAUTHORIZED"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_START_WEEK", $_POST["MAIN_START_WEEK"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_DAYS", $_POST["MAIN_DEFAULT_WORKING_DAYS"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_HOURS", $_POST["MAIN_DEFAULT_WORKING_HOURS"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_SHOW_LOGO", $_POST["MAIN_SHOW_LOGO"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION", $_POST["MAIN_FIRSTNAME_NAME_POSITION"],'chaine',0,'',$conf->entity);
    +
    +	dolibarr_set_const($db, "MAIN_HELPCENTER_DISABLELINK", $_POST["MAIN_HELPCENTER_DISABLELINK"],'chaine',0,'',0);	// Param for all entities
    +	dolibarr_set_const($db, "MAIN_MOTD", dol_htmlcleanlastbr($_POST["main_motd"]),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_HOME", dol_htmlcleanlastbr($_POST["main_home"]),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_HELP_DISABLELINK", $_POST["MAIN_HELP_DISABLELINK"],'chaine',0,'',0);	    // Param for all entities
    +	dolibarr_set_const($db, "MAIN_BUGTRACK_ENABLELINK", $_POST["MAIN_BUGTRACK_ENABLELINK"],'chaine',0,'',$conf->entity);
     
     	$varforimage='imagebackground'; $dirforimage=$conf->mycompany->dir_output.'/logos/';
     	if ($_FILES[$varforimage]["tmp_name"])
    @@ -236,7 +240,7 @@ if ($action == 'edit')	// Edit
     
     	// Default language
     	print '<tr><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>';
    -	print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300');
    +	print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300', 2);
     	print '</td>';
     	print '<td width="20">&nbsp;</td>';
     	print '</tr>';
    @@ -413,7 +417,7 @@ if ($action == 'edit')	// Edit
     		print '<a href="'.$_SERVER["PHP_SELF"].'?action=removebackgroundlogin">'.img_delete($langs->trans("Delete")).'</a>';
     		if (file_exists($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) {
     			print ' &nbsp; ';
    -			print '<img class="paddingleft valignmiddle" width="100px" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('/'.$conf->global->MAIN_LOGIN_BACKGROUND).'">';
    +			print '<img class="paddingleft valignmiddle" width="100px" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/'.$conf->global->MAIN_LOGIN_BACKGROUND).'">';
     		}
     	} else {
     		print '<img class="paddingleft valignmiddle" width="100" src="'.DOL_URL_ROOT.'/public/theme/common/nophoto.png">';
    @@ -561,7 +565,7 @@ else	// Show
     	print $conf->global->MAIN_LOGIN_BACKGROUND;
     	if ($conf->global->MAIN_LOGIN_BACKGROUND && is_file($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND))
     	{
    -		print '<img class="img_logo paddingleft valignmiddle" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'">';
    +		print '<img class="img_logo paddingleft valignmiddle" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/'.$conf->global->MAIN_LOGIN_BACKGROUND).'">';
     	}
     	else
     	{
    @@ -578,6 +582,6 @@ else	// Show
     	print '</div>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php
    index 6542cec1174..be9859c1beb 100644
    --- a/htdocs/admin/index.php
    +++ b/htdocs/admin/index.php
    @@ -89,6 +89,14 @@ print '<br>';
     
     // Show info setup module
     print img_picto('','puce').' '.$langs->trans("SetupDescription4", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentities("Setup"), $langs->transnoentities("Modules"));
    +
    +/*
    +$nbofactivatedmodules=count($conf->modules);
    +$moreinfo=$langs->trans("TotalNumberOfActivatedModules",($nbofactivatedmodules-1), count($modules));
    +if ($nbofactivatedmodules <= 1) $moreinfo .= ' '.img_warning($langs->trans("YouMustEnableOneModule"));
    +print '<br>'.$moreinfo;
    +*/
    +
     if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)?1:$conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING))	// If only user module enabled
     {
     	$langs->load("errors");
    @@ -114,7 +122,6 @@ if (empty($reshook))
     	print '<div class="center"><div class="logo_setup"></div></div>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php
    index 6776cfb1480..1f7b803a50e 100644
    --- a/htdocs/admin/ldap.php
    +++ b/htdocs/admin/ldap.php
    @@ -336,9 +336,9 @@ if (function_exists("ldap_connect"))
     			print $langs->trans("Error").' '.$ldap->error;
     			print '<br>';
     		}
    -
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/ldap_contacts.php b/htdocs/admin/ldap_contacts.php
    index 3188bf6e58a..dd85a998383 100644
    --- a/htdocs/admin/ldap_contacts.php
    +++ b/htdocs/admin/ldap_contacts.php
    @@ -318,6 +318,7 @@ if (function_exists("ldap_connect"))
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php
    index 4ae6ce9ad97..2650fe4fe6e 100644
    --- a/htdocs/admin/ldap_groups.php
    +++ b/htdocs/admin/ldap_groups.php
    @@ -251,5 +251,6 @@ if (function_exists("ldap_connect"))
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/ldap_members.php b/htdocs/admin/ldap_members.php
    index 616eb99a8da..61da334a90d 100644
    --- a/htdocs/admin/ldap_members.php
    +++ b/htdocs/admin/ldap_members.php
    @@ -80,9 +80,9 @@ if ($action == 'setvalue' && $user->admin)
     	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION', GETPOST("fieldendlastsubscription"),'chaine',0,'',$conf->entity)) $error++;
     
     	// Subscriptions
    -	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE',  GETPOST("fieldfirstsubscriptiondate"),'chaine',0,'',$conf->entity)) $error++;
    +	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE', GETPOST("fieldfirstsubscriptiondate"),'chaine',0,'',$conf->entity)) $error++;
     	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT',GETPOST("fieldfirstsubscriptionamount"),'chaine',0,'',$conf->entity)) $error++;
    -	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE',   GETPOST("fieldlastsubscriptiondate"),'chaine',0,'',$conf->entity)) $error++;
    +	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE', GETPOST("fieldlastsubscriptiondate"),'chaine',0,'',$conf->entity)) $error++;
     	if (! dolibarr_set_const($db, 'LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT', GETPOST("fieldlastsubscriptionamount"),'chaine',0,'',$conf->entity)) $error++;
     
     	// This one must be after the others
    @@ -439,10 +439,8 @@ if (function_exists("ldap_connect"))
     			print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'<br>';
     		}
     	}
    -
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php
    index e45857f2f38..e845fd37adc 100644
    --- a/htdocs/admin/ldap_members_types.php
    +++ b/htdocs/admin/ldap_members_types.php
    @@ -241,5 +241,6 @@ if (function_exists("ldap_connect"))
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php
    index 8b11069fc61..87df901cfa9 100644
    --- a/htdocs/admin/ldap_users.php
    +++ b/htdocs/admin/ldap_users.php
    @@ -443,7 +443,6 @@ if (function_exists("ldap_connect"))
     					}
     					$liste[$key] = $label;
     				}
    -
     			}
     			else
     		   {
    @@ -470,5 +469,6 @@ if (function_exists("ldap_connect"))
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/limits.php b/htdocs/admin/limits.php
    index e9389b0271d..ca4b8fca512 100644
    --- a/htdocs/admin/limits.php
    +++ b/htdocs/admin/limits.php
    @@ -66,11 +66,11 @@ if ($action == 'update')
     
         if (! $error)
         {
    -        dolibarr_set_const($db, "MAIN_MAX_DECIMALS_UNIT",   $_POST["MAIN_MAX_DECIMALS_UNIT"],'chaine',0,'',$conf->entity);
    -        dolibarr_set_const($db, "MAIN_MAX_DECIMALS_TOT",    $_POST["MAIN_MAX_DECIMALS_TOT"],'chaine',0,'',$conf->entity);
    -        dolibarr_set_const($db, "MAIN_MAX_DECIMALS_SHOWN",  $_POST["MAIN_MAX_DECIMALS_SHOWN"],'chaine',0,'',$conf->entity);
    +        dolibarr_set_const($db, "MAIN_MAX_DECIMALS_UNIT", $_POST["MAIN_MAX_DECIMALS_UNIT"],'chaine',0,'',$conf->entity);
    +        dolibarr_set_const($db, "MAIN_MAX_DECIMALS_TOT", $_POST["MAIN_MAX_DECIMALS_TOT"],'chaine',0,'',$conf->entity);
    +        dolibarr_set_const($db, "MAIN_MAX_DECIMALS_SHOWN", $_POST["MAIN_MAX_DECIMALS_SHOWN"],'chaine',0,'',$conf->entity);
     
    -        dolibarr_set_const($db, "MAIN_ROUNDING_RULE_TOT",   $_POST["MAIN_ROUNDING_RULE_TOT"],'chaine',0,'',$conf->entity);
    +        dolibarr_set_const($db, "MAIN_ROUNDING_RULE_TOT", $_POST["MAIN_ROUNDING_RULE_TOT"],'chaine',0,'',$conf->entity);
     
             header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
             exit;
    @@ -253,7 +253,6 @@ else
     	    print " x ".$langs->trans("Quantity").": ".$qty;
     	    print " - ".$langs->trans("VAT").": ".$vat.'%';
     	    print " &nbsp; -> &nbsp; ".$langs->trans("TotalPriceAfterRounding").": ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."<br>\n";
    -
     	}
     
     	// Important: can debug rounding, to simulate the rounded total
    @@ -306,7 +305,6 @@ else
     	*/
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/livraison.php b/htdocs/admin/livraison.php
    index 88ce717f005..91fb9f964e4 100644
    --- a/htdocs/admin/livraison.php
    +++ b/htdocs/admin/livraison.php
    @@ -478,6 +478,7 @@ print '</form>';
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/livraison_extrafields.php b/htdocs/admin/livraison_extrafields.php
    index 6ccf798bc93..55fe6f10362 100644
    --- a/htdocs/admin/livraison_extrafields.php
    +++ b/htdocs/admin/livraison_extrafields.php
    @@ -87,7 +87,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -100,7 +100,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -119,6 +119,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/livraisondet_extrafields.php b/htdocs/admin/livraisondet_extrafields.php
    index 431d5c3c170..e70b4f2d09b 100644
    --- a/htdocs/admin/livraisondet_extrafields.php
    +++ b/htdocs/admin/livraisondet_extrafields.php
    @@ -88,7 +88,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -101,7 +101,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -120,6 +120,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/loan.php b/htdocs/admin/loan.php
    index 3349ac0056a..419f6efbee9 100644
    --- a/htdocs/admin/loan.php
    +++ b/htdocs/admin/loan.php
    @@ -122,5 +122,6 @@ print "</table>\n";
     
     print '<br><div style="text-align:center"><input type="submit" class="button" value="'.$langs->trans('Modify').'" name="button"></div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/mailing.php b/htdocs/admin/mailing.php
    index 32fbdd4aeb6..d5b866d9d20 100644
    --- a/htdocs/admin/mailing.php
    +++ b/htdocs/admin/mailing.php
    @@ -152,6 +152,6 @@ print '<div align="center"><input type="submit" class="button" value="'.$langs->
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/mailman.php b/htdocs/admin/mailman.php
    index b831c13823f..460a2d43abe 100644
    --- a/htdocs/admin/mailman.php
    +++ b/htdocs/admin/mailman.php
    @@ -238,7 +238,6 @@ if (! empty($conf->global->ADHERENT_USE_MAILMAN))
         print '</form>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php
    index 5b6a0841e76..3576ec845d1 100644
    --- a/htdocs/admin/mails.php
    +++ b/htdocs/admin/mails.php
    @@ -65,27 +65,27 @@ complete_substitutions_array($substitutionarrayfortest, $langs);
     
     if ($action == 'update' && empty($_POST["cancel"]))
     {
    -	dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS",     GETPOST("MAIN_DISABLE_ALL_MAILS"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_FORCE_SENDTO",     GETPOST("MAIN_MAIL_FORCE_SENDTO"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_ENABLED_USER_DEST_SELECT",     GETPOST("MAIN_MAIL_ENABLED_USER_DEST_SELECT"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS", GETPOST("MAIN_DISABLE_ALL_MAILS"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_FORCE_SENDTO", GETPOST("MAIN_MAIL_FORCE_SENDTO"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_ENABLED_USER_DEST_SELECT", GETPOST("MAIN_MAIL_ENABLED_USER_DEST_SELECT"), 'chaine', 0, '', $conf->entity);
     	// Send mode parameters
    -	dolibarr_set_const($db, "MAIN_MAIL_SENDMODE",         GETPOST("MAIN_MAIL_SENDMODE"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT",        GETPOST("MAIN_MAIL_SMTP_PORT"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER",      GETPOST("MAIN_MAIL_SMTP_SERVER"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID",         GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW",         GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS",        GETPOST("MAIN_MAIL_EMAIL_TLS"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS",   GETPOST("MAIN_MAIL_EMAIL_STARTTLS"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS", GETPOST("MAIN_MAIL_EMAIL_STARTTLS"), 'chaine', 0, '', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_ENABLED",     GETPOST("MAIN_MAIL_EMAIL_DKIM_ENABLED"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_DOMAIN",      GETPOST("MAIN_MAIL_EMAIL_DKIM_DOMAIN"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_SELECTOR",    GETPOST("MAIN_MAIL_EMAIL_DKIM_SELECTOR"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY", GETPOST("MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_ENABLED", GETPOST("MAIN_MAIL_EMAIL_DKIM_ENABLED"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_DOMAIN", GETPOST("MAIN_MAIL_EMAIL_DKIM_DOMAIN"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_SELECTOR", GETPOST("MAIN_MAIL_EMAIL_DKIM_SELECTOR"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY", GETPOST("MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY"), 'chaine', 0, '', $conf->entity);
     	// Content parameters
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM",       GETPOST("MAIN_MAIL_EMAIL_FROM"), 'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO",		  GETPOST("MAIN_MAIL_ERRORS_TO"),  'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO",      GETPOST("MAIN_MAIL_AUTOCOPY_TO"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, 'MAIN_MAIL_DEFAULT_FROMTYPE', GETPOST('MAIN_MAIL_DEFAULT_FROMTYPE'),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM", GETPOST("MAIN_MAIL_EMAIL_FROM"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO", GETPOST("MAIN_MAIL_ERRORS_TO"), 'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO", GETPOST("MAIN_MAIL_AUTOCOPY_TO"),'chaine', 0, '', $conf->entity);
    +	dolibarr_set_const($db, 'MAIN_MAIL_DEFAULT_FROMTYPE', GETPOST('MAIN_MAIL_DEFAULT_FROMTYPE'), 'chaine', 0, '', $conf->entity);
     
     	header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
     	exit;
    @@ -366,7 +366,7 @@ if ($action == 'edit')
     	{
     
     		$mainstmpid=(! empty($conf->global->MAIN_MAIL_SMTPS_ID)?$conf->global->MAIN_MAIL_SMTPS_ID:'');
    -		print '<tr '.$bcdd[$var].'><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>';
    +		print '<tr class="drag drop oddeven"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>';
     		// SuperAdministrator access only
     		if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity))
     		{
    @@ -386,7 +386,7 @@ if ($action == 'edit')
     	{
     
     		$mainsmtppw=(! empty($conf->global->MAIN_MAIL_SMTPS_PW)?$conf->global->MAIN_MAIL_SMTPS_PW:'');
    -		print '<tr '.$bcdd[$var].'><td>'.$langs->trans("MAIN_MAIL_SMTPS_PW").'</td><td>';
    +		print '<tr class="drag drop oddeven"><td>'.$langs->trans("MAIN_MAIL_SMTPS_PW").'</td><td>';
     		// SuperAdministrator access only
     		if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity))
     		{
    @@ -854,7 +854,6 @@ else
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/mails_emailing.php b/htdocs/admin/mails_emailing.php
    index 91826f2be1d..59fc0ade0cd 100644
    --- a/htdocs/admin/mails_emailing.php
    +++ b/htdocs/admin/mails_emailing.php
    @@ -61,12 +61,12 @@ complete_substitutions_array($substitutionarrayfortest, $langs);
     if ($action == 'update' && empty($_POST["cancel"]))
     {
         // Send mode parameters
    -	dolibarr_set_const($db, "MAIN_MAIL_SENDMODE_EMAILING",       GETPOST("MAIN_MAIL_SENDMODE_EMAILING"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT_EMAILING",      GETPOST("MAIN_MAIL_SMTP_PORT_EMAILING"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER_EMAILING",    GETPOST("MAIN_MAIL_SMTP_SERVER_EMAILING"),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID_EMAILING",       GETPOST("MAIN_MAIL_SMTPS_ID_EMAILING"), 'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW_EMAILING",       GETPOST("MAIN_MAIL_SMTPS_PW_EMAILING"), 'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS_EMAILING",      GETPOST("MAIN_MAIL_EMAIL_TLS_EMAILING"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SENDMODE_EMAILING", GETPOST("MAIN_MAIL_SENDMODE_EMAILING"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT_EMAILING", GETPOST("MAIN_MAIL_SMTP_PORT_EMAILING"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER_EMAILING", GETPOST("MAIN_MAIL_SMTP_SERVER_EMAILING"),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID_EMAILING", GETPOST("MAIN_MAIL_SMTPS_ID_EMAILING"), 'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW_EMAILING", GETPOST("MAIN_MAIL_SMTPS_PW_EMAILING"), 'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS_EMAILING", GETPOST("MAIN_MAIL_EMAIL_TLS_EMAILING"),'chaine',0,'',$conf->entity);
     	dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS_EMAILING", GETPOST("MAIN_MAIL_EMAIL_STARTTLS_EMAILING"),'chaine',0,'',$conf->entity);
     
     	header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
    @@ -601,7 +601,6 @@ else
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php
    index b6268e7fc1e..4914152f680 100644
    --- a/htdocs/admin/mails_senderprofile_list.php
    +++ b/htdocs/admin/mails_senderprofile_list.php
    @@ -23,7 +23,7 @@
      */
     
     require '../main.inc.php';
    -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    @@ -498,7 +498,7 @@ print '</form>'."\n";
     
     if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords))
     {
    -	require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     	$formfile = new FormFile($db);
     
     	$hidegeneratedfilelistifempty=1;
    diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php
    index 206191f5967..ab169afc096 100644
    --- a/htdocs/admin/mails_templates.php
    +++ b/htdocs/admin/mails_templates.php
    @@ -926,6 +926,7 @@ print '</form>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/menus.php b/htdocs/admin/menus.php
    index 083d78c03e5..09907652df0 100644
    --- a/htdocs/admin/menus.php
    +++ b/htdocs/admin/menus.php
    @@ -64,10 +64,10 @@ if ($action == 'update' && ! $cancel)
     {
     	$_SESSION["mainmenu"]="home";   // Le gestionnaire de menu a pu changer
     
    -	dolibarr_set_const($db, "MAIN_MENU_STANDARD",        GETPOST('MAIN_MENU_STANDARD','alpha'),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_MENU_SMARTPHONE",      GETPOST('MAIN_MENU_SMARTPHONE','alpha'),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MENU_STANDARD", GETPOST('MAIN_MENU_STANDARD','alpha'),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MENU_SMARTPHONE", GETPOST('MAIN_MENU_SMARTPHONE','alpha'),'chaine',0,'',$conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_MENUFRONT_STANDARD",   GETPOST('MAIN_MENUFRONT_STANDARD','alpha'),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MENUFRONT_STANDARD", GETPOST('MAIN_MENUFRONT_STANDARD','alpha'),'chaine',0,'',$conf->entity);
     	dolibarr_set_const($db, "MAIN_MENUFRONT_SMARTPHONE", GETPOST('MAIN_MENUFRONT_SMARTPHONE','alpha'),'chaine',0,'',$conf->entity);
     
     	// Define list of menu handlers to initialize
    @@ -269,7 +269,6 @@ if ($action != 'edit')
     	print '</div>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php
    index 191db98a402..0db2d3cd6d1 100644
    --- a/htdocs/admin/menus/edit.php
    +++ b/htdocs/admin/menus/edit.php
    @@ -28,9 +28,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php';
     
    -
    -$langs->load("admin");
    -$langs->load('other');
    +// Load translation files required by the page
    +$langs->loadLangs(array("other","admin"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -514,5 +513,6 @@ elseif ($action == 'edit')
         print '<br>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/menus/index.php b/htdocs/admin/menus/index.php
    index c3211fc2d75..9d0178c956d 100644
    --- a/htdocs/admin/menus/index.php
    +++ b/htdocs/admin/menus/index.php
    @@ -27,8 +27,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
     
    -$langs->load("other");
    -$langs->load("admin");
    +// Load translation files required by the page
    +$langs->loadLangs(array("other","admin"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -410,6 +410,6 @@ else
     
     print '<br>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/menus/other.php b/htdocs/admin/menus/other.php
    index 7789c3fb21c..7b1a73f2f09 100644
    --- a/htdocs/admin/menus/other.php
    +++ b/htdocs/admin/menus/other.php
    @@ -24,9 +24,8 @@
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     
    -$langs->load("users");
    -$langs->load("admin");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("user","other","admin"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -105,6 +104,6 @@ print '</tr>';
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php
    index 6281376dc2e..13f72e7c4b3 100644
    --- a/htdocs/admin/modulehelp.php
    +++ b/htdocs/admin/modulehelp.php
    @@ -162,10 +162,10 @@ foreach ($modulesdir as $dir)
     		    			            	$familykey = $objMod->family;
     		    			            }
     
    -		    			            $moduleposition = ($objMod->module_position?$objMod->module_position:'500');
    -		    			            if ($moduleposition == 500 && ($objMod->isCoreOrExternalModule() == 'external'))
    +		    			            $moduleposition = ($objMod->module_position?$objMod->module_position:'50');
    +		    			            if ($moduleposition == '50' && ($objMod->isCoreOrExternalModule() == 'external'))
     		    			            {
    -		    			                $moduleposition = 800;
    +		    			                $moduleposition = '80';		// External modules at end by default
     		    			            }
     
     		    			            $orders[$i]  = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j;   // Sort by family, then by module position then number
    @@ -594,7 +594,6 @@ dol_fiche_end();
     
     print '</div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php
    index 68f7c3a29a7..81eec5a4247 100644
    --- a/htdocs/admin/modules.php
    +++ b/htdocs/admin/modules.php
    @@ -7,6 +7,7 @@
      * Copyright (C) 2011		Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2015		Jean-François Ferry		<jfefe@aternatik.fr>
      * Copyright (C) 2015		Raphaël Doursenaud		<rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2018		Nicolas ZABOURI 		<info@inovea-conseil.com>
      *
      * 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
    @@ -271,14 +272,13 @@ $dirins_ok=(dol_is_dir($dirins));
     $help_url='EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones';
     llxHeader('',$langs->trans("Setup"),$help_url, '', '', '', $morejs, $morecss, 0, 0);
     
    -$arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - '.$langs->trans("AllPublishers"));
    -$arrayofwarnings=array();    // Array of warning each module want to show when activated
    -$arrayofwarningsext=array();    // Array of warning each module want to show when we activate an external module
     
     // Search modules dirs
     $modulesdir = dolGetModulesDirs();
     
    -
    +$arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - ['.$langs->trans("AllPublishers").']');
    +$arrayofwarnings=array();    // Array of warning each module want to show when activated
    +$arrayofwarningsext=array();    // Array of warning each module want to show when we activate an external module
     $filename = array();
     $modules = array();
     $orders = array();
    @@ -370,10 +370,10 @@ foreach ($modulesdir as $dir)
     		    			            	$familykey = $objMod->family;
     		    			            }
     
    -		    			            $moduleposition = ($objMod->module_position?$objMod->module_position:'500');
    -		    			            if ($moduleposition == 500 && ($objMod->isCoreOrExternalModule() == 'external'))
    +		    			            $moduleposition = ($objMod->module_position?$objMod->module_position:'50');
    +		    			            if ($moduleposition == '50' && ($objMod->isCoreOrExternalModule() == 'external'))
     		    			            {
    -		    			                $moduleposition = 800;
    +		    			            	$moduleposition = '80';		// External modules at end by default
     		    			            }
     
     		    			            // Add list of warnings to show into arrayofwarnings and arrayofwarningsext
    @@ -433,9 +433,7 @@ if ($action == 'reset_confirm' && $user->admin)
     
     		$form = new Form($db);
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?value='.$value.'&mode='.$mode.$param, $langs->trans('ConfirmUnactivation'), $langs->trans(GETPOST('confirm_message_code')), 'reset', '', 'no', 1);
    -
     	}
    -
     }
     
     print $formconfirm;
    @@ -597,17 +595,18 @@ if ($mode == 'common')
             }
     
             // Print a separator if we change family
    -        if ($familykey!=$oldfamily)
    -        {
    -        	if ($oldfamily) print '</table></div><br>';
    +        if ($familykey != $oldfamily) {
    +            if ($oldfamily) {
    +                print '</table></div><br>';
    +            }
     
    -            $familytext=empty($familyinfo[$familykey]['label'])?$familykey:$familyinfo[$familykey]['label'];
    -            print_fiche_titre($familytext, '', '');
    +            $familytext = empty($familyinfo[$familykey]['label'])?$familykey:$familyinfo[$familykey]['label'];
    +            print load_fiche_titre($familytext, '', '');
     
                 print '<div class="div-table-responsive">';
    -        	print '<table class="tagtable liste" summary="list_of_modules">'."\n";
    +            print '<table class="tagtable liste" summary="list_of_modules">'."\n";
     
    -        	$atleastoneforfamily=0;
    +            $atleastoneforfamily=0;
             }
     
             $atleastoneforfamily++;
    @@ -637,6 +636,7 @@ if ($mode == 'common')
             }
     
             print '<tr class="oddeven">'."\n";
    +        if (!empty($conf->global->MAIN_MODULES_SHOW_LINENUMBERS)) print '<td width="20px">'.++$linenum.'</td>';
     
             // Picto + Name of module
             print '  <td width="200px">';
    @@ -669,6 +669,17 @@ if ($mode == 'common')
             // Version
             print '<td class="center nowrap" width="120px">';
             print $versiontrans;
    +        if(!empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)){
    +            require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
    +            if (!empty($objMod->url_last_version)) {
    +                $newversion = getURLContent($objMod->url_last_version);
    +                if(isset($newversion['content'])){
    +                    if (version_compare($newversion['content'], $versiontrans) > 0) {
    +                        print "&nbsp;<span class='butAction' title='" . $langs->trans('LastStableVersion') . "'>".$newversion['content']."</span>";
    +                    }
    +                }
    +            }
    +        }
             print "</td>\n";
     
             // Activate/Disable and Setup (2 columns)
    @@ -698,16 +709,13 @@ if ($mode == 'common')
             			print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=reset_confirm&amp;confirm_message_code='.$objMod->warnings_unactivation[$mysoc->country_code].'&amp;value=' . $modName . '&amp;mode=' . $mode . $param . '">';
             			print img_picto($langs->trans("Activated"),'switch_on');
             			print '</a>';
    -
             		}
             		else {
     
             			print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=reset&amp;value=' . $modName . '&amp;mode=' . $mode .'&amp;confirm=yes' . $param . '">';
             			print img_picto($langs->trans("Activated"),'switch_on');
             			print '</a>';
    -
             		}
    -
             	}
             	print '</td>'."\n";
     
    @@ -762,7 +770,6 @@ if ($mode == 'common')
             	{
             		print '<td class="tdsetuppicto right valignmiddle" width="60px">'.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').'</td>';
             	}
    -
             }
             else	// Module not yet activated
     		{
    @@ -1051,7 +1058,7 @@ if ($mode == 'develop')
     	//print '<img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolibarr_preferred_partner_int.png">';
     	print '<div class="imgmaxheight50 logo_setup"></div>';
     	print '</td>';
    -	print '<td>'.$langs->trans("TryToUseTheModuleBuilder").'</td>';
    +	print '<td>'.$langs->trans("TryToUseTheModuleBuilder", $langs->transnoentitiesnoconv("ModuleBuilder")).'</td>';
     	print '<td>'.$langs->trans("SeeTopRightMenu").'</td>';
     	print '</tr>';
     
    @@ -1069,8 +1076,6 @@ if ($mode == 'develop')
     	dol_fiche_end();
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php
    index b301a2c7a03..9843c6a4fb0 100644
    --- a/htdocs/admin/multicurrency.php
    +++ b/htdocs/admin/multicurrency.php
    @@ -171,7 +171,7 @@ llxHeader('', $langs->trans($page_name));
     
     // Subheader
     $linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php?restore_lastsearch_values=1">' . $langs->trans("BackToModuleList") . '</a>';
    -print_fiche_titre($langs->trans($page_name), $linkback);
    +print load_fiche_titre($langs->trans($page_name), $linkback);
     
     // Configuration header
     $head = multicurrencyAdminPrepareHead();
    @@ -361,6 +361,6 @@ print '
     	</script>
     ';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php
    index 43782816202..92ba0bec200 100644
    --- a/htdocs/admin/notification.php
    +++ b/htdocs/admin/notification.php
    @@ -166,12 +166,15 @@ foreach($listofnotifiedevents as $notifiedevent)
     {
     
         $label=$langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label'];
    +    $elementLabel = $langs->trans(ucfirst($notifiedevent['elementtype']));
     
         if ($notifiedevent['elementtype'] == 'order_supplier') $elementLabel = $langs->trans('SupplierOrder');
         elseif ($notifiedevent['elementtype'] == 'propal') $elementLabel = $langs->trans('Proposal');
         elseif ($notifiedevent['elementtype'] == 'facture') $elementLabel = $langs->trans('Bill');
         elseif ($notifiedevent['elementtype'] == 'commande') $elementLabel = $langs->trans('Order');
         elseif ($notifiedevent['elementtype'] == 'ficheinter') $elementLabel = $langs->trans('Intervention');
    +    elseif ($notifiedevent['elementtype'] == 'shipping') $elementLabel = $langs->trans('Shipping');
    +    elseif ($notifiedevent['elementtype'] == 'expensereport') $elementLabel = $langs->trans('ExpenseReport');
     
         if ($i) print ', ';
         print $label;
    @@ -209,11 +212,15 @@ foreach($listofnotifiedevents as $notifiedevent)
     
         $label=$langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label'];
     
    +    $elementLabel = $langs->trans(ucfirst($notifiedevent['elementtype']));
    +	// Special cases
         if ($notifiedevent['elementtype'] == 'order_supplier') $elementLabel = $langs->trans('SupplierOrder');
         elseif ($notifiedevent['elementtype'] == 'propal') $elementLabel = $langs->trans('Proposal');
         elseif ($notifiedevent['elementtype'] == 'facture') $elementLabel = $langs->trans('Bill');
         elseif ($notifiedevent['elementtype'] == 'commande') $elementLabel = $langs->trans('Order');
     	elseif ($notifiedevent['elementtype'] == 'ficheinter') $elementLabel = $langs->trans('Intervention');
    +	elseif ($notifiedevent['elementtype'] == 'shipping') $elementLabel = $langs->trans('Shipping');
    +	elseif ($notifiedevent['elementtype'] == 'expensereport') $elementLabel = $langs->trans('ExpenseReport');
     
         print '<tr class="oddeven">';
         print '<td>'.$elementLabel.'</td>';
    @@ -272,7 +279,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     
     print '</form>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php
    index f03af4655d4..16827306bda 100644
    --- a/htdocs/admin/oauth.php
    +++ b/htdocs/admin/oauth.php
    @@ -139,7 +139,6 @@ foreach ($list as $key)
         print '<td><label for="'.$key[2].'">'.$langs->trans($key[2]).'</label></td>';
         print '<td><input type="password" size="100" id="'.$key[2].'" name="'.$key[2].'" value="'.$conf->global->{$key[2]}.'">';
         print '</td></tr>';
    -
     }
     
     print '</table>'."\n";
    @@ -150,6 +149,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     
     print '</form>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php
    index 4406dbd9576..f29c49e9f38 100644
    --- a/htdocs/admin/oauthlogintokens.php
    +++ b/htdocs/admin/oauthlogintokens.php
    @@ -17,7 +17,7 @@
      */
     
     /**
    - * \file        htdocs/admin/oauthlogintoken.php
    + * \file        htdocs/admin/oauthlogintokens.php
      * \ingroup     oauth
      * \brief       Setup page to configure oauth access to login information
      */
    @@ -327,7 +327,6 @@ if ($mode == 'setup' && $user->admin)
     
             print '</form>';
         }
    -
     }
     
     if ($mode == 'test' && $user->admin)
    @@ -342,7 +341,7 @@ if ($mode == 'test' && $user->admin)
             $langs->load($driver);
             $printer = new $classname($db);
             //print '<pre>'.print_r($printer, true).'</pre>';
    -        if (count($printer->getlist_available_printers())) {
    +        if (count($printer->getlistAvailablePrinters())) {
                 if ($printer->listAvailablePrinters()==0) {
                     print $printer->resprint;
                 } else {
    @@ -352,11 +351,9 @@ if ($mode == 'test' && $user->admin)
             else {
                 print $langs->trans('PleaseConfigureDriverfromList');
             }
    -
         }
     
         print '</table>';
    -
     }
     
     if ($mode == 'userconf' && $user->admin)
    @@ -394,6 +391,6 @@ if ($mode == 'userconf' && $user->admin)
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/order_extrafields.php b/htdocs/admin/order_extrafields.php
    index 361fc5b67bb..828bb13384f 100644
    --- a/htdocs/admin/order_extrafields.php
    +++ b/htdocs/admin/order_extrafields.php
    @@ -85,7 +85,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -98,7 +98,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -117,6 +117,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/orderdet_extrafields.php b/htdocs/admin/orderdet_extrafields.php
    index c75551cf9f0..929e49c4ab3 100644
    --- a/htdocs/admin/orderdet_extrafields.php
    +++ b/htdocs/admin/orderdet_extrafields.php
    @@ -86,7 +86,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -99,7 +99,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -118,6 +118,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/payment.php b/htdocs/admin/payment.php
    index 1864fdb557c..816ab8344ce 100644
    --- a/htdocs/admin/payment.php
    +++ b/htdocs/admin/payment.php
    @@ -83,7 +83,6 @@ if ($action == 'setparams')
     	{
     	    setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
     	}
    -
     }
     
     
    @@ -217,7 +216,6 @@ foreach ($dirmodels as $reldir)
                                 print '</td>';
     
                                 print "</tr>\n";
    -
                             }
                         }
                     }
    @@ -262,7 +260,6 @@ print '</form>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php
    index f988b27c5e6..50d8fb5b927 100644
    --- a/htdocs/admin/pdf.php
    +++ b/htdocs/admin/pdf.php
    @@ -32,11 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array('admin', 'languages', 'other'));
    -
    -$langs->load("companies");
    -$langs->load("products");
    -$langs->load("members");
    +$langs->loadLangs(array('admin', 'languages', 'other', 'companies', 'products', 'members'));
     
     if (! $user->admin) accessforbidden();
     
    @@ -54,29 +50,31 @@ if ($cancel) {
     
     if ($action == 'update')
     {
    -	dolibarr_set_const($db, "MAIN_PDF_FORMAT",    $_POST["MAIN_PDF_FORMAT"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_PDF_FORMAT", $_POST["MAIN_PDF_FORMAT"],'chaine',0,'', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_PDF_MARGIN_LEFT",    $_POST["MAIN_PDF_MARGIN_LEFT"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PDF_MARGIN_RIGHT",   $_POST["MAIN_PDF_MARGIN_RIGHT"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PDF_MARGIN_TOP",     $_POST["MAIN_PDF_MARGIN_TOP"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PDF_MARGIN_BOTTOM",  $_POST["MAIN_PDF_MARGIN_BOTTOM"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_PDF_MARGIN_LEFT", $_POST["MAIN_PDF_MARGIN_LEFT"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PDF_MARGIN_RIGHT", $_POST["MAIN_PDF_MARGIN_RIGHT"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PDF_MARGIN_TOP", $_POST["MAIN_PDF_MARGIN_TOP"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PDF_MARGIN_BOTTOM", $_POST["MAIN_PDF_MARGIN_BOTTOM"],'chaine',0,'', $conf->entity);
     
    -    dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS",    $_POST["MAIN_PROFID1_IN_ADDRESS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PROFID2_IN_ADDRESS",    $_POST["MAIN_PROFID2_IN_ADDRESS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PROFID3_IN_ADDRESS",    $_POST["MAIN_PROFID3_IN_ADDRESS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PROFID4_IN_ADDRESS",    $_POST["MAIN_PROFID4_IN_ADDRESS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT",    $_POST["MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"],'chaine',0,'',$conf->entity);
    +    dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", $_POST["MAIN_PROFID1_IN_ADDRESS"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PROFID2_IN_ADDRESS", $_POST["MAIN_PROFID2_IN_ADDRESS"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PROFID3_IN_ADDRESS", $_POST["MAIN_PROFID3_IN_ADDRESS"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PROFID4_IN_ADDRESS", $_POST["MAIN_PROFID4_IN_ADDRESS"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT", $_POST["MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"],'chaine',0,'', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_TVAINTRA_NOT_IN_ADDRESS",    $_POST["MAIN_TVAINTRA_NOT_IN_ADDRESS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS", $_POST["MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DESC",    $_POST["MAIN_GENERATE_DOCUMENTS_HIDE_DESC"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_REF",     $_POST["MAIN_GENERATE_DOCUMENTS_HIDE_REF"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_PDF_USE_ISO_LOCATION",     $_POST["MAIN_PDF_USE_ISO_LOCATION"],'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS",     $_POST["MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_TVAINTRA_NOT_IN_ADDRESS", $_POST["MAIN_TVAINTRA_NOT_IN_ADDRESS"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS", $_POST["MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_DESC", $_POST["MAIN_GENERATE_DOCUMENTS_HIDE_DESC"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_HIDE_REF", $_POST["MAIN_GENERATE_DOCUMENTS_HIDE_REF"],'chaine',0,'', $conf->entity);
    +
    +	dolibarr_set_const($db, "MAIN_INVERT_SENDER_RECIPIENT", $_POST["MAIN_INVERT_SENDER_RECIPIENT"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_PDF_USE_ISO_LOCATION", $_POST["MAIN_PDF_USE_ISO_LOCATION"],'chaine',0,'', $conf->entity);
    +	dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS", $_POST["MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS"],'chaine',0,'', $conf->entity);
     
     
    -    dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_SECOND_TAX",    $_POST["MAIN_PDF_MAIN_HIDE_SECOND_TAX"],'chaine',0,'',$conf->entity);
    -    dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_THIRD_TAX",     $_POST["MAIN_PDF_MAIN_HIDE_THIRD_TAX"],'chaine',0,'',$conf->entity);
    +    dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_SECOND_TAX", $_POST["MAIN_PDF_MAIN_HIDE_SECOND_TAX"],'chaine',0,'', $conf->entity);
    +    dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_THIRD_TAX", $_POST["MAIN_PDF_MAIN_HIDE_THIRD_TAX"],'chaine',0,'', $conf->entity);
     
     	header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
     	exit;
    @@ -519,7 +517,6 @@ else	// Show
                 $text.= yn($conf->global->MAIN_PDF_MAIN_HIDE_THIRD_TAX,1);
                 $text.= '</td></tr>';
             }
    -
         }
     
         // Sales TAX / VAT information
    @@ -576,31 +573,36 @@ else	// Show
     	print "</td>";
     	print '</tr>';
     
    -	//Desc
    +	// Hide Desc
     
     	print '<tr class="oddeven"><td>'.$langs->trans("HideDescOnPDF").'</td><td colspan="2">';
     	print yn($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC,1);
     	print '</td></tr>';
     
    -	//Ref
    +	// Hide Ref
     
     	print '<tr class="oddeven"><td>'.$langs->trans("HideRefOnPDF").'</td><td colspan="2">';
     	print yn($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF,1);
     	print '</td></tr>';
     
    -	//Details
    +	// Hide Details
     
     	print '<tr class="oddeven"><td>'.$langs->trans("HideDetailsOnPDF").'</td><td colspan="2">';
     	print yn($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS,1);
     	print '</td></tr>';
     
    +	// Invert sender and recipient
    +	print '<tr class="oddeven"><td>'.$langs->trans("SwapSenderAndRecipientOnPDF").'</td><td colspan="2">';
    +	print yn($conf->global->MAIN_INVERT_SENDER_RECIPIENT,1);
    +	print '</td></tr>';
     
    -    print '<tr class="oddeven"><td>'.$langs->trans("PlaceCustomerAddressToIsoLocation").'</td><td colspan="2">';
    +	// Use French location
    +	print '<tr class="oddeven"><td>'.$langs->trans("PlaceCustomerAddressToIsoLocation").'</td><td colspan="2">';
     	print yn($conf->global->MAIN_PDF_USE_ISO_LOCATION,1);
     	print '</td></tr>';
     
     
    -    print '<tr class="oddeven"><td>'.$langs->trans("ShowDetailsInPDFPageFoot").'</td><td colspan="2">';
    +	print '<tr class="oddeven"><td>'.$langs->trans("ShowDetailsInPDFPageFoot").'</td><td colspan="2">';
     	print $arraydetailsforpdffoot[($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS ? $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS : 0)];
     	print '</td></tr>';
     
    @@ -668,7 +670,6 @@ else	// Show
     	print '<br>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/perms.php b/htdocs/admin/perms.php
    index 50bf939c07f..db4e1f33553 100644
    --- a/htdocs/admin/perms.php
    +++ b/htdocs/admin/perms.php
    @@ -218,5 +218,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
    -$db->close();
    +$db->close();
    \ No newline at end of file
    diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php
    index 6fd40cf2825..cdfcd451f2c 100644
    --- a/htdocs/admin/prelevement.php
    +++ b/htdocs/admin/prelevement.php
    @@ -80,6 +80,16 @@ if ($action == "set")
             $res = dolibarr_set_const($db, "PRELEVEMENT_USER", GETPOST("PRELEVEMENT_USER"),'chaine',0,'',$conf->entity);
             if (! $res > 0) $error++;
         }
    +    if (GETPOST("PRELEVEMENT_END_TO_END") || GETPOST("PRELEVEMENT_END_TO_END")=="")
    +    {
    +        $res = dolibarr_set_const($db, "END_TO_END", GETPOST("PRELEVEMENT_END_TO_END"),'chaine',0,'',$conf->entity);
    +        if (! $res > 0) $error++;
    +    }
    +    if (GETPOST("PRELEVEMENT_USTRD") || GETPOST("PRELEVEMENT_USTRD")=="")
    +    {
    +        $res = dolibarr_set_const($db, "USTRD", GETPOST("PRELEVEMENT_USTRD"),'chaine',0,'',$conf->entity);
    +        if (! $res > 0) $error++;
    +    }
     
         if (! $error)
     	{
    @@ -221,6 +231,18 @@ print $form->select_dolusers($conf->global->PRELEVEMENT_USER, 'PRELEVEMENT_USER'
     print '</td>';
     print '</tr>';
     
    +//EntToEnd
    +print '<tr class="pair"><td class="fieldrequired">'.$langs->trans("END_TO_END").'</td>';
    +print '<td align="left">';
    +print '<input type="text" name="PRELEVEMENT_END_TO_END" value="'.$conf->global->END_TO_END.'" size="15" ></td>';
    +print '</td></tr>';
    +
    +//USTRD
    +print '<tr class="pair"><td class="fieldrequired">'.$langs->trans("USTRD").'</td>';
    +print '<td align="left">';
    +print '<input type="text" name="PRELEVEMENT_USTRD" value="'.$conf->global->USTRD.'" size="15" ></td>';
    +print '</td></tr>';
    +
     print '</table>';
     print '<br>';
     
    @@ -443,7 +465,6 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION))
         {
             $num = $db->num_rows($resql);
             $i = 0;
    -        $var = false;
             while ($i < $num)
             {
                 $obj = $db->fetch_object($resql);
    @@ -489,7 +510,6 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION))
     	{
     	    $num = $db->num_rows($resql);
     	    $i = 0;
    -	    $var = false;
     	    while ($i < $num)
     	    {
     	        $obj = $db->fetch_object($resql);
    @@ -511,5 +531,6 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION))
     }
     */
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php
    index 94b1d1dac67..bc91729829f 100644
    --- a/htdocs/admin/propal.php
    +++ b/htdocs/admin/propal.php
    @@ -649,7 +649,6 @@ print "</td></tr>\n";
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/proxy.php b/htdocs/admin/proxy.php
    index 87a89f5d99b..9490a291729 100644
    --- a/htdocs/admin/proxy.php
    +++ b/htdocs/admin/proxy.php
    @@ -205,5 +205,6 @@ print '</div>';
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php
    index 4465017bdc6..b8d92687d84 100644
    --- a/htdocs/admin/receiptprinter.php
    +++ b/htdocs/admin/receiptprinter.php
    @@ -52,6 +52,12 @@ if (!$mode) $mode='config';
     
     // used in library escpos maybe useful if php doesn't support gzdecode
     if (!function_exists('gzdecode')) {
    +    /**
    +     * Gzdecode
    +     *
    +     * @param string    $data   data to deflate
    +     * @return string           data deflated
    +     */
         function gzdecode($data)
         {
             return gzinflate(substr($data,10,-8));
    @@ -243,14 +249,14 @@ if ($mode == 'config' && $user->admin)
         print "</tr>\n";
         $ret = $printer->listprinters();
         $nbofprinters = count($printer->listprinters);
    -    
    +
         if ($ret > 0) {
             setEventMessages($printer->error, $printer->errors, 'errors');
         } else {
    -        for ($line=0; $line < $nbofprinters; $line++) 
    +        for ($line=0; $line < $nbofprinters; $line++)
             {
                 print '<tr class="oddeven">';
    -            if ($action=='editprinter' && $printer->listprinters[$line]['rowid']==$printerid) 
    +            if ($action=='editprinter' && $printer->listprinters[$line]['rowid']==$printerid)
                 {
                     print '<input type="hidden" name="printerid" value="'.$printer->listprinters[$line]['rowid'].'">';
                     print '<td><input size="50" type="text" name="printername" value="'.$printer->listprinters[$line]['name'].'"></td>';
    @@ -285,7 +291,7 @@ if ($mode == 'config' && $user->admin)
             }
         }
     
    -    if ($action!='editprinter') 
    +    if ($action!='editprinter')
         {
             if ($nbofprinters > 0)
             {
    @@ -299,7 +305,7 @@ if ($mode == 'config' && $user->admin)
                 print '<th></th>';
                 print "</tr>\n";
             }
    -        
    +
             print '<tr>';
             print '<td><input size="50" type="text" name="printername"></td>';
             $ret = $printer->selectTypePrinter();
    @@ -315,7 +321,7 @@ if ($mode == 'config' && $user->admin)
         print '</table>';
     
         dol_fiche_end();
    -    
    +
         if ($action!='editprinter') {
             print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Add")).'"></div>';
         } else {
    @@ -324,9 +330,9 @@ if ($mode == 'config' && $user->admin)
         print '</form>';
     
         print '<div><p></div>';
    -    
    +
         dol_fiche_head();
    -    
    +
         print $langs->trans("ReceiptPrinterTypeDesc")."<br><br>\n";
         print '<table class="noborder" width="100%">'."\n";
         print '<tr class="oddeven"><td>'.$langs->trans("CONNECTOR_DUMMY").':</td><td>'.$langs->trans("CONNECTOR_DUMMY_HELP").'</td></tr>';
    @@ -338,7 +344,7 @@ if ($mode == 'config' && $user->admin)
         dol_fiche_end();
     
         print '<div><p></div>';
    -    
    +
         dol_fiche_head();
         print $langs->trans("ReceiptPrinterProfileDesc")."<br><br>\n";
         print '<table class="noborder" width="100%">'."\n";
    @@ -378,7 +384,7 @@ if ($mode == 'template' && $user->admin)
             setEventMessages($printer->error, $printer->errors, 'errors');
         } else {
             $max = count($printer->listprinterstemplates);
    -        for ($line=0; $line < $max; $line++) 
    +        for ($line=0; $line < $max; $line++)
             {
                 print '<tr class="oddeven">';
                 if ($action=='edittemplate' && $printer->listprinterstemplates[$line]['rowid']==$templateid) {
    @@ -423,7 +429,7 @@ if ($mode == 'template' && $user->admin)
         print '<th>'.$langs->trans("Description").'</th>';
         print "</tr>\n";
         $max = count($printer->tags);
    -    for ($tag=0; $tag < $max; $tag++) 
    +    for ($tag=0; $tag < $max; $tag++)
         {
             print '<tr class="oddeven">';
             print '<td>&lt;'.$printer->tags[$tag].'&gt;</td><td>'.$langs->trans(strtoupper($printer->tags[$tag])).'</td>';
    @@ -432,22 +438,20 @@ if ($mode == 'template' && $user->admin)
         print '</table>';
     
         dol_fiche_end();
    -
     }
     
     // to remove after test
    -$object=new stdClass();
    -$object->date_time = '2015-11-02 22:30:25';
    -$object->id = 1234;
    -$object->customer_firstname  = 'John';
    -$object->customer_lastname  = 'Deuf';
    -$object->vendor_firstname  = 'Jim';
    -$object->vendor_lastname  = 'Big';
    -$object->barcode = '3700123862396';
    +// $object=new stdClass();
    +// $object->date_time = '2015-11-02 22:30:25';
    +// $object->id = 1234;
    +// $object->customer_firstname  = 'John';
    +// $object->customer_lastname  = 'Deuf';
    +// $object->vendor_firstname  = 'Jim';
    +// $object->vendor_lastname  = 'Big';
    +// $object->barcode = '3700123862396';
     //$printer->sendToPrinter($object, 1, 16);
     //setEventMessages($printer->error, $printer->errors, 'errors');
     
    +// End of page
     llxFooter();
    -
     $db->close();
    -
    diff --git a/htdocs/admin/resource.php b/htdocs/admin/resource.php
    index e8f8bdba204..566e57e587b 100644
    --- a/htdocs/admin/resource.php
    +++ b/htdocs/admin/resource.php
    @@ -137,6 +137,6 @@ print '</form>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/resource_extrafields.php b/htdocs/admin/resource_extrafields.php
    index 8193d146aaa..b8ea860ac25 100644
    --- a/htdocs/admin/resource_extrafields.php
    +++ b/htdocs/admin/resource_extrafields.php
    @@ -84,7 +84,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -97,7 +97,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -116,6 +116,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/salaries.php b/htdocs/admin/salaries.php
    index 6c5281173c3..a68a4bda5a6 100644
    --- a/htdocs/admin/salaries.php
    +++ b/htdocs/admin/salaries.php
    @@ -75,7 +75,7 @@ if ($action == 'update')
     llxHeader('',$langs->trans('SalariesSetup'));
     
     $form = new Form($db);
    -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db);
    +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db);
     
     $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
     print load_fiche_titre($langs->trans('SalariesSetup'),$linkback,'title_setup');
    @@ -127,5 +127,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -$db->close();
    +$db->close();;
    diff --git a/htdocs/admin/security.php b/htdocs/admin/security.php
    index 129853837a4..58f349ffe55 100644
    --- a/htdocs/admin/security.php
    +++ b/htdocs/admin/security.php
    @@ -500,7 +500,6 @@ print '</form>';
     
     print '</div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php
    index 4a4637185ca..1b7098c55aa 100644
    --- a/htdocs/admin/security_file.php
    +++ b/htdocs/admin/security_file.php
    @@ -178,7 +178,6 @@ print '<div class="center"><input type="submit" class="button" name="button" val
     print '</form>';
     
     
    -
     // Form to test upload
     print '<br>';
     $formfile=new FormFile($db);
    @@ -188,5 +187,6 @@ $formfile->form_attach_new_file($_SERVER['PHP_SELF'], $langs->trans("FormToTestF
     $filearray=dol_dir_list($upload_dir, "files", 0, '', '', 'name', SORT_ASC, 1);
     $formfile->list_of_documents($filearray, null, 'admin_temp', '');
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/security_other.php b/htdocs/admin/security_other.php
    index 6503ab10f77..0e3da947fa8 100644
    --- a/htdocs/admin/security_other.php
    +++ b/htdocs/admin/security_other.php
    @@ -206,6 +206,6 @@ print '<div class="center"><input type="submit" class="button" name="button" val
     
     print '</form>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php
    index db1cb20b5e3..45071117c89 100644
    --- a/htdocs/admin/sms.php
    +++ b/htdocs/admin/sms.php
    @@ -48,12 +48,12 @@ $action=GETPOST('action','aZ09');
     
     if ($action == 'update' && empty($_POST["cancel"]))
     {
    -	dolibarr_set_const($db, "MAIN_DISABLE_ALL_SMS",   $_POST["MAIN_DISABLE_ALL_SMS"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_DISABLE_ALL_SMS", $_POST["MAIN_DISABLE_ALL_SMS"], 'chaine', 0, '', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_SMS_SENDMODE",      $_POST["MAIN_SMS_SENDMODE"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_SMS_SENDMODE", $_POST["MAIN_SMS_SENDMODE"], 'chaine', 0, '', $conf->entity);
     
    -	dolibarr_set_const($db, "MAIN_MAIL_SMS_FROM",     $_POST["MAIN_MAIL_SMS_FROM"],'chaine',0,'',$conf->entity);
    -	//dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO",    $_POST["MAIN_MAIL_AUTOCOPY_TO"],'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "MAIN_MAIL_SMS_FROM", $_POST["MAIN_MAIL_SMS_FROM"], 'chaine', 0, '', $conf->entity);
    +	//dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO", $_POST["MAIN_MAIL_AUTOCOPY_TO"], 'chaine', 0, '', $conf->entity);
     
     	header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
     	exit;
    @@ -169,21 +169,21 @@ if ($action == 'edit')
     	print '<table class="noborder" width="100%">';
     	print '<tr class="liste_titre"><td>'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
     
    -	// Disable	
    +	// Disable
     	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_DISABLE_ALL_SMS").'</td><td>';
     	print $form->selectyesno('MAIN_DISABLE_ALL_SMS',$conf->global->MAIN_DISABLE_ALL_SMS,1);
     	print '</td></tr>';
     
    -	// Separator	
    +	// Separator
     	print '<tr class="oddeven"><td colspan="2">&nbsp;</td></tr>';
     
    -	// Method	
    +	// Method
     	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_SMS_SENDMODE").'</td><td>';
     	if (count($listofmethods)) print $form->selectarray('MAIN_SMS_SENDMODE',$listofmethods,$conf->global->MAIN_SMS_SENDMODE,1);
     	else print '<font class="error">'.$langs->trans("None").'</font>';
         print '</td></tr>';
     
    -	// From	
    +	// From
     	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SMS_FROM",$langs->transnoentities("Undefined")).'</td>';
     	print '<td><input class="flat" name="MAIN_MAIL_SMS_FROM" size="32" value="' . $conf->global->MAIN_MAIL_SMS_FROM;
     	print '"></td></tr>';
    @@ -213,20 +213,20 @@ else
     	print '<table class="noborder" width="100%">';
     	print '<tr class="liste_titre"><td>'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
     
    -	// Disable	
    +	// Disable
     	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_DISABLE_ALL_SMS").'</td><td>'.yn($conf->global->MAIN_DISABLE_ALL_SMS).'</td></tr>';
     
    -	// Separator	
    +	// Separator
     	print '<tr class="oddeven"><td colspan="2">&nbsp;</td></tr>';
     
    -	// Method	
    +	// Method
     	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_SMS_SENDMODE").'</td><td>';
     	$text=$listofmethods[$conf->global->MAIN_SMS_SENDMODE];
     	if (empty($text)) $text=$langs->trans("Undefined").' '.img_warning();
     	print $text;
     	print '</td></tr>';
     
    -	// From	
    +	// From
     	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SMS_FROM",$langs->transnoentities("Undefined")).'</td>';
     	print '<td>'.$conf->global->MAIN_MAIL_SMS_FROM;
     	if (!empty($conf->global->MAIN_MAIL_SMS_FROM) && ! isValidPhone($conf->global->MAIN_MAIL_SMS_FROM)) print ' '.img_warning($langs->trans("ErrorBadPhone"));
    @@ -331,7 +331,6 @@ else
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/socialnetworks.php b/htdocs/admin/socialnetworks.php
    new file mode 100644
    index 00000000000..9aba26b3fc4
    --- /dev/null
    +++ b/htdocs/admin/socialnetworks.php
    @@ -0,0 +1,123 @@
    +<?php
    +/* Copyright (C) 2018 Laurent Destailleur  <eldy@users.sourceforge.net>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *   	\file       htdocs/admin/socialnetworks.php
    + *		\ingroup    socialnetworks
    + *		\brief      Page to setup the module Social Networks
    + */
    +
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/mailmanspip.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin", "errors"));
    +
    +if (! $user->admin) accessforbidden();
    +
    +$type=array('yesno','texte','chaine');
    +
    +$action = GETPOST('action','aZ09');
    +
    +
    +
    +/*
    + * Actions
    + */
    +
    +// Action activation d'un sous module du module adherent
    +if ($action == 'set')
    +{
    +	$result=dolibarr_set_const($db, $_GET["name"], $_GET["value"], '', 0, '', $conf->entity);
    +	if ($result < 0)
    +	{
    +		dol_print_error($db);
    +	}
    +}
    +
    +// Action desactivation d'un sous module du module adherent
    +if ($action == 'unset')
    +{
    +	$result=dolibarr_del_const($db, $_GET["name"], $conf->entity);
    +	if ($result < 0)
    +	{
    +		dol_print_error($db);
    +	}
    +}
    +
    +
    +/*
    + * View
    + */
    +
    +$help_url='';
    +
    +llxHeader('',$langs->trans("SocialNetworkSetup"),$help_url);
    +
    +
    +$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
    +print load_fiche_titre($langs->trans("SocialNetworkSetup"),$linkback,'title_setup');
    +
    +//$head = socialnetworks_admin_prepare_head();
    +$h=0;
    +$head = array();
    +$head[$h][0] = DOL_URL_ROOT.'/admin/socialnetworks.php';
    +$head[$h][1] = $langs->trans("Setup");
    +$head[$h][2] = 'setup';
    +$h++;
    +
    +
    +print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    +
    +dol_fiche_head($head, 'setup', '', 0, 'user');
    +
    +print '<br>';
    +
    +$arrayofsocialnetworks=array('skype'=>'Skype', 'twitter'=>'Twitter', 'facebook'=>'Facebook');
    +
    +foreach($arrayofsocialnetworks as $snkey => $snlabel)
    +{
    +	$consttocheck = 'SOCIALNETWORKS_'.strtoupper($snkey);
    +	if (! empty($conf->global->$consttocheck))
    +	{
    +		//$link=img_picto($langs->trans("Active"),'tick').' ';
    +		$link='<a href="'.$_SERVER["PHP_SELF"].'?action=unset&value=0&name='.$consttocheck.'">';
    +		//$link.=$langs->trans("Disable");
    +		$link.=img_picto($langs->trans("Activated"),'switch_on');
    +		$link.='</a>';
    +	}
    +	else
    +	{
    +		$link='<a href="'.$_SERVER["PHP_SELF"].'?action=set&value=1&name='.$consttocheck.'">';
    +		//$link.=img_$langs->trans("Activate")
    +		$link.=img_picto($langs->trans("Disabled"),'switch_off');
    +		$link.='</a>';
    +	}
    +	print $langs->trans('EnableFeatureFor', $snlabel).' '.$link.'<br><br>';
    +}
    +
    +
    +dol_fiche_end();
    +
    +print '</form>';
    +
    +
    +// End of page
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/admin/spip.php b/htdocs/admin/spip.php
    index b9892fdf2a9..d179c66d58d 100644
    --- a/htdocs/admin/spip.php
    +++ b/htdocs/admin/spip.php
    @@ -163,6 +163,6 @@ else
         dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php
    index cdfaf928cf4..858422c598c 100644
    --- a/htdocs/admin/stock.php
    +++ b/htdocs/admin/stock.php
    @@ -567,7 +567,6 @@ if ($conf->global->PRODUIT_SOUSPRODUITS)
     }
     */
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php
    index 5dbe26596fe..3db96ddd8a4 100644
    --- a/htdocs/admin/supplier_invoice.php
    +++ b/htdocs/admin/supplier_invoice.php
    @@ -519,7 +519,6 @@ print "</td></tr>\n";
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php
    index 695d25a963c..72050867dfa 100644
    --- a/htdocs/admin/supplier_order.php
    +++ b/htdocs/admin/supplier_order.php
    @@ -589,7 +589,6 @@ print "</td></tr>\n";
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php
    index c1f3a7cb25d..77f2a95070e 100644
    --- a/htdocs/admin/supplier_payment.php
    +++ b/htdocs/admin/supplier_payment.php
    @@ -301,7 +301,6 @@ foreach ($dirmodels as $reldir)
                                 print '</td>';
     
                                 print "</tr>\n";
    -
                             }
                         }
                     }
    @@ -430,7 +429,6 @@ print '</table>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php
    index 99069447e81..eeb148e9d99 100644
    --- a/htdocs/admin/supplier_proposal.php
    +++ b/htdocs/admin/supplier_proposal.php
    @@ -582,6 +582,7 @@ print "</tr>\n";
     print "<tr class=\"oddeven\">\n  <td width=\"140\">".$langs->trans("PathDirectory")."</td>\n  <td>".$conf->supplier_proposal->dir_output."</td>\n</tr>\n";
     print "</table>\n<br>";
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/supplierinvoice_extrafields.php b/htdocs/admin/supplierinvoice_extrafields.php
    index 7e913772e2c..bbda698a778 100644
    --- a/htdocs/admin/supplierinvoice_extrafields.php
    +++ b/htdocs/admin/supplierinvoice_extrafields.php
    @@ -4,7 +4,7 @@
      * Copyright (C) 2004-2013	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2012		Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2012		Florian Henry			<florian.henry@open-concept.pro>
    - * Copyright (C) 2013		Philippe Grand			<philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018	Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2013		Juanjo Menent			<jmenent@2byte.es>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -32,17 +32,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
     // Load translation files required by the page
    -$langs->load("orders");
    +$langs->loadLangs(array("admin", "other", "bills", "orders", "suppliers"));
     
     if (!$user->admin)
     	accessforbidden();
     
    -$langs->load("admin");
    -$langs->load("other");
    -$langs->load("bills");
    -$langs->load("orders");
    -$langs->load("suppliers");
    -
     $extrafields = new ExtraFields($db);
     $form = new Form($db);
     
    @@ -91,7 +85,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -104,7 +98,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -123,6 +117,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplierinvoicedet_extrafields.php b/htdocs/admin/supplierinvoicedet_extrafields.php
    index d8156d54779..cdf128871fd 100644
    --- a/htdocs/admin/supplierinvoicedet_extrafields.php
    +++ b/htdocs/admin/supplierinvoicedet_extrafields.php
    @@ -87,7 +87,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -100,7 +100,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -119,6 +119,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplierorder_extrafields.php b/htdocs/admin/supplierorder_extrafields.php
    index 30cf4d983e4..640b6375c57 100644
    --- a/htdocs/admin/supplierorder_extrafields.php
    +++ b/htdocs/admin/supplierorder_extrafields.php
    @@ -85,7 +85,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -98,7 +98,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -117,6 +117,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/supplierorderdet_extrafields.php b/htdocs/admin/supplierorderdet_extrafields.php
    index 85106bf84f0..65fe0537ba7 100644
    --- a/htdocs/admin/supplierorderdet_extrafields.php
    +++ b/htdocs/admin/supplierorderdet_extrafields.php
    @@ -86,7 +86,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -99,7 +99,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -118,6 +118,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/syslog.php b/htdocs/admin/syslog.php
    index 45dc91a8b95..d9ab678faa8 100644
    --- a/htdocs/admin/syslog.php
    +++ b/htdocs/admin/syslog.php
    @@ -132,9 +132,7 @@ if ($action == 'set')
     	{
     		$db->rollback();
     		setEventMessages($error, $errors, 'errors');
    -
     	}
    -
     }
     
     // Set level
    @@ -302,6 +300,6 @@ if(! empty($conf->loghandlers['mod_syslog_file']) && ! empty($conf->cron->enable
     print '</table>';
     print "</form>\n";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/about.php b/htdocs/admin/system/about.php
    index 61780d51386..ba61203191a 100644
    --- a/htdocs/admin/system/about.php
    +++ b/htdocs/admin/system/about.php
    @@ -28,10 +28,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    -$langs->load("admin");
    -$langs->load("help");
    -$langs->load("members");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("help","members","other","admin"));
     
     $action=GETPOST('action','alpha');
     
    @@ -196,7 +194,7 @@ if ($showpromotemessage)
         {
             print '<br>';
             print '<br>';
    -        
    +
             if ((empty($tmp[2]) && (strpos($tmp[1], '0') === 0)) || (strpos($tmp[2], '0') === 0))
             {
                 print $langs->trans("TitleExampleForMajorRelease").':<br>';
    @@ -214,7 +212,6 @@ if ($showpromotemessage)
         }
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/browser.php b/htdocs/admin/system/browser.php
    index 4f2a53de88d..9df49489e34 100644
    --- a/htdocs/admin/system/browser.php
    +++ b/htdocs/admin/system/browser.php
    @@ -26,9 +26,8 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
    -$langs->load("admin");
    -$langs->load("install");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("install","other","admin"));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -66,7 +65,6 @@ print '</table>';
     print '</div>';
     print '<br>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/constall.php b/htdocs/admin/system/constall.php
    index 82e8481c2dd..d510cc07773 100644
    --- a/htdocs/admin/system/constall.php
    +++ b/htdocs/admin/system/constall.php
    @@ -24,9 +24,8 @@
     
     require '../../main.inc.php';
     
    -$langs->load("admin");
    -$langs->load("user");
    -$langs->load("install");
    +// Load translation files required by the page
    +$langs->loadLangs(array("install","user","admin"));
     
     
     if (!$user->admin)
    @@ -249,7 +248,6 @@ if ($resql)
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php
    index 556961cb565..17d72edf20a 100644
    --- a/htdocs/admin/system/database-tables.php
    +++ b/htdocs/admin/system/database-tables.php
    @@ -212,5 +212,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/system/database.php b/htdocs/admin/system/database.php
    index 45ce3c087e6..d5a7bbcdbfd 100644
    --- a/htdocs/admin/system/database.php
    +++ b/htdocs/admin/system/database.php
    @@ -126,6 +126,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/dbtable.php b/htdocs/admin/system/dbtable.php
    index cef493c95f8..392c083c382 100644
    --- a/htdocs/admin/system/dbtable.php
    +++ b/htdocs/admin/system/dbtable.php
    @@ -138,6 +138,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/dolibarr.php b/htdocs/admin/system/dolibarr.php
    index b2000b65c5b..99a07c17248 100644
    --- a/htdocs/admin/system/dolibarr.php
    +++ b/htdocs/admin/system/dolibarr.php
    @@ -29,9 +29,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    -$langs->load("admin");
    -$langs->load("install");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("install","other","admin"));
     
     $action=GETPOST('action','alpha');
     
    @@ -454,7 +453,6 @@ if ($resql)
     print '</table>';
     print '</div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php
    index 309d20e0abe..e978ac85b55 100644
    --- a/htdocs/admin/system/filecheck.php
    +++ b/htdocs/admin/system/filecheck.php
    @@ -307,7 +307,7 @@ if (! $error && $xml)
             }
             else
             {
    -            $out.='<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
    +            $out.='<tr class="oddeven"><td colspan="6" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
             }
             $out.='</table>';
             $out.='</div>';
    @@ -372,11 +372,11 @@ if (! $error && $xml)
             // Show warning
             if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3))
             {
    -            setEventMessage($langs->trans("FileIntegrityIsStrictlyConformedWithReference"));
    +            setEventMessages($langs->trans("FileIntegrityIsStrictlyConformedWithReference"), null, 'mesgs');
             }
             else
             {
    -            setEventMessage($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), 'warnings');
    +            setEventMessages($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), null, 'warnings');
             }
         }
         else
    @@ -428,7 +428,7 @@ if (! $error && $xml)
         	$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
         }
     
    -    print_fiche_titre($langs->trans("GlobalChecksum")).'<br>';
    +    print load_fiche_titre($langs->trans("GlobalChecksum")).'<br>';
         print $langs->trans("ExpectedChecksum").' = '. $outexpectedchecksum .'<br>';
         print $langs->trans("CurrentChecksum").' = '. $outcurrentchecksum;
     
    @@ -439,12 +439,8 @@ if (! $error && $xml)
         print $out;
     }
     
    -
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
     
     exit($error);
    -
    diff --git a/htdocs/admin/system/index.php b/htdocs/admin/system/index.php
    index 3d473640618..cf79ae910b3 100644
    --- a/htdocs/admin/system/index.php
    +++ b/htdocs/admin/system/index.php
    @@ -25,9 +25,8 @@
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     
    -$langs->load("admin");
    -$langs->load("user");
    -$langs->load("install");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin", "user", "install"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -106,7 +105,7 @@ print '<br>';
     print '<table class="noborder" width="100%">';
     print "<tr class=\"liste_titre\"><td colspan=\"2\">".$langs->trans("Browser")."</td></tr>\n";
     print "<tr $bc[0]><td width=\"280\">".$langs->trans("UserAgent")."</td><td>" .$_SERVER["HTTP_USER_AGENT"]."</td></tr>\n";
    -print "<tr $bc[1]><td width=\"280\">".$langs->trans("Smartphone")."</td><td>".(empty($conf->browser->phone)?$langs->trans("No"):$conf->browser->phone)."</td></tr>\n";
    +print "<tr $bc[1]><td width=\"280\">".$langs->trans("Smartphone")."</td><td>".(($conf->browser->layout != 'phone')?$langs->trans("No"):$langs->trans("Yes"))."</td></tr>\n";
     print '</table>';
     print '<br>';
     
    @@ -114,6 +113,6 @@ print '<br>';
     //print "<br>\n";
     print info_admin($langs->trans("SystemInfoDesc")).'<br>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/modules.php b/htdocs/admin/system/modules.php
    index 4a6967089e2..c70ad1b7fba 100644
    --- a/htdocs/admin/system/modules.php
    +++ b/htdocs/admin/system/modules.php
    @@ -25,9 +25,8 @@
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     
    -$langs->load("admin");
    -$langs->load("install");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("install","other","admin"));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -79,17 +78,17 @@ foreach($modulesdir as $dir)
     						{
     							try {
     	    						$objMod = new $modName($db);
    -						
    +
     			    				$modules[$objMod->numero]=$objMod;
     			    				$modules_names[$objMod->numero]=$objMod->name;
     	    						$modules_files[$objMod->numero]=$file;
     	    						$modules_fullpath[$file]=$dir.$file;
     	    						$picto[$objMod->numero]=(isset($objMod->picto) && $objMod->picto)?$objMod->picto:'generic';
    -							} 
    +							}
     							catch(Exception $e)
     							{
     								dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
    -							}	
    +							}
     						}
     						else
     						{
    @@ -159,5 +158,6 @@ foreach($rights_ids as $right_id)
     	$old = $right_id;
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/system/os.php b/htdocs/admin/system/os.php
    index 01d48f2444d..251025a4c9e 100644
    --- a/htdocs/admin/system/os.php
    +++ b/htdocs/admin/system/os.php
    @@ -49,6 +49,6 @@ $osversion=version_os();
     print "<tr $bc[1]><td width=\"240\">".$langs->trans("Version")."</td><td>".$osversion."</td></tr>\n";
     print '</table>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/system/perf.php b/htdocs/admin/system/perf.php
    index 1e757b72f63..d69723f1299 100644
    --- a/htdocs/admin/system/perf.php
    +++ b/htdocs/admin/system/perf.php
    @@ -26,9 +26,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     
    -$langs->load("admin");
    -$langs->load("install");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("install","other","admin"));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -491,7 +490,6 @@ print '<strong>'.$langs->trans("DatabaseStatistics").'</strong>: ';
     print '<br>';
     */
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/phpinfo.php b/htdocs/admin/system/phpinfo.php
    index 8664a28b28a..aa502cde421 100644
    --- a/htdocs/admin/system/phpinfo.php
    +++ b/htdocs/admin/system/phpinfo.php
    @@ -116,7 +116,6 @@ foreach($phparray as $key => $value)
     	print '<br>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/system/xcache.php b/htdocs/admin/system/xcache.php
    index 53eaeec085f..b582e61619b 100644
    --- a/htdocs/admin/system/xcache.php
    +++ b/htdocs/admin/system/xcache.php
    @@ -76,6 +76,6 @@ if ($action == 'clear')
     }
     */
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/taxes.php b/htdocs/admin/taxes.php
    index 7c4bf64909f..304f9b79bd0 100644
    --- a/htdocs/admin/taxes.php
    +++ b/htdocs/admin/taxes.php
    @@ -273,6 +273,6 @@ if (! empty($conf->accounting->enabled))
     	print '<br><br><span class="opacitymedium">'.$langs->trans("AccountingAccountForSalesTaxAreDefinedInto", $langs->transnoentitiesnoconv("MenuAccountancy"), $langs->transnoentitiesnoconv("Setup")).'</span>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php
    index 742f966e4cc..5cf72b302c9 100644
    --- a/htdocs/admin/ticket.php
    +++ b/htdocs/admin/ticket.php
    @@ -54,10 +54,13 @@ if ($action == 'updateMask') {
             $error++;
         }
     
    -    if (!$error) {
    -        setEventMessage($langs->trans("SetupSaved"));
    -    } else {
    -        setEventMessage($langs->trans("Error"), 'errors');
    +    if (!$error)
    +    {
    +        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        setEventMessages($langs->trans("Error"), null, 'errors');
         }
     } elseif ($action == 'setmod') {
         // TODO Verifier si module numerotation choisi peut etre active
    @@ -638,6 +641,6 @@ print '</tr>';
     print '</table><br>';
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/ticket_extrafields.php b/htdocs/admin/ticket_extrafields.php
    index 0687a33c52b..6fa70808ec8 100644
    --- a/htdocs/admin/ticket_extrafields.php
    +++ b/htdocs/admin/ticket_extrafields.php
    @@ -16,9 +16,9 @@
      */
     
     /**
    - *      \file       ticket/admin/ticket_extrafields.php
    - *        \ingroup    ticket
    - *        \brief      Page to setup extra fields of ticket
    + *      \file       admin/ticket_extrafields.php
    + *      \ingroup    ticket
    + *      \brief      Page to setup extra fields of ticket
      */
     
     require '../main.inc.php';
    @@ -109,6 +109,6 @@ if ($action == 'edit' && !empty($attrname)) {
         include DOL_DOCUMENT_ROOT . '/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php
    index 1c985e23090..4c69f2ead48 100644
    --- a/htdocs/admin/tools/dolibarr_export.php
    +++ b/htdocs/admin/tools/dolibarr_export.php
    @@ -493,6 +493,7 @@ print '</table>';
     
     </div> 	<!-- end div fichehalfleft -->
     
    +
     <div id="backupdatabaseright" class="fichehalfright" style="height:480px; overflow: auto;">
     <div class="ficheaddleft">
     
    @@ -505,23 +506,96 @@ print '<br>';
     
     </div>
     </div>
    -
    +</form>
     </fieldset>
     
     <br>
    +<!-- Dump of a server -->
    +
    +<form method="post" action="export_files.php" name="dump">
    +<input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>" />
    +<input type="hidden" name="export_type" value="server" />
     
     <fieldset><legend class="legendforfieldsetstep" style="font-size: 3em">2</legend>
    +<div class="fichehalfleft">
    +
     <?php
     print $langs->trans("BackupDesc2",DOL_DATA_ROOT).'<br>';
     print $langs->trans("BackupDescX").'<br><br>';
    +
     ?>
    +
    +<label for="zipfilename_template"> <?php echo $langs->trans("FileNameToGenerate"); ?></label><br>
    +<input type="text" name="zipfilename_template" style="width: 90%"
    +	id="zipfilename_template"
    +	value="<?php
    +$prefix='documents';
    +$ext='zip';
    +
    +$file=$prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.'.$ext;
    +echo $file;
    +?>" /> <br>
    +<br>
    +
    +<?php
    +// Show compression choices
    +print '<div class="formelementrow">';
    +print "\n";
    +
    +print $langs->trans("Compression").': &nbsp; ';
    +$filecompression = $compression;
    +array_shift($filecompression);
    +$filecompression['zip']= array('function' => 'dol_compress_dir', 'id' => 'radio_compression_zip',  'label' => $langs->trans("FormatZip"));
    +
    +foreach($filecompression as $key => $val)
    +{
    +    if (! $val['function'] || function_exists($val['function']))	// Enabled export format
    +    {
    +        print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" checked>';
    +        print ' <label for="'.$val['id'].'">'.$val['label'].'</label>';
    +    }
    +    else	// Disabled export format
    +    {
    +        print '<input type="radio" name="compression" value="'.$key.'" id="'.$val['id'].'" disabled>';
    +        print ' <label for="'.$val['id'].'">'.$val['label'].'</label>';
    +        print ' ('.$langs->trans("NotAvailable").')';
    +    }
    +    print ' &nbsp; &nbsp; ';
    +}
    +
    +print '</div>';
    +print "\n";
    +
    +?>
    +<br>
    +<div align="center"><input type="submit" class="button"
    +	value="<?php echo $langs->trans("GenerateBackup") ?>" id="buttonGo" /><br>
    +<br>
    +</div>
    +
    +</div>
    +
    +<div id="backupdatabaseright" class="fichehalfright" style="height:480px; overflow: auto;">
    +<div class="ficheaddleft">
    +
    +<?php
    +$filearray=dol_dir_list($conf->admin->dir_output.'/documents','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1);
    +$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'documents/',1,0,$langs->trans("NoBackupFileAvailable"),0,$langs->trans("PreviousDumpFiles"));
    +print '<br>';
    +?>
    +
    +
    +</div>
    +</div>
    +
     </fieldset>
    -
    -
    -
     </form>
    +
    +
    +
    +
     <?php
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/tools/dolibarr_import.php b/htdocs/admin/tools/dolibarr_import.php
    index f390c192159..9dc3deec5ac 100644
    --- a/htdocs/admin/tools/dolibarr_import.php
    +++ b/htdocs/admin/tools/dolibarr_import.php
    @@ -24,8 +24,8 @@
     
     require '../../main.inc.php';
     
    -$langs->load("admin");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("other","admin"));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -212,6 +212,6 @@ else if (in_array($type, array('pgsql')))
     </fieldset>
     
     <?php
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/tools/eaccelerator.php b/htdocs/admin/tools/eaccelerator.php
    index d3253c02514..c6209cd7c34 100644
    --- a/htdocs/admin/tools/eaccelerator.php
    +++ b/htdocs/admin/tools/eaccelerator.php
    @@ -168,7 +168,6 @@ function create_script_table($list)
             default:
                 $sortby = "file";
                 ($order == "asc" ? uasort($list, 'compare') : uasort($list, 'revcompare'));
    -
         }
     
         foreach($list as $script) {
    @@ -181,7 +180,6 @@ function create_script_table($list)
             print '</tr>';
         }
         print '</table>';
    -
     }
     
     /**
    @@ -335,7 +333,6 @@ if (function_exists('eaccelerator_get')) {
     
     print "<br><br>";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php
    new file mode 100644
    index 00000000000..809cea3b271
    --- /dev/null
    +++ b/htdocs/admin/tools/export_files.php
    @@ -0,0 +1,166 @@
    +<?php
    +/* Copyright (C) 2006-2014  Laurent Destailleur <eldy@users.sourceforge.net>
    + * Copyright (C) 2011       Juanjo Menent       <jmenent@2byte.es>
    + * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    + *
    +* 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 <http://www.gnu.org/licenses/>.
    +*/
    +
    +/**
    + *		\file 		htdocs/admin/tools/export.php
    + *		\brief      Page to export a database into a dump file
    + */
    +
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
    +
    +$langs->load("admin");
    +
    +$action=GETPOST('action','alpha');
    +$what=GETPOST('what','alpha');
    +$export_type=GETPOST('export_type','alpha');
    +$file=GETPOST('zipfilename_template','alpha');
    +$compression = GETPOST('compression');
    +
    +$sortfield = GETPOST('sortfield','alpha');
    +$sortorder = GETPOST('sortorder','alpha');
    +$page = GETPOST("page",'int');
    +if (! $sortorder) $sortorder="DESC";
    +if (! $sortfield) $sortfield="date";
    +if ($page < 0) { $page = 0; }
    +elseif (empty($page)) $page = 0;
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    +$offset = $limit * $page;
    +
    +if (! $user->admin) accessforbidden();
    +
    +$errormsg='';
    +
    +
    +/*
    + * Actions
    + */
    +
    +if ($action == 'delete')
    +{
    +	$file=$conf->admin->dir_output.'/'.GETPOST('urlfile');
    +	$ret=dol_delete_file($file, 1);
    +	if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
    +	else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
    +	$action='';
    +}
    +
    +
    +/*
    + * View
    + */
    +
    +// Increase limit of time. Works only if we are not in safe mode
    +$ExecTimeLimit=600;
    +if (!empty($ExecTimeLimit))
    +{
    +    $err=error_reporting();
    +    error_reporting(0);     // Disable all errors
    +    //error_reporting(E_ALL);
    +    @set_time_limit($ExecTimeLimit);   // Need more than 240 on Windows 7/64
    +    error_reporting($err);
    +}
    +$MemoryLimit=0;
    +if (!empty($MemoryLimit))
    +{
    +    @ini_set('memory_limit', $MemoryLimit);
    +}
    +
    +$form=new Form($db);
    +$formfile = new FormFile($db);
    +
    +//$help_url='EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad';
    +//llxHeader('','',$help_url);
    +
    +//print load_fiche_titre($langs->trans("Backup"),'','title_setup');
    +
    +
    +// Start with empty buffer
    +$dump_buffer = '';
    +$dump_buffer_len = 0;
    +
    +// We will send fake headers to avoid browser timeout when buffering
    +$time_start = time();
    +
    +
    +$outputdir  = $conf->admin->dir_output.'/documents';
    +$result=dol_mkdir($outputdir);
    +
    +$utils = new Utils($db);
    +
    +if ($compression == 'zip')
    +{
    +    $ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression);
    +    if ($ret < 0)
    +    {
    +        $errormsg = $langs->trans("ErrorFailedToWriteInDir",$outputfile);
    +    }
    +}
    +elseif (in_array($compression, array('gz', 'bz')))
    +{
    +    $file = substr($file, 0, strrpos($file, '.'));
    +    $file .= '.tar';
    +    $cmd = 'tar -cf '.$outputdir."/".$file." --exclude=documents/admin/documents -C ".DOL_DATA_ROOT." ".DOL_DATA_ROOT."/../documents/";
    +    exec($cmd, $out, $retval);
    +    //var_dump($cmd, DOL_DATA_ROOT);exit;
    +    
    +    if ($retval != 0)
    +    {
    +        $langs->load("errors");
    +        dol_syslog("Documents tar retval after exec=".$retval, LOG_ERR);
    +        $errormsg = 'Error tar generation return '.$retval;
    +    }
    +    else
    +    {
    +        if ($compression == 'gz')
    +        {
    +            $cmd = "gzip " . $outputdir."/".$file;
    +        }
    +        if ($compression == 'bz')
    +        {
    +            $cmd = "bzip2 " . $outputdir."/".$file;
    +        }
    +        
    +        exec($cmd, $out, $retval);
    +        if ($retval != 0)
    +        {
    +            $errormsg = 'Error '.$compression.' generation return '.$retval;
    +            unlink($outputdir."/".$file);
    +        }
    +    }
    +}
    +
    +if ($errormsg)
    +{
    +	setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors');
    +}
    +
    +print '<br>';
    +
    +
    +// Redirect t backup page
    +header("Location: dolibarr_export.php");
    +
    +$time_end = time();
    +
    +$db->close();
    +
    diff --git a/htdocs/admin/tools/index.php b/htdocs/admin/tools/index.php
    index 98a490550ca..aed25ae45a3 100644
    --- a/htdocs/admin/tools/index.php
    +++ b/htdocs/admin/tools/index.php
    @@ -24,8 +24,8 @@
     
     require '../../main.inc.php';
     
    -$langs->load("admin");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","admin"));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -56,6 +56,6 @@ print '<br><br>';
     //print '<div class="center"><div class="logo_setup"></div></div>';
     print '<center><div class="logo_setup"></div></center>';				// For a reason I don't know, the div class="center does not works, we must keep the <center>
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php
    index 48d3ef57fd5..9afe7c5fcb3 100644
    --- a/htdocs/admin/tools/listevents.php
    +++ b/htdocs/admin/tools/listevents.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2004-2017  Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012  Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2015       Bahfir Abbes		<bafbes@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -40,10 +41,8 @@ if ($user->societe_id > 0)
     	$socid = $user->societe_id;
     }
     
    -$langs->load("admin");
    -$langs->load("companies");
    -$langs->load("users");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","admin","users","other"));
     
     // Load variable for pagination
     $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    @@ -237,7 +236,7 @@ if ($result)
     	// Lignes des champs de filtres
     	print '<tr class="liste_titre">';
     
    -	print '<td class="liste_titre" width="15%">'.$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).$form->select_date($date_end,'date_end',0,0,0,'',1,0,1).'</td>';
    +	print '<td class="liste_titre" width="15%">'.$form->selectDate($date_start,'date_start',0,0,0,'',1,0).$form->selectDate($date_end,'date_end',0,0,0,'',1,0).'</td>';
     
     	print '<td align="left" class="liste_titre">';
     	print '<input class="flat" type="text" size="10" name="search_code" value="'.$search_code.'">';
    @@ -339,6 +338,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/tools/listsessions.php b/htdocs/admin/tools/listsessions.php
    index 0e9e315f2ac..8ddc1d65525 100644
    --- a/htdocs/admin/tools/listsessions.php
    +++ b/htdocs/admin/tools/listsessions.php
    @@ -25,7 +25,8 @@
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     
    -$langs->load("install");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","install","users","other"));
     
     if (! $user->admin)
     	accessforbidden();
    @@ -40,10 +41,6 @@ if ($user->societe_id > 0)
       $socid = $user->societe_id;
     }
     
    -$langs->load("companies");
    -$langs->load("users");
    -$langs->load("other");
    -
     $sortfield = GETPOST("sortfield",'alpha');
     $sortorder = GETPOST("sortorder",'alpha');
     $page = GETPOST("page",'int');
    @@ -173,7 +170,6 @@ if ($savehandler == 'files')
     		print '<tr '.$bc[false].'><td colspan="6">'.$langs->trans("NoSessionFound",$savepath,$openbasedir).'</td></tr>';
     	}
     	print "</table>";
    -
     }
     else
     {
    @@ -208,5 +204,6 @@ print '</div>';
     
     print '<br>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/tools/purge.php b/htdocs/admin/tools/purge.php
    index f415ed1692c..097fc507240 100644
    --- a/htdocs/admin/tools/purge.php
    +++ b/htdocs/admin/tools/purge.php
    @@ -119,7 +119,6 @@ if (preg_match('/^confirm/i',$choice))
     	print $form->formconfirm($_SERVER["PHP_SELF"].'?choice=allfiles', $langs->trans('Purge'), $langs->trans('ConfirmPurge').img_warning().' ', 'purge', $formquestion, 'no', 2);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/tools/update.php b/htdocs/admin/tools/update.php
    index d0802d6b473..1ec7c98552e 100644
    --- a/htdocs/admin/tools/update.php
    +++ b/htdocs/admin/tools/update.php
    @@ -27,8 +27,8 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/geturl.lib.php';
     
    -$langs->load("admin");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","other"));
     
     $action=GETPOST('action','alpha');
     
    @@ -76,7 +76,7 @@ print $langs->trans("CurrentVersion").' : <strong>'.DOL_VERSION.'</strong><br>';
     if (function_exists('curl_init'))
     {
         $conf->global->MAIN_USE_RESPONSE_TIMEOUT = 10;
    -    
    +
         if ($action == 'getlastversion')
         {
             if ($sfurl)
    @@ -95,7 +95,7 @@ if (function_exists('curl_init'))
                     }
                     $i++;
                 }
    -            
    +
                 // Show version
             	print $langs->trans("LastStableVersion").' : <b>'. (($version != '0.0')?$version:$langs->trans("Unknown")) .'</b><br>';
             }
    @@ -142,7 +142,6 @@ print '<hr>';
     
     print $langs->trans("GoModuleSetupArea", DOL_URL_ROOT.'/admin/modules.php?mode=deploy', $langs->transnoentities("Home").' - '.$langs->transnoentities("Setup").' - '.$langs->transnoentities("Modules"));
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php
    index cc21a8ff717..da26d6648cd 100644
    --- a/htdocs/admin/translation.php
    +++ b/htdocs/admin/translation.php
    @@ -384,7 +384,6 @@ if ($mode == 'overwrite')
     
         print '</table>';
         print '</div>';
    -
     }
     
     if ($mode == 'searchkey')
    @@ -584,6 +583,6 @@ if (! empty($langcode))
     	dol_set_focus('#transvalue');
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/triggers.php b/htdocs/admin/triggers.php
    index 1a1893e2eb0..cd2f33b4cb0 100644
    --- a/htdocs/admin/triggers.php
    +++ b/htdocs/admin/triggers.php
    @@ -84,6 +84,6 @@ foreach ($triggers as $trigger)
     print '</table>';
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php
    index f888c8410bb..2cf8fc5b6f3 100644
    --- a/htdocs/admin/user.php
    +++ b/htdocs/admin/user.php
    @@ -337,5 +337,6 @@ print "<br>";
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php
    index 28f1ad6af2f..c1b55dcec6a 100644
    --- a/htdocs/admin/usergroup.php
    +++ b/htdocs/admin/usergroup.php
    @@ -282,5 +282,6 @@ print "<br>";
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php
    index 80144f93c1f..e36b8d59df3 100644
    --- a/htdocs/admin/website.php
    +++ b/htdocs/admin/website.php
    @@ -167,7 +167,6 @@ if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha'))
                 {
                     $obj = $db->fetch_object($result);
                     $newid=($obj->newid + 1);
    -
                 } else {
                     dol_print_error($db);
                 }
    @@ -322,10 +321,16 @@ if ($action == 'confirm_delete' && $confirm == 'yes')       // delete
     
         if ($website->id > 0)
         {
    -	    $sql = "DELETE from ".MAIN_DB_PREFIX."website_page WHERE fk_website ='".$rowid."'";
    -	    $result = $db->query($sql);
    +    	$sql = "DELETE from ".MAIN_DB_PREFIX."website_account WHERE fk_website ='".$rowid."'";
    +    	$result = $db->query($sql);
     
    -	    $sql = "DELETE from ".MAIN_DB_PREFIX."website WHERE rowid ='".$rowid."'";
    +    	$sql = "DELETE from ".MAIN_DB_PREFIX."website_page WHERE fk_website ='".$rowid."'";
    +    	$result = $db->query($sql);
    +
    +    	$sql = "DELETE from ".MAIN_DB_PREFIX."website_extrafields WHERE fk_object ='".$rowid."'";
    +    	$result = $db->query($sql);
    +
    +    	$sql = "DELETE from ".MAIN_DB_PREFIX."website WHERE rowid ='".$rowid."'";
     	    $result = $db->query($sql);
     	    if (! $result)
     	    {
    @@ -640,9 +645,7 @@ if ($id)
     
     dol_fiche_end();
     
    -//print '<br>';
    -
    -
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/website_options.php b/htdocs/admin/website_options.php
    index c688da0e550..9d724b86390 100644
    --- a/htdocs/admin/website_options.php
    +++ b/htdocs/admin/website_options.php
    @@ -143,9 +143,8 @@ else
     
     
     dol_fiche_end();
    -//print '<br>';
    -
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php
    index b5bdec73f3e..24a39ce827a 100644
    --- a/htdocs/admin/workflow.php
    +++ b/htdocs/admin/workflow.php
    @@ -187,7 +187,6 @@ if ($nbqualified == 0)
     }
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php
    index 63f66295556..6d6ef4578cd 100644
    --- a/htdocs/api/class/api.class.php
    +++ b/htdocs/api/class/api.class.php
    @@ -94,7 +94,8 @@ class DolibarrApi
          * @param   object  $object	Object to clean
          * @return	array	Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             // Remove $db object property for object
             unset($object->db);
    @@ -218,9 +219,11 @@ class DolibarrApi
     	 * @param string	$feature2		Feature to check, second level of permission (optional). Can be or check with 'level1|level2'.
     	 * @param string	$dbt_keyfield   Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
     	 * @param string	$dbt_select     Field name for select if not rowid. Not used if objectid is null (optional)
    +     * @return bool
     	 * @throws RestException
     	 */
    -	static function _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid') {
    +    static function _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
    +    {
     
     		// Features/modules to check
     		$featuresarray = array($resource);
    @@ -251,7 +254,7 @@ class DolibarrApi
     	    //$tmp=preg_replace_all('/'.$regexstring.'/', '', $sqlfilters);
     	    $tmp=$sqlfilters;
     	    $ok=0;
    -	    $i=0; $nb=count($tmp);
    +	    $i=0; $nb=strlen($tmp);
     	    $counter=0;
     	    while ($i < $nb)
     	    {
    @@ -268,6 +271,7 @@ class DolibarrApi
     	    return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Function to forge a SQL criteria
     	 *
    @@ -276,6 +280,7 @@ class DolibarrApi
     	 */
     	static function _forge_criteria_callback($matches)
     	{
    +        // phpcs:enable
     	    global $db;
     
     	    //dol_syslog("Convert matches ".$matches[1]);
    diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php
    index d067d6e2ad6..e453bd331c2 100644
    --- a/htdocs/api/class/api_access.class.php
    +++ b/htdocs/api/class/api_access.class.php
    @@ -59,8 +59,7 @@ class DolibarrApiAccess implements iAuthenticate
     	 */
     	public static $user = '';
     
    -    // @codingStandardsIgnoreStart
    -
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName
     	/**
     	 * Check access
     	 *
    @@ -69,6 +68,7 @@ class DolibarrApiAccess implements iAuthenticate
     	 */
     	public function __isAllowed()
     	{
    +        // phpcs:enable
     		global $conf, $db;
     
     		$login = '';
    @@ -166,6 +166,7 @@ class DolibarrApiAccess implements iAuthenticate
     	    return in_array(static::$role, (array) $requirefortest) || static::$role == 'admin';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName
     	/**
     	 * @return string string to be used with WWW-Authenticate header
     	 * @example Basic
    @@ -174,9 +175,9 @@ class DolibarrApiAccess implements iAuthenticate
     	 */
     	public function __getWWWAuthenticateString()
         {
    +        // phpcs:enable
             return '';
         }
    -    // @codingStandardsIgnoreEnd
     
     	/**
     	 * Verify access
    @@ -196,6 +197,5 @@ class DolibarrApiAccess implements iAuthenticate
             return $requires
                 ? static::$role == 'admin' || in_array(static::$role, (array) $requires)
                 : true;
    -
         }
     }
    diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php
    index 07f124741fe..66c293f2cb0 100644
    --- a/htdocs/api/class/api_documents.class.php
    +++ b/htdocs/api/class/api_documents.class.php
    @@ -356,6 +356,22 @@ class Documents extends DolibarrApi
     
     			$upload_dir = $conf->facture->dir_output . "/" . get_exdir(0, 0, 0, 1, $object, 'invoice');
     		}
    +		else if ($modulepart == 'agenda' || $modulepart == 'action' || $modulepart == 'event')
    +		{
    +			require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
    +
    +			if (!DolibarrApiAccess::$user->rights->agenda->myactions->read && !DolibarrApiAccess::$user->rights->agenda->allactions->read) {
    +				throw new RestException(401);
    +			}
    +
    +			$object = new ActionComm($this->db);
    +			$result=$object->fetch($id, $ref);
    +			if ( ! $result ) {
    +				throw new RestException(404, 'Event not found');
    +			}
    +
    +			$upload_dir = $conf->agenda->dir_output.'/'.dol_sanitizeFileName($object->ref);
    +		}
     		else
     		{
     			throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
    diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php
    index 56808819b3f..86d1cfff87c 100644
    --- a/htdocs/api/class/api_login.class.php
    +++ b/htdocs/api/class/api_login.class.php
    @@ -26,7 +26,11 @@ require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
     class Login
     {
     
    -	function __construct() {
    +    /**
    +     * Constructor of the class
    +     */
    +    function __construct()
    +    {
     		global $db;
     		$this->db = $db;
     	}
    @@ -51,7 +55,8 @@ class Login
     	 * @url GET /
     	 * @url POST /
     	 */
    -	public function index($login, $password, $entity='', $reset=0) {
    +    public function index($login, $password, $entity='', $reset=0)
    +    {
     
     	    global $conf, $dolibarr_main_authentication, $dolibarr_auto_user;
     
    diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
    index ef2b4c8bb6d..60a51074d58 100644
    --- a/htdocs/api/class/api_setup.class.php
    +++ b/htdocs/api/class/api_setup.class.php
    @@ -1,8 +1,9 @@
     <?php
     /* Copyright (C) 2016   Xebax Christy           <xebax@wanadoo.fr>
      * Copyright (C) 2016	Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2017	Regis Houssin	<regis.houssin@capnetworks.com>
    - * Copyright (C) 2017	Neil Orley	<neil.orley@oeris.fr>
    + * Copyright (C) 2017	Regis Houssin	        <regis.houssin@capnetworks.com>
    + * Copyright (C) 2017	Neil Orley	            <neil.orley@oeris.fr>
    + * Copyright (C) 2018   Frédéric France         <frederic.france@netlogic.fr>
      *
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -121,7 +122,7 @@ class Setup extends DolibarrApi
          * @param string    $filter     To filter the countries by name
          * @param string    $lang       Code of the language the label of the countries must be translated to
          * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of countries
    +     * @return array                List of countries
          *
          * @url     GET dictionary/countries
          *
    @@ -188,6 +189,7 @@ class Setup extends DolibarrApi
          * @param int       $id        ID of country
          * @param string    $lang      Code of the language the name of the
          *                             country must be translated to
    +     * @return array 			   Array of cleaned object properties
          *
          * @url     GET dictionary/countries/{id}
          *
    @@ -293,6 +295,7 @@ class Setup extends DolibarrApi
          * @param Ccountry $country   Country
          * @param string   $lang      Code of the language the name of the
          *                            country must be translated to
    +     * @return void
          */
         private function translateLabel($country, $lang)
         {
    @@ -377,6 +380,66 @@ class Setup extends DolibarrApi
             return $list;
         }
     
    +    /**
    +     * Get the list of civility.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $module     To filter on module events
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/civility
    +     *
    +     * @throws RestException
    +     */
    +    function getListOfCivility($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $sqlfilters = '')
    +    {
    +        $list = array();
    +
    +        $sql = "SELECT rowid, code, label, module";
    +        $sql.= " FROM ".MAIN_DB_PREFIX."c_civility as t";
    +        $sql.= " WHERE t.active = 1";
    +        if ($module)    $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
    +        // Add sql filters
    +        if ($sqlfilters)
    +        {
    +            if (! DolibarrApi::_checkFilters($sqlfilters))
    +            {
    +                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +            }
    +	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +            $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +        }
    +
    +
    +        $sql.= $this->db->order($sortfield, $sortorder);
    +
    +        if ($limit) {
    +            if ($page < 0) {
    +                $page = 0;
    +            }
    +            $offset = $limit * $page;
    +
    +            $sql .= $this->db->plimit($limit, $offset);
    +        }
    +
    +        $result = $this->db->query($sql);
    +
    +        if ($result) {
    +            $num = $this->db->num_rows($result);
    +            $min = min($num, ($limit <= 0 ? $num : $limit));
    +            for ($i = 0; $i < $min; $i++) {
    +                $list[] = $this->db->fetch_object($result);
    +            }
    +        } else {
    +            throw new RestException(503, 'Error when retrieving list of civility : '.$this->db->lasterror());
    +        }
    +
    +        return $list;
    +    }
     
         /**
          * Get the list of extra fields.
    @@ -579,6 +642,185 @@ class Setup extends DolibarrApi
             return $list;
         }
     
    +     /**
    +     * Get the list of tickets categories.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/ticket_categories
    +     *
    +     * @throws RestException
    +     */
    +    function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
    +    	$list = array();
    +
    +    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    +    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
    +    	$sql.= " WHERE t.active = 1";
    +    	// Add sql filters
    +    	if ($sqlfilters)
    +    	{
    +    		if (! DolibarrApi::_checkFilters($sqlfilters))
    +    		{
    +    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +    		}
    +    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +    	}
    +
    +
    +    	$sql.= $this->db->order($sortfield, $sortorder);
    +
    +    	if ($limit) {
    +    		if ($page < 0) {
    +    			$page = 0;
    +    		}
    +    		$offset = $limit * $page;
    +
    +    		$sql .= $this->db->plimit($limit, $offset);
    +    	}
    +
    +    	$result = $this->db->query($sql);
    +
    +    	if ($result) {
    +    		$num = $this->db->num_rows($result);
    +    		$min = min($num, ($limit <= 0 ? $num : $limit));
    +    		for ($i = 0; $i < $min; $i++) {
    +    			$list[] = $this->db->fetch_object($result);
    +    		}
    +    	} else {
    +    		throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
    +    	}
    +
    +    	return $list;
    +    }
    +
    +    /**
    +     * Get the list of tickets severity.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/ticket_severities
    +     *
    +     * @throws RestException
    +     */
    +    function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
    +    	$list = array();
    +
    +    	$sql = "SELECT rowid, code, pos,  label, use_default, color, description";
    +    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
    +    	$sql.= " WHERE t.active = 1";
    +    	// Add sql filters
    +    	if ($sqlfilters)
    +    	{
    +    		if (! DolibarrApi::_checkFilters($sqlfilters))
    +    		{
    +    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +    		}
    +    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +    	}
    +
    +
    +    	$sql.= $this->db->order($sortfield, $sortorder);
    +
    +    	if ($limit) {
    +    		if ($page < 0) {
    +    			$page = 0;
    +    		}
    +    		$offset = $limit * $page;
    +
    +    		$sql .= $this->db->plimit($limit, $offset);
    +    	}
    +
    +    	$result = $this->db->query($sql);
    +
    +    	if ($result) {
    +    		$num = $this->db->num_rows($result);
    +    		$min = min($num, ($limit <= 0 ? $num : $limit));
    +    		for ($i = 0; $i < $min; $i++) {
    +    			$list[] = $this->db->fetch_object($result);
    +    		}
    +    	} else {
    +    		throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
    +    	}
    +
    +    	return $list;
    +    }
    +
    +    /**
    +     * Get the list of tickets types.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/ticket_types
    +     *
    +     * @throws RestException
    +     */
    +    function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
    +    	$list = array();
    +
    +    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    +    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
    +    	$sql.= " WHERE t.active = 1";
    +    	if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'";
    +    	if ($module)    $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
    +    	// Add sql filters
    +    	if ($sqlfilters)
    +    	{
    +    		if (! DolibarrApi::_checkFilters($sqlfilters))
    +    		{
    +    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +    		}
    +    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +    	}
    +
    +
    +    	$sql.= $this->db->order($sortfield, $sortorder);
    +
    +    	if ($limit) {
    +    		if ($page < 0) {
    +    			$page = 0;
    +    		}
    +    		$offset = $limit * $page;
    +
    +    		$sql .= $this->db->plimit($limit, $offset);
    +    	}
    +
    +    	$result = $this->db->query($sql);
    +
    +    	if ($result) {
    +    		$num = $this->db->num_rows($result);
    +    		$min = min($num, ($limit <= 0 ? $num : $limit));
    +    		for ($i = 0; $i < $min; $i++) {
    +    			$list[] = $this->db->fetch_object($result);
    +    		}
    +    	} else {
    +    		throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
    +    	}
    +
    +    	return $list;
    +    }
    +
     
         /**
          * Do a test of integrity for files and setup.
    @@ -863,11 +1105,11 @@ class Setup extends DolibarrApi
         			// Show warning
         			if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3))
         			{
    -    				//setEventMessage($langs->trans("FileIntegrityIsStrictlyConformedWithReference"));
    +    				//setEventMessages($langs->trans("FileIntegrityIsStrictlyConformedWithReference"), null, 'mesgs');
         			}
         			else
         			{
    -    				//setEventMessage($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), 'warnings');
    +    				//setEventMessages($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), null, 'warnings');
         			}
         		}
         		else
    @@ -916,5 +1158,4 @@ class Setup extends DolibarrApi
     
         	return array('resultcode'=>$resultcode, 'resultcomment'=>$resultcomment, 'expectedchecksum'=> $outexpectedchecksum, 'currentchecksum'=> $outcurrentchecksum, 'out'=>$out);
         }
    -
     }
    diff --git a/htdocs/api/class/api_status.class.php b/htdocs/api/class/api_status.class.php
    index ea61731b51a..3ade4ea51b8 100644
    --- a/htdocs/api/class/api_status.class.php
    +++ b/htdocs/api/class/api_status.class.php
    @@ -26,18 +26,21 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
      */
     class Status
     {
    -	/**
    +    /**
          * Get status (Dolibarr version)
    -	 */
    -	function index() {
    -		global $conf;
    +     *
    +     * @return array
    +     */
    +    function index()
    +    {
    +        global $conf;
     
    -		return array(
    -			'success' => array(
    -				'code' => 200,
    -				'dolibarr_version' => DOL_VERSION,
    -				'access_locked' => (empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)?'0':$conf->global->MAIN_ONLY_LOGIN_ALLOWED)
    -			)
    -		);
    +        return array(
    +            'success' => array(
    +                'code' => 200,
    +                'dolibarr_version' => DOL_VERSION,
    +                'access_locked' => (empty($conf->global->MAIN_ONLY_LOGIN_ALLOWED)?'0':$conf->global->MAIN_ONLY_LOGIN_ALLOWED),
    +            ),
    +        );
         }
     }
    diff --git a/htdocs/asset/admin/assets_extrafields.php b/htdocs/asset/admin/assets_extrafields.php
    index 1cdf78df4bf..f220d5cb849 100644
    --- a/htdocs/asset/admin/assets_extrafields.php
    +++ b/htdocs/asset/admin/assets_extrafields.php
    @@ -64,7 +64,7 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
     print load_fiche_titre($langs->trans("AssetsSetup"),$linkback,'title_setup');
     
     
    -$head = AssetsAdminPrepareHead();
    +$head = asset_admin_prepare_head();
     
     dol_fiche_head($head, 'attributes', $langs->trans("Assets"), -1, 'generic');
     
    @@ -109,6 +109,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/asset/admin/assets_type_extrafields.php b/htdocs/asset/admin/assets_type_extrafields.php
    index d828bffa4de..a791078f37b 100644
    --- a/htdocs/asset/admin/assets_type_extrafields.php
    +++ b/htdocs/asset/admin/assets_type_extrafields.php
    @@ -63,7 +63,7 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
     print load_fiche_titre($langs->trans("AssetsSetup"),$linkback,'title_setup');
     
     
    -$head = AssetsAdminPrepareHead();
    +$head = asset_admin_prepare_head();
     
     dol_fiche_head($head, 'attributes_type', $langs->trans("Assets"), -1, 'generic');
     
    @@ -107,6 +107,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php
    index c240f350590..57738309abd 100644
    --- a/htdocs/asset/admin/setup.php
    +++ b/htdocs/asset/admin/setup.php
    @@ -58,7 +58,7 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
     print load_fiche_titre($langs->trans("AssetsSetup"),$linkback,'title_setup');
     
     
    -$head = AssetsAdminPrepareHead();
    +$head = asset_admin_prepare_head();
     
     dol_fiche_head($head, 'settings', $langs->trans("Assets"), -1, 'generic');
     
    @@ -107,9 +107,8 @@ else
     	print '</div>';
     }
     
    -
    -// Page end
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php
    index 0187dc93939..4f7061aed20 100644
    --- a/htdocs/asset/card.php
    +++ b/htdocs/asset/card.php
    @@ -17,7 +17,7 @@
      */
     
     /**
    - *  \file       card.php
    + *  \file       htdocs/asset/card.php
      *  \ingroup    asset
      *  \brief      Page to create/edit/view asset
      */
    @@ -25,8 +25,8 @@
     require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php';
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("asset"));
    @@ -203,7 +203,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     {
     	$res = $object->fetch_optionals($object->id, $extralabels);
     
    -	$head = AssetsPrepareHead($object);
    +	$head = asset_prepare_head($object);
     	dol_fiche_head($head, 'card', $langs->trans("Asset"), -1, 'generic');
     
     	$formconfirm = '';
    @@ -221,12 +221,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
     	}
     
    -	if (! $formconfirm) {
    -		$parameters = array('lineid' => $lineid);
    -		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php
    index 4ab05ce675c..22e24703bc3 100644
    --- a/htdocs/asset/class/asset.class.php
    +++ b/htdocs/asset/class/asset.class.php
    @@ -35,18 +35,22 @@ class Asset extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'asset';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'asset';
    +
     	/**
     	 * @var int  Does module support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 0;
    +
     	/**
     	 * @var int  Does asset support extrafields ? 0=No, 1=Yes
     	 */
     	public $isextrafieldmanaged = 1;
    +
     	/**
     	 * @var string String with name of icon for asset. Must be the part after the 'object_' into object_asset.png
     	 */
    @@ -91,20 +95,59 @@ class Asset extends CommonObject
     		'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1,),
     		'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Active', '-1'=>'Cancel')),
     	);
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    -	public $label;
    +
    +    /**
    +     * @var string Asset label
    +     */
    +    public $label;
    +
     	public $amount;
    -	public $fk_soc;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +    public $fk_soc;
    +
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
    +
     	public $note_public;
     	public $note_private;
     	public $date_creation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
     	public $import_key;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
     
     	// If this object has a subtable with lines
    @@ -329,6 +372,7 @@ class Asset extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -338,43 +382,38 @@ class Asset extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
    -		if ($mode == 0)
    -		{
    -			$prefix='';
    -			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    -		}
    -		if ($mode == 1)
    +		if ($mode == 0 || $mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
     	}
     
    @@ -424,7 +463,6 @@ class Asset extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -461,4 +499,4 @@ class Asset extends CommonObject
     
     		return 0;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/asset/class/asset_type.class.php b/htdocs/asset/class/asset_type.class.php
    index 51ea3a0c799..8eb915f95eb 100644
    --- a/htdocs/asset/class/asset_type.class.php
    +++ b/htdocs/asset/class/asset_type.class.php
    @@ -29,21 +29,44 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class AssetType extends CommonObject
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element = 'asset_type';
    -	public $element = 'asset_type';
    -	public $picto = 'group';
    -	public $ismultientitymanaged = 1;  // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     
    -	/** @var string Label */
    -	public $label;
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element = 'asset_type';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'group';
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
    +	/**
    +     * @var string Asset type label
    +     */
    +    public $label;
    +
     	/** @var string Accountancy code asset */
     	public $accountancy_code_asset;
    +
     	/** @var string Accountancy code depreciation asset */
     	public $accountancy_code_depreciation_asset;
    +
     	/** @var string Accountancy code depreciation expense */
     	public $accountancy_code_depreciation_expense;
    +
     	/** @var string 	Public note */
     	public $note;
    +
     	/** @var array Array of asset */
     	public $asset=array();
     
    @@ -274,6 +297,7 @@ class AssetType extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of asset's type
     	 *
    @@ -281,6 +305,7 @@ class AssetType extends CommonObject
     	 */
     	function liste_array()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$assettypes = array();
    @@ -429,5 +454,4 @@ class AssetType extends CommonObject
     	{
     		return '';
     	}
    -
     }
    diff --git a/htdocs/asset/document.php b/htdocs/asset/document.php
    index 66baaae196c..c1332ed10a2 100644
    --- a/htdocs/asset/document.php
    +++ b/htdocs/asset/document.php
    @@ -17,7 +17,7 @@
      */
     
     /**
    - *  \file       document.php
    + *  \file       htdocs/asset/document.php
      *  \ingroup    asset
      *  \brief      Tab for documents linked to Assets
      */
    @@ -95,12 +95,12 @@ if ($object->id)
     	 * Show tabs
     	 */
     	if (! empty($conf->notification->enabled)) $langs->load("mails");
    -	$head = AssetsPrepareHead($object);
    +	$head = asset_prepare_head($object);
     
     	dol_fiche_head($head, 'document', $langs->trans("Asset"), -1, 'generic');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -148,6 +148,6 @@ else
     	accessforbidden('',0,0);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/asset/info.php b/htdocs/asset/info.php
    index 71460f31a2c..e01316ae685 100644
    --- a/htdocs/asset/info.php
    +++ b/htdocs/asset/info.php
    @@ -16,7 +16,7 @@
      */
     
     /**
    - *  \file       info.php
    + *  \file       htdocs/asset/info.php
      *  \ingroup    asset
      *  \brief      Page to show an asset information
      */
    @@ -55,7 +55,7 @@ $form = new Form($db);
     
     $object->info($id);
     
    -$head = AssetsPrepareHead($object);
    +$head = asset_prepare_head($object);
     
     dol_fiche_head($head, 'info', $langs->trans("Asset"), -1, 'generic');
     
    @@ -79,5 +79,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php
    index 5dc8b2c6866..fa965aade5b 100644
    --- a/htdocs/asset/list.php
    +++ b/htdocs/asset/list.php
    @@ -18,7 +18,7 @@
      */
     
     /**
    - *   	\file       list.php
    + *   	\file       htdocs/asset/list.php
      *		\ingroup    asset
      *		\brief      List page for asset
      */
    diff --git a/htdocs/asset/note.php b/htdocs/asset/note.php
    index cf0166df96f..f76c6ea028f 100644
    --- a/htdocs/asset/note.php
    +++ b/htdocs/asset/note.php
    @@ -17,7 +17,7 @@
      */
     
     /**
    - *  \file       note.php
    + *  \file       htdocs/asset/note.php
      *  \ingroup    asset
      *  \brief      Card with notes on Asset
      */
    @@ -78,7 +78,7 @@ if ($id > 0 || ! empty($ref))
     {
     	$object->fetch_thirdparty();
     
    -	$head = AssetsPrepareHead($object);
    +	$head = asset_prepare_head($object);
     
     	dol_fiche_head($head, 'note', $langs->trans("Asset"), -1, 'generic');
     
    @@ -144,6 +144,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/asset/type.php b/htdocs/asset/type.php
    index f4409ee5417..9e06c4a765d 100644
    --- a/htdocs/asset/type.php
    +++ b/htdocs/asset/type.php
    @@ -356,7 +356,6 @@ if ($action == 'create')
     		print '<td>';
     		print $formaccounting->select_account($object->accountancy_code_depreciation_expense, 'accountancy_code_depreciation_expense', 1, '', 1, 1);
     		print '</td></tr>';
    -
     	}
     	else // For external software
     	{
    @@ -732,7 +731,6 @@ if ($rowid > 0)
     		{
     			dol_print_error($db);
     		}
    -
     	}
     
     	/* ************************************************************************** */
    @@ -782,7 +780,6 @@ if ($rowid > 0)
     			print '<td>';
     			print $formaccounting->select_account($object->accountancy_code_depreciation_expense, 'accountancy_code_depreciation_expense', 1, '', 1, 1);
     			print '</td></tr>';
    -
     		}
     		else // For external software
     		{
    @@ -851,7 +848,6 @@ if ($rowid > 0)
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/asterisk/cidlookup.php b/htdocs/asterisk/cidlookup.php
    index e6b4985f6b8..56e90c1a639 100644
    --- a/htdocs/asterisk/cidlookup.php
    +++ b/htdocs/asterisk/cidlookup.php
    @@ -31,9 +31,9 @@ include '../master.inc.php';
     
     $phone = GETPOST('phone');
     $notfound = $langs->trans("Unknown");
    - 
    +
     // Security check
    -if (empty($conf->clicktodial->enabled)) 
    +if (empty($conf->clicktodial->enabled))
     {
         print "Error: Module Click to dial is not enabled.\n";
         exit;
    diff --git a/htdocs/asterisk/wrapper.php b/htdocs/asterisk/wrapper.php
    index 8cd5ff979a0..66ff541d499 100644
    --- a/htdocs/asterisk/wrapper.php
    +++ b/htdocs/asterisk/wrapper.php
    @@ -190,5 +190,6 @@ else {
         print 'Bad parameters in URL. Must be '.$_SERVER['PHP_SELF'].'?caller=99999&called=99999&login=xxxxx&password=xxxxx';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php
    index 26386052480..7086af7f17e 100644
    --- a/htdocs/barcode/codeinit.php
    +++ b/htdocs/barcode/codeinit.php
    @@ -319,6 +319,6 @@ if ($conf->product->enabled || $conf->product->service)
     print '</form>';
     print '<br>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php
    index 7dfec76b39e..a1f3632fd2f 100644
    --- a/htdocs/barcode/printsheet.php
    +++ b/htdocs/barcode/printsheet.php
    @@ -178,19 +178,19 @@ if ($action == 'builddoc')
     	{
     		// List of values to scan for a replacement
     		$substitutionarray = array (
    -		'%LOGIN%'=>$user->login,
    -		'%COMPANY%'=>$mysoc->name,
    -		'%ADDRESS%'=>$mysoc->address,
    -		'%ZIP%'=>$mysoc->zip,
    -		'%TOWN%'=>$mysoc->town,
    -		'%COUNTRY%'=>$mysoc->country,
    -		'%COUNTRY_CODE%'=>$mysoc->country_code,
    -		'%EMAIL%'=>$mysoc->email,
    -		'%YEAR%'=>$year,
    -		'%MONTH%'=>$month,
    -		'%DAY%'=>$day,
    -		'%DOL_MAIN_URL_ROOT%'=>DOL_MAIN_URL_ROOT,
    -		'%SERVER%'=>"http://".$_SERVER["SERVER_NAME"]."/"
    +		    '%LOGIN%' => $user->login,
    +		    '%COMPANY%' => $mysoc->name,
    +		    '%ADDRESS%' => $mysoc->address,
    +		    '%ZIP%' => $mysoc->zip,
    +		    '%TOWN%' => $mysoc->town,
    +		    '%COUNTRY%' => $mysoc->country,
    +		    '%COUNTRY_CODE%' => $mysoc->country_code,
    +		    '%EMAIL%' => $mysoc->email,
    +		    '%YEAR%' => $year,
    +		    '%MONTH%' => $month,
    +		    '%DAY%' => $day,
    +		    '%DOL_MAIN_URL_ROOT%' => DOL_MAIN_URL_ROOT,
    +		    '%SERVER%' => "http://".$_SERVER["SERVER_NAME"]."/",
     		);
     		complete_substitutions_array($substitutionarray, $langs);
     
    @@ -416,7 +416,7 @@ print $langs->trans("BarcodeType").' &nbsp; ';
     print '</div><div class="tagtd" style="overflow: hidden; white-space: nowrap; max-width: 300px;">';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php';
     $formbarcode = new FormBarCode($db);
    -$formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1);
    +print $formbarcode->selectBarcodeType($fk_barcode_type, 'fk_barcode_type', 1);
     print '</div></div>';
     
     // Barcode value
    @@ -441,6 +441,6 @@ print '<br><input class="button" type="submit" id="submitformbarcodegen" '.((GET
     print '</form>';
     print '<br>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/blockedlog/admin/blockedlog.php b/htdocs/blockedlog/admin/blockedlog.php
    index 326fea79c5d..8c2835d856c 100644
    --- a/htdocs/blockedlog/admin/blockedlog.php
    +++ b/htdocs/blockedlog/admin/blockedlog.php
    @@ -178,5 +178,6 @@ if (GETPOST('withtab','alpha'))
     
     print '<br><br>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php
    index b93856b7af5..734e9d31f67 100644
    --- a/htdocs/blockedlog/admin/blockedlog_list.php
    +++ b/htdocs/blockedlog/admin/blockedlog_list.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2017      ATM Consulting      <contact@atm-consulting.fr>
    - * Copyright (C) 2017-2018 Laurent Destailleur <eldy@destailleur.fr>
    +/* Copyright (C) 2017       ATM Consulting          <contact@atm-consulting.fr>
    + * Copyright (C) 2017-2018  Laurent Destailleur     <eldy@destailleur.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -131,7 +132,7 @@ else if (GETPOST('downloadcsv','alpha'))
     		{
     			// Make the first fetch to get first line
     			$obj = $db->fetch_object($res);
    -			if ($obj) 
    +			if ($obj)
     			{
     				$previoushash = $block_static->getPreviousHash(0, $obj->rowid);
     				$firstid = $obj->rowid;
    @@ -145,7 +146,7 @@ else if (GETPOST('downloadcsv','alpha'))
     		else
     		{
     			$error++;
    -			setEventMessage($db->lasterror, 'errors');
    +			setEventMessages($db->lasterror, null, 'errors');
     		}
     	}
     
    @@ -250,7 +251,7 @@ else if (GETPOST('downloadcsv','alpha'))
     		}
     		else
     		{
    -			setEventMessage($db->lasterror, 'errors');
    +			setEventMessages($db->lasterror, null, 'errors');
     		}
     	}
     }
    @@ -372,10 +373,10 @@ print '<td class="liste_titre">&nbsp;</td>';
     
     print '<td class="liste_titre">';
     //print $langs->trans("from").': ';
    -$form->select_date($search_start,'search_start');
    +print $form->selectDate($search_start,'search_start');
     //print '<br>';
     //print $langs->trans("to").': ';
    -$form->select_date($search_end,'search_end');
    +print $form->selectDate($search_end,'search_end');
     print '</td>';
     
     // User
    @@ -443,7 +444,6 @@ if (! empty($conf->global->BLOCKEDLOG_SCAN_ALL_FOR_LOWERIDINERROR))
     
     	// TODO Make a full scan of table in reverse order of id of $block, so we can use the parameter $previoushash into checkSignature to save requests
     	// to find the $loweridinerror.
    -
     }
     else
     {
    @@ -537,7 +537,6 @@ if (is_array($blocks))
     			print '<td></td>';
     
     			print '</tr>';
    -
     		}
     	}
     }
    @@ -607,5 +606,6 @@ if (GETPOST('withtab','alpha'))
     
     print '<br><br>';
     
    +// End of page
     llxFooter();
    -$db->close();
    +$db->close();
    \ No newline at end of file
    diff --git a/htdocs/blockedlog/ajax/authority.php b/htdocs/blockedlog/ajax/authority.php
    index 7bde15aa879..1104eeb3c02 100644
    --- a/htdocs/blockedlog/ajax/authority.php
    +++ b/htdocs/blockedlog/ajax/authority.php
    @@ -53,7 +53,6 @@ if($auth->fetch(0, $signature)<=0) {
     if(!empty($hash)) {
     
     	echo $auth->checkBlockchain($hash) ? 'hashisok' : 'hashisjunk';
    -
     }
     elseif(!empty($newblock)){
     	if($auth->checkBlock($newblock)) {
    @@ -65,7 +64,6 @@ elseif(!empty($newblock)){
     	else{
     
     		echo 'blockalreadyadded';
    -
     	}
     }
     else{
    diff --git a/htdocs/blockedlog/ajax/check_signature.php b/htdocs/blockedlog/ajax/check_signature.php
    index 199f9051e07..9617e6cd1ef 100644
    --- a/htdocs/blockedlog/ajax/check_signature.php
    +++ b/htdocs/blockedlog/ajax/check_signature.php
    @@ -49,7 +49,6 @@ $auth->signature = $block_static->getSignature();
     
     foreach($blocks as &$b) {
     	$auth->blockchain.=$b->signature;
    -
     }
     
     $hash = $auth->getBlockchainHash();
    diff --git a/htdocs/blockedlog/class/authority.class.php b/htdocs/blockedlog/class/authority.class.php
    index b1084b01a54..0d0fc183b6c 100644
    --- a/htdocs/blockedlog/class/authority.class.php
    +++ b/htdocs/blockedlog/class/authority.class.php
    @@ -50,10 +50,9 @@ class BlockedLogAuthority
     	 *
     	 *      @param		DoliDB		$db      Database handler
     	 */
    -    public function __construct($db) {
    -
    +    public function __construct($db)
    +    {
         	$this->db = $db;
    -
     	}
     
     	/**
    @@ -61,7 +60,8 @@ class BlockedLogAuthority
     	 *
     	 *	@return     string         			blockchain
     	 */
    -	public function getLocalBlockChain() {
    +    public function getLocalBlockChain()
    +    {
     
     		$block_static = new BlockedLog($this->db);
     
    @@ -73,7 +73,6 @@ class BlockedLogAuthority
     
     		foreach($blocks as &$b) {
     			$this->blockchain.=$b->signature;
    -
     		}
     
     		return $this->blockchain;
    @@ -84,10 +83,10 @@ class BlockedLogAuthority
     	 *
     	 *	@return     string         			hash md5 of blockchain
     	 */
    -	public function getBlockchainHash() {
    +    public function getBlockchainHash()
    +    {
     
     		return md5($this->signature.$this->blockchain);
    -
     	}
     
     	/**
    @@ -96,21 +95,22 @@ class BlockedLogAuthority
     	 *	@param      string		$hash		hash md5 of blockchain to test
     	 *	@return     boolean
     	 */
    -	public function checkBlockchain($hash) {
    +    public function checkBlockchain($hash)
    +    {
     
     		return ($hash === $this->getBlockchainHash() );
    -
     	}
     
     	/**
     	 *	Add a new block to the chain
     	 *
    -	 *	@param      string		$block		new block to chain
    +     *	@param      string		$block		new block to chain
    +     *  @return void
     	 */
    -	public function addBlock($block) {
    +    public function addBlock($block)
    +    {
     
     		$this->blockchain.=$block;
    -
     	}
     
     	/**
    @@ -119,7 +119,8 @@ class BlockedLogAuthority
     	 *	@param      string		$block		new block to chain
     	 *	@return     boolean
     	 */
    -	public function checkBlock($block) {
    +    public function checkBlock($block)
    +    {
     
     		if(strlen($block)!=64) return false;
     
    @@ -141,7 +142,8 @@ class BlockedLogAuthority
     	 *	@param      string		$signature		Signature of object to load
     	 *	@return     int         				>0 if OK, <0 if KO, 0 if not found
     	 */
    -	public function fetch($id, $signature='') {
    +    public function fetch($id, $signature='')
    +    {
     
     		global $langs;
     
    @@ -189,7 +191,6 @@ class BlockedLogAuthority
     			$this->error=$this->db->error();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -198,7 +199,8 @@ class BlockedLogAuthority
     	 *	@param	User	$user      		Object user that create
     	 *	@return	int						<0 if KO, >0 if OK
     	 */
    -	public function create($user) {
    +    public function create($user)
    +    {
     
     		global $conf,$langs,$hookmanager;
     
    @@ -243,7 +245,6 @@ class BlockedLogAuthority
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -252,7 +253,8 @@ class BlockedLogAuthority
     	 *	@param	User	$user      		Object user that create
     	 *	@return	int						<0 if KO, >0 if OK
     	 */
    -	public function update($user) {
    +    public function update($user)
    +    {
     
     		global $conf,$langs,$hookmanager;
     
    @@ -281,7 +283,6 @@ class BlockedLogAuthority
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -289,7 +290,8 @@ class BlockedLogAuthority
     	 *
     	 *	@return	int						<0 if KO, >0 if OK
     	 */
    -	public function syncSignatureWithAuthority() {
    +    public function syncSignatureWithAuthority()
    +    {
     		global $conf, $langs;
     
     		//TODO create cron task on activation
    @@ -316,18 +318,14 @@ class BlockedLogAuthority
     			if($res === 'blockalreadyadded' || $res === 'blockadded') {
     
     				$block->setCertified();
    -
     			}
     			else {
     
     				$this->error = $langs->trans('ImpossibleToContactAuthority ',$url);
     				return -1;
     			}
    -
    -
     		}
     
     		return 1;
     	}
    -
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php
    index 0210491fba7..46766277669 100644
    --- a/htdocs/blockedlog/class/blockedlog.class.php
    +++ b/htdocs/blockedlog/class/blockedlog.class.php
    @@ -18,9 +18,6 @@
      * See https://medium.com/@lhartikk/a-blockchain-in-200-lines-of-code-963cc1cc0e54
      */
     
    -
    -
    -
     /*ini_set('unserialize_callback_func', 'mycallback');
     
     function mycallback($classname)
    @@ -42,13 +39,21 @@ class BlockedLog
     	 * @var int
     	 */
     	public $id;
    +
     	/**
     	 * Entity
     	 * @var int
     	 */
     	public $entity;
     
    +	/**
    +	 * @var string Error message
    +	 */
     	public $error = '';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
     	public $errors = array();
     
     	/**
    @@ -171,6 +176,7 @@ class BlockedLog
     
     	/**
     	 *  Try to retrieve source object (it it still exists)
    +     * @return string
     	 */
     	public function getObjectLink()
     	{
    @@ -281,11 +287,11 @@ class BlockedLog
     		}
     
     		return '<i class="opacitymedium">'.$langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object).'</i>';
    -
     	}
     
     	/**
     	 *      try to retrieve user author
    +     * @return string
     	 */
     	public function getUser()
     	{
    @@ -609,7 +615,8 @@ class BlockedLog
     	 *	@param      int		$id       	Id of object to load
     	 *	@return     int         			>0 if OK, <0 if KO, 0 if not found
     	 */
    -	public function fetch($id) {
    +    public function fetch($id)
    +    {
     
     		global $langs;
     
    @@ -672,7 +679,6 @@ class BlockedLog
     			$this->error=$this->db->error();
     			return -1;
     		}
    -
     	}
     
     
    @@ -705,14 +711,13 @@ class BlockedLog
     	 *
     	 *	@return	boolean
     	 */
    -	public function setCertified() {
    +    public function setCertified()
    +    {
     
     		$res = $this->db->query("UPDATE ".MAIN_DB_PREFIX."blockedlog SET certified=1 WHERE rowid=".$this->id);
     		if($res===false) return false;
     
     		return true;
    -
    -
     	}
     
     	/**
    @@ -722,7 +727,8 @@ class BlockedLog
     	 *  @param	int		$forcesignature		Force signature (for example '0000000000' when we disabled the module)
     	 *	@return	int							<0 if KO, >0 if OK
     	 */
    -	public function create($user, $forcesignature='') {
    +    public function create($user, $forcesignature='')
    +    {
     
     		global $conf,$langs,$hookmanager;
     
    @@ -941,17 +947,14 @@ class BlockedLog
     
     	 		$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
     	         WHERE entity=".$conf->entity;
    -
     		}
     		else if ($element=='not_certified') {
     			$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
     	         WHERE entity=".$conf->entity." AND certified = 0";
    -
     		}
     		else if ($element=='just_certified') {
     			$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
     	         WHERE entity=".$conf->entity." AND certified = 1";
    -
     		}
     		else{
     			$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
    @@ -1029,6 +1032,7 @@ class BlockedLog
     	 * Check if module was already used or not for at least one recording.
     	 *
     	 * @param	int		$ignoresystem		Ignore system events for the test
    +     * @return bool
     	 */
     	function alreadyUsed($ignoresystem=0)
     	{
    @@ -1053,6 +1057,4 @@ class BlockedLog
     
     		return $result;
     	}
    -
     }
    -
    diff --git a/htdocs/bookmarks/admin/bookmark.php b/htdocs/bookmarks/admin/bookmark.php
    index 25fa032902f..ed20f619b25 100644
    --- a/htdocs/bookmarks/admin/bookmark.php
    +++ b/htdocs/bookmarks/admin/bookmark.php
    @@ -81,5 +81,6 @@ print '<input size="3" type="text" name="BOOKMARKS_SHOW_IN_MENU" value="'.$conf-
     print '</td></tr>';
     print '</table><br><div class="center"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></div></form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php
    index d450e476506..1d10dc7ca34 100644
    --- a/htdocs/bookmarks/card.php
    +++ b/htdocs/bookmarks/card.php
    @@ -333,10 +333,8 @@ if ($id > 0 && ! preg_match('/^add/i',$action))
     	}
     
     	print '</div>';
    -
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/bookmarks/class/bookmark.class.php b/htdocs/bookmarks/class/bookmark.class.php
    index 1beb4b36871..f66ef8e4d80 100644
    --- a/htdocs/bookmarks/class/bookmark.class.php
    +++ b/htdocs/bookmarks/class/bookmark.class.php
    @@ -28,21 +28,53 @@
      */
     class Bookmark extends CommonObject
     {
    -    public $element='bookmark';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='bookmark';
    +
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element='bookmark';
    -    public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    -    public $picto = 'bookmark';
     
    -    var $db;
    +    /**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +    public $ismultientitymanaged = 1;
     
    -    var $id;
    -    var $fk_user;
    -    var $datec;
    -    var $url;
    -    var $target;	// 0=replace, 1=new window
    -    var $title;
    -    var $position;
    -    var $favicon;
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'bookmark';
    +
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $id;
    +
    +    /**
    +	 * @var int User ID
    +	 */
    +	public $fk_user;
    +
    +    public $datec;
    +
    +    public $url;
    +
    +    public $target;	// 0=replace, 1=new window
    +
    +    public $title;
    +
    +    public $position;
    +
    +    public $favicon;
     
     
         /**
    @@ -127,7 +159,7 @@ class Bookmark extends CommonObject
             $sql.= ", ".$this->db->escape($conf->entity);
             $sql.= ")";
     
    -        dol_syslog("Bookmark::update", LOG_DEBUG);
    +        dol_syslog("Bookmark::create", LOG_DEBUG);
             $resql = $this->db->query($sql);
             if ($resql)
             {
    @@ -211,7 +243,6 @@ class Bookmark extends CommonObject
                 $this->error=$this->db->lasterror();
                 return -1;
             }
    -
         }
     
     	/**
    @@ -241,5 +272,4 @@ class Bookmark extends CommonObject
     	{
     	    return '';
     	}
    -
     }
    diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php
    index ac5a89c66f3..10ce877c7e0 100644
    --- a/htdocs/bookmarks/list.php
    +++ b/htdocs/bookmarks/list.php
    @@ -209,7 +209,7 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/cashdesk/admin/cashdesk.php b/htdocs/cashdesk/admin/cashdesk.php
    index f4af16b3739..62867d855cb 100644
    --- a/htdocs/cashdesk/admin/cashdesk.php
    +++ b/htdocs/cashdesk/admin/cashdesk.php
    @@ -185,5 +185,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     
     print "</form>\n";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/cashdesk/affContenu.php b/htdocs/cashdesk/affContenu.php
    index bd778f3422e..2a3c0279df8 100644
    --- a/htdocs/cashdesk/affContenu.php
    +++ b/htdocs/cashdesk/affContenu.php
    @@ -87,7 +87,7 @@ print '</div>';
     print '<div class="inline-block" style="vertical-align: top">';
     print '<div class="liste_articles">';
     
    -require ('tpl/liste_articles.tpl.php');
    +require 'tpl/liste_articles.tpl.php';
     
     print '</div>';
     print '</div>';
    diff --git a/htdocs/cashdesk/affIndex.php b/htdocs/cashdesk/affIndex.php
    index a2e467a35e3..9ff676531f1 100644
    --- a/htdocs/cashdesk/affIndex.php
    +++ b/htdocs/cashdesk/affIndex.php
    @@ -36,9 +36,8 @@ if ( $_SESSION['uid'] <= 0 )
     	exit;
     }
     
    -$langs->load("companies");
    -$langs->load("compta");
    -$langs->load("cashdesk");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","compta","cashdesk"));
     
     
     /*
    diff --git a/htdocs/cashdesk/class/Auth.class.php b/htdocs/cashdesk/class/Auth.class.php
    index 5e431514d1c..78b76e20d11 100644
    --- a/htdocs/cashdesk/class/Auth.class.php
    +++ b/htdocs/cashdesk/class/Auth.class.php
    @@ -138,6 +138,5 @@ class Auth
     
     		return $ret;
     	}
    -
     }
     
    diff --git a/htdocs/cashdesk/class/Facturation.class.php b/htdocs/cashdesk/class/Facturation.class.php
    index a0e992e9da9..18487619a76 100644
    --- a/htdocs/cashdesk/class/Facturation.class.php
    +++ b/htdocs/cashdesk/class/Facturation.class.php
    @@ -37,7 +37,12 @@ class Facturation
          * int $prix		=> Prix HT du produit en cours
          * int $tva			=> 'rowid' du taux de tva dans llx_c_tva
          */
    -    public $id;
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
         protected $ref;
         protected $qte;
         protected $stock;
    @@ -167,7 +172,6 @@ class Facturation
             $_SESSION['poscart']=$newcartarray;
     
             $this->raz();
    -
         }
     
         /**
    @@ -269,7 +273,6 @@ class Facturation
             $this->prixTotalHt('RESET');
             $this->montantTva('RESET');
             $this->prixTotalTtc('RESET');
    -
         }
     
     
    @@ -287,19 +290,16 @@ class Facturation
             if ( !$aId )
             {
                 return $this->id;
    -
             }
             else if ( $aId == 'RESET' )
             {
     
                 $this->id = null;
    -
             }
             else
             {
     
                 $this->id = $aId;
    -
             }
         }
     
    @@ -310,7 +310,7 @@ class Facturation
          * @return	string			Ref
          */
         public function ref($aRef=null)
    -     {
    +    {
     
             if (is_null($aRef))
             {
    @@ -324,7 +324,6 @@ class Facturation
             {
                 $this->ref = $aRef;
             }
    -
         }
     
         /**
    @@ -348,7 +347,6 @@ class Facturation
             {
                 $this->qte = $aQte;
             }
    -
         }
     
         /**
    @@ -372,7 +370,6 @@ class Facturation
             {
                 $this->stock = $aStock;
             }
    -
         }
     
         /**
    @@ -396,7 +393,6 @@ class Facturation
             {
                 $this->remise_percent = $aRemisePercent;
             }
    -
         }
     
         /**
    @@ -411,17 +407,13 @@ class Facturation
             if (is_null($aMontantRemise)) {
     
                 return $this->montant_remise;
    -
             } else if ( $aMontantRemise == 'RESET' ) {
     
                 $this->montant_remise = null;
    -
             } else {
     
                 $this->montant_remise = $aMontantRemise;
    -
             }
    -
         }
     
         /**
    @@ -436,17 +428,13 @@ class Facturation
             if (is_null($aPrix)) {
     
                 return $this->prix;
    -
             } else if ( $aPrix == 'RESET' ) {
     
                 $this->prix = null;
    -
             } else {
     
                 $this->prix = $aPrix;
    -
             }
    -
         }
     
         /**
    @@ -460,17 +448,13 @@ class Facturation
             if (is_null($aTva)) {
     
                 return $this->tva;
    -
             } else if ( $aTva == 'RESET' ) {
     
                 $this->tva = null;
    -
             } else {
     
                 $this->tva = $aTva;
    -
             }
    -
         }
     
         /**
    @@ -484,15 +468,12 @@ class Facturation
             if (is_null($aNumFacture)) {
     
                 return $this->num_facture;
    -
             } else if ( $aNumFacture == 'RESET' ) {
     
                 $this->num_facture = null;
    -
             } else {
     
                 $this->num_facture = $aNumFacture;
    -
             }
         }
     
    @@ -508,17 +489,13 @@ class Facturation
             if (is_null($aModeReglement)) {
     
                 return $this->mode_reglement;
    -
             } else if ( $aModeReglement == 'RESET' ) {
     
                 $this->mode_reglement = null;
    -
             } else {
     
                 $this->mode_reglement = $aModeReglement;
    -
             }
    -
         }
     
         /**
    @@ -533,17 +510,13 @@ class Facturation
             if (is_null($aMontantEncaisse)) {
     
                 return $this->montant_encaisse;
    -
             } else if ( $aMontantEncaisse == 'RESET' ) {
     
                 $this->montant_encaisse = null;
    -
             } else {
     
                 $this->montant_encaisse = $aMontantEncaisse;
    -
             }
    -
         }
     
         /**
    @@ -561,13 +534,10 @@ class Facturation
             } else if ( $aMontantRendu == 'RESET' ) {
     
                 $this->montant_rendu = null;
    -
             } else {
     
                 $this->montant_rendu = $aMontantRendu;
    -
             }
    -
         }
     
         /**
    @@ -581,15 +551,12 @@ class Facturation
             if (is_null($aPaiementLe)) {
     
                 return $this->paiement_le;
    -
             } else if ( $aPaiementLe == 'RESET' ) {
     
                 $this->paiement_le = null;
    -
             } else {
     
                 $this->paiement_le = $aPaiementLe;
    -
             }
         }
     
    @@ -604,15 +571,12 @@ class Facturation
             if (is_null($aTotalHt)) {
     
                 return $this->prix_total_ht;
    -
             } else if ( $aTotalHt == 'RESET' ) {
     
                 $this->prix_total_ht = null;
    -
             } else {
     
                 $this->prix_total_ht = $aTotalHt;
    -
             }
         }
     
    @@ -627,17 +591,13 @@ class Facturation
             if (is_null($aMontantTva)) {
     
                 return $this->montant_tva;
    -
             } else if ( $aMontantTva == 'RESET' ) {
     
                 $this->montant_tva = null;
    -
             } else {
     
                 $this->montant_tva = $aMontantTva;
    -
             }
    -
         }
     
         /**
    @@ -652,7 +612,7 @@ class Facturation
             {
                 return $this->prix_total_ttc;
             }
    -        else if ( $aTotalTtc == 'RESET' )
    +        elseif ( $aTotalTtc == 'RESET' )
             {
                 $this->prix_total_ttc = null;
             }
    @@ -661,6 +621,4 @@ class Facturation
                 $this->prix_total_ttc = $aTotalTtc;
             }
         }
    -
     }
    -
    diff --git a/htdocs/cashdesk/css/style.css b/htdocs/cashdesk/css/style.css
    index d4149619aae..dc579711aa3 100644
    --- a/htdocs/cashdesk/css/style.css
    +++ b/htdocs/cashdesk/css/style.css
    @@ -52,7 +52,7 @@ p {
     }
     .logopos {
     	padding-top: 20px;
    -	max-height: 40px;	
    +	max-height: 40px;
     }
     
     /* ------------------- Header ------------------- */
    diff --git a/htdocs/cashdesk/facturation.php b/htdocs/cashdesk/facturation.php
    index f52890b68d2..4ca8a562659 100644
    --- a/htdocs/cashdesk/facturation.php
    +++ b/htdocs/cashdesk/facturation.php
    @@ -137,7 +137,6 @@ if ( $nbr_enreg > 1 )
     	{
     		$top_liste_produits = '----- '.$nbr_enreg.' '.$langs->transnoentitiesnoconv("CashDeskProducts").' '.$langs->trans("CashDeskOn").' '.$nbr_enreg.' -----';
     	}
    -
     }
     else if ( $nbr_enreg == 1 )
     {
    @@ -163,4 +162,4 @@ $obj_facturation->paiementLe('RESET');
     
     
     // Affichage des templates
    -require ('tpl/facturation1.tpl.php');
    +require 'tpl/facturation1.tpl.php';
    diff --git a/htdocs/cashdesk/facturation_dhtml.php b/htdocs/cashdesk/facturation_dhtml.php
    index e1a1dcc6bc8..bcfc1e82f82 100644
    --- a/htdocs/cashdesk/facturation_dhtml.php
    +++ b/htdocs/cashdesk/facturation_dhtml.php
    @@ -108,5 +108,4 @@ if (dol_strlen($search) >= 0)	// If search criteria is on char length at least
     			print '</ul>';
     		}
     	}
    -
     }
    diff --git a/htdocs/cashdesk/facturation_verif.php b/htdocs/cashdesk/facturation_verif.php
    index cdeeaf6c424..6aa81d991df 100644
    --- a/htdocs/cashdesk/facturation_verif.php
    +++ b/htdocs/cashdesk/facturation_verif.php
    @@ -216,7 +216,6 @@ switch($action)
     			$obj_facturation->remisePercent($_POST['txtRemise']);
     			$obj_facturation->ajoutArticle();	// This add an entry into $_SESSION['poscart']
     			// We update prixTotalTtc
    -
     		}
     
     		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation';
    @@ -227,7 +226,6 @@ switch($action)
     
     		$redirection = DOL_URL_ROOT.'/cashdesk/affIndex.php?menutpl=facturation';
     		break;
    -
     }
     
     // We saved object obj_facturation
    diff --git a/htdocs/cashdesk/index.php b/htdocs/cashdesk/index.php
    index 24b94562915..d2ea5160ca8 100644
    --- a/htdocs/cashdesk/index.php
    +++ b/htdocs/cashdesk/index.php
    @@ -28,8 +28,8 @@
     require_once '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
     
    -$langs->load("admin");
    -$langs->load("cashdesk");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","cashdesk"));
     
     // Test if user logged
     if ( $_SESSION['uid'] > 0 )
    @@ -63,7 +63,7 @@ top_htmlhead('','',0,0,'',$arrayofcss);
     <?php
     if (! empty($mysoc->logo_small))
     {
    -    print '<img class="logopos" alt="Logo company" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('/thumbs/'.$mysoc->logo_small).'">';
    +    print '<img class="logopos" alt="Logo company" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small).'">';
     }
     else
     {
    diff --git a/htdocs/cashdesk/index_verif.php b/htdocs/cashdesk/index_verif.php
    index 238a73f6ef7..cd354293022 100644
    --- a/htdocs/cashdesk/index_verif.php
    +++ b/htdocs/cashdesk/index_verif.php
    @@ -30,9 +30,8 @@ include '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/cashdesk/include/environnement.php';
     require_once DOL_DOCUMENT_ROOT.'/cashdesk/class/Auth.class.php';
     
    -$langs->load("main");
    -$langs->load("admin");
    -$langs->load("cashdesk");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","admin","cashdesk"));
     
     $username = GETPOST("txtUsername");
     $password = GETPOST("pwdPassword");
    @@ -119,7 +118,7 @@ if ( $retour >= 0 )
     		$_SESSION['firstname'] = $tab['firstname'];
     		$_SESSION['CASHDESK_ID_THIRDPARTY'] = ($thirdpartyid > 0 ? $thirdpartyid : '');
             $_SESSION['CASHDESK_ID_WAREHOUSE'] = ($warehouseid > 0 ? $warehouseid : '');
    -        
    +
             $_SESSION['CASHDESK_ID_BANKACCOUNT_CASH'] = ($bankid_cash > 0 ? $bankid_cash : '');
             $_SESSION['CASHDESK_ID_BANKACCOUNT_CHEQUE'] = ($bankid_cheque > 0 ? $bankid_cheque : '');
             $_SESSION['CASHDESK_ID_BANKACCOUNT_CB'] = ($bankid_cb > 0 ? $bankid_cb : '');
    @@ -135,8 +134,8 @@ if ( $retour >= 0 )
     }
     else
     {
    -	$langs->load("errors");
    -    $langs->load("other");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array("other","errors"));
     	$retour=$langs->trans("ErrorBadLoginPassword");
     	header('Location: '.DOL_URL_ROOT.'/cashdesk/index.php?err='.urlencode($retour).'&user='.$username.'&socid='.$thirdpartyid.'&warehouseid='.$warehouseid);
     	exit;
    diff --git a/htdocs/cashdesk/tpl/facturation1.tpl.php b/htdocs/cashdesk/tpl/facturation1.tpl.php
    index 146ae3d40b6..2ff71e2a359 100644
    --- a/htdocs/cashdesk/tpl/facturation1.tpl.php
    +++ b/htdocs/cashdesk/tpl/facturation1.tpl.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2011		Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2011		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2015		Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -26,10 +27,8 @@ if (empty($langs) || ! is_object($langs))
     	exit;
     }
     
    -
    -$langs->load("main");
    -$langs->load("bills");
    -$langs->load("cashdesk");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","bills","cashdesk"));
     
     // Object $form must de defined
     
    @@ -90,7 +89,6 @@ $langs->load("cashdesk");
     							print '<option '.$selected.' value="'.$tab_designations[$i]['rowid'].'">'.dol_trunc($tab_designations[$i]['ref'],16).' - '.dol_trunc($label,35,'middle');
     							if (! empty($conf->stock->enabled) && !empty($conf_fkentrepot) && $tab_designations[$i]['fk_product_type']==0) print ' ('.$langs->trans("CashDeskStock").': '.(empty($tab_designations[$i]['reel'])?0:$tab_designations[$i]['reel']).')';
     							print '</option>'."\n";
    -
     						}
     					?>
     				</select>
    @@ -204,7 +202,7 @@ $langs->load("cashdesk");
     				<input class="button bouton_mode_reglement" type="submit" name="btnModeReglement" value="<?php echo $langs->trans("Reported"); ?>" onclick="javascript: verifClic('DIF');" />
     			<?php
     			print $langs->trans("DateDue").' :';
    -			print $form->select_date(-1,'txtDatePaiement',0,0,0,'paymentmode',1,0,1);
    +			print $form->selectDate(-1,'txtDatePaiement',0,0,0,'paymentmode',1,0);
     			print '</div>';
     			?>
     		</div>
    diff --git a/htdocs/cashdesk/tpl/liste_articles.tpl.php b/htdocs/cashdesk/tpl/liste_articles.tpl.php
    index 65f48b0603c..53209d735c4 100644
    --- a/htdocs/cashdesk/tpl/liste_articles.tpl.php
    +++ b/htdocs/cashdesk/tpl/liste_articles.tpl.php
    @@ -28,9 +28,8 @@ if (empty($langs) || ! is_object($langs))
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
    -$langs->load("main");
    -$langs->load("bills");
    -$langs->load("cashdesk");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","bills","cashdesk"));
     
     ?>
     
    @@ -61,11 +60,9 @@ else
             if ( $tab[$i]['remise_percent'] > 0 ) {
     
                 $remise_percent = ' -'.$tab[$i]['remise_percent'].'%';
    -
             } else {
     
                 $remise_percent = '';
    -
             }
     
             $remise = $tab[$i]['remise'];
    diff --git a/htdocs/cashdesk/tpl/menu.tpl.php b/htdocs/cashdesk/tpl/menu.tpl.php
    index 250aaa18cc2..afe2c0da4ec 100644
    --- a/htdocs/cashdesk/tpl/menu.tpl.php
    +++ b/htdocs/cashdesk/tpl/menu.tpl.php
    @@ -63,9 +63,8 @@ if (!empty($_SESSION["CASHDESK_ID_WAREHOUSE"]) && ! empty($conf->stock->enabled)
     	$warehouseLink = $warehouse->getNomUrl(1);
     }
     
    -
    -$langs->load("cashdesk");
    -$langs->load("main");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","cashdesk"));
     
     print "\n".'<!-- menu.tpl.php -->'."\n";
     print '<div class="menu_bloc">';
    diff --git a/htdocs/cashdesk/tpl/ticket.tpl.php b/htdocs/cashdesk/tpl/ticket.tpl.php
    index 3937c9dbde3..5ed7650bfad 100644
    --- a/htdocs/cashdesk/tpl/ticket.tpl.php
    +++ b/htdocs/cashdesk/tpl/ticket.tpl.php
    @@ -27,8 +27,8 @@ if (empty($langs) || ! is_object($langs))
     
     include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     
    -$langs->load("main");
    -$langs->load('cashdesk');
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","cashdesk"));
     
     top_httphead('text/html');
     
    @@ -47,7 +47,7 @@ $object->fetch($facid);
     
     <div class="entete">
         <div class="logo">
    -        <?php print '<img src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('/thumbs/'.$mysoc->logo_small).'">'; ?>
    +        <?php print '<img src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small).'">'; ?>
         </div>
         <div class="infos">
             <p class="address"><?php echo $mysoc->name; ?><br>
    diff --git a/htdocs/cashdesk/tpl/validation1.tpl.php b/htdocs/cashdesk/tpl/validation1.tpl.php
    index 2a390b99c65..750831cead8 100644
    --- a/htdocs/cashdesk/tpl/validation1.tpl.php
    +++ b/htdocs/cashdesk/tpl/validation1.tpl.php
    @@ -23,10 +23,8 @@ if (empty($langs) || ! is_object($langs))
     	exit;
     }
     
    -
    -$langs->load("main");
    -$langs->load("bills");
    -$langs->load("banks");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","bills","banks"));
     
     // Object $form must de defined
     
    @@ -43,13 +41,11 @@ $langs->load("banks");
     			if ( $obj_facturation->montantTva() ) {
     
     				echo ('<tr><td class="resume_label">'.$langs->trans("VAT").'</td><td>'.price(price2num($obj_facturation->montantTva(),'MT'),0,$langs,0,0,-1,$conf->currency).'</td></tr>');
    -
     			}
     			else
     			{
     
     				echo ('<tr><td class="resume_label">'.$langs->trans("VAT").'</td><td>'.$langs->trans("NoVAT").'</td></tr>');
    -
     			}
     		?>
     		<tr><td class="resume_label"><?php echo $langs->trans("TotalTTC"); ?> </td><td><?php echo price(price2num($obj_facturation->prixTotalTtc(),'MT'),0,$langs,0,0,-1,$conf->currency); ?></td></tr>
    @@ -93,18 +89,15 @@ $langs->load("banks");
     			if ( $obj_facturation->getsetPaymentMode() == 'DIF' ) {
     
     				echo ('<tr><td class="resume_label">'.$langs->trans("DateDue").'</td><td>'.$obj_facturation->paiementLe().'</td></tr>');
    -
     			} else {
     
     				echo ('<tr><td class="resume_label">'.$langs->trans("Received").'</td><td>'.price(price2num($obj_facturation->montantEncaisse(),'MT'),0,$langs,0,0,-1,$conf->currency).'</td></tr>');
    -
     			}
     
     			// Affichage du montant rendu (reglement en especes)
     			if ( $obj_facturation->montantRendu() ) {
     
     				echo ('<tr><td class="resume_label">'.$langs->trans("Change").'</td><td>'.price(price2num($obj_facturation->montantRendu(),'MT'),0,$langs,0,0,-1,$conf->currency).'</td></tr>');
    -
     			}
     
     		?>
    diff --git a/htdocs/cashdesk/tpl/validation2.tpl.php b/htdocs/cashdesk/tpl/validation2.tpl.php
    index a9889451bda..4592e106c9a 100644
    --- a/htdocs/cashdesk/tpl/validation2.tpl.php
    +++ b/htdocs/cashdesk/tpl/validation2.tpl.php
    @@ -24,9 +24,8 @@ if (empty($langs) || ! is_object($langs))
     	exit;
     }
     
    -
    -$langs->load("main");
    -$langs->load("bills");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","bills"));
     
     ?>
     
    diff --git a/htdocs/cashdesk/validation.php b/htdocs/cashdesk/validation.php
    index 289c864ca32..ff1219861e2 100644
    --- a/htdocs/cashdesk/validation.php
    +++ b/htdocs/cashdesk/validation.php
    @@ -24,5 +24,5 @@
     $form=new Form($db);
     
     // Affichage des templates
    -require ('tpl/validation1.tpl.php');
    +require 'tpl/validation1.tpl.php';
     
    diff --git a/htdocs/cashdesk/validation_ok.php b/htdocs/cashdesk/validation_ok.php
    index 70bf3d1b64f..c8c83a91f18 100644
    --- a/htdocs/cashdesk/validation_ok.php
    +++ b/htdocs/cashdesk/validation_ok.php
    @@ -22,5 +22,5 @@
      */
     
     // Affichage des templates
    -require ('tpl/validation2.tpl.php');
    +require 'tpl/validation2.tpl.php';
     
    diff --git a/htdocs/cashdesk/validation_ticket.php b/htdocs/cashdesk/validation_ticket.php
    index 577df309138..a98b50b0bc9 100644
    --- a/htdocs/cashdesk/validation_ticket.php
    +++ b/htdocs/cashdesk/validation_ticket.php
    @@ -24,7 +24,7 @@
     require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/cashdesk/include/environnement.php';
     require_once DOL_DOCUMENT_ROOT.'/cashdesk/class/Facturation.class.php';
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php');
    +require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
     
     $obj_facturation = unserialize($_SESSION['serObjFacturation']);
     unset($_SESSION['serObjFacturation']);
    @@ -35,7 +35,7 @@ $parameters=array();
     $reshook=$hookmanager->executeHooks('doActions',$parameters,$obj_facturation);
     if (empty($reshook))
     {
    -    require ('tpl/ticket.tpl.php');
    +    require 'tpl/ticket.tpl.php';
     }
     
     
    diff --git a/htdocs/cashdesk/validation_verif.php b/htdocs/cashdesk/validation_verif.php
    index 431f921a1fb..be1f201a8fe 100644
    --- a/htdocs/cashdesk/validation_verif.php
    +++ b/htdocs/cashdesk/validation_verif.php
    @@ -215,6 +215,8 @@ switch ($action)
     		$invoice->note_private=$note;
     		$invoice->cond_reglement_id=$cond_reglement_id;
     		$invoice->mode_reglement_id=$mode_reglement_id;
    +		$invoice->module_source = 'cashdesk';
    +		$invoice->pos_source = '0';
     		//print "c=".$invoice->cond_reglement_id." m=".$invoice->mode_reglement_id; exit;
     
     		// Si paiement differe ...
    @@ -253,7 +255,7 @@ switch ($action)
     			}
     			else
     			{
    -				setEventMessage($invoice->error, $invoice->errors, 'errors');
    +				setEventMessages($invoice->error, $invoice->errors, 'errors');
     			    $error++;
     			}
     
    @@ -326,7 +328,6 @@ switch ($action)
                         		$result=$invoice->set_paid($user);
                       			//print 'set paid';exit;
                         	}
    -
                         }
     				}
     				else
    diff --git a/htdocs/categories/admin/categorie.php b/htdocs/categories/admin/categorie.php
    index 92e23a2199a..03adfdbb41e 100644
    --- a/htdocs/categories/admin/categorie.php
    +++ b/htdocs/categories/admin/categorie.php
    @@ -122,5 +122,6 @@ print '</td></tr>';
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/categories/admin/categorie_extrafields.php b/htdocs/categories/admin/categorie_extrafields.php
    index 3fd7d1c69b5..abea3f41eeb 100644
    --- a/htdocs/categories/admin/categorie_extrafields.php
    +++ b/htdocs/categories/admin/categorie_extrafields.php
    @@ -79,7 +79,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -92,7 +92,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -111,6 +111,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/categories/card.php b/htdocs/categories/card.php
    index db56902347b..44b209e4371 100644
    --- a/htdocs/categories/card.php
    +++ b/htdocs/categories/card.php
    @@ -44,6 +44,7 @@ $origin		= GETPOST('origin','alpha');
     $catorigin	= GETPOST('catorigin','int');
     $type 		= GETPOST('type','alpha');
     $urlfrom	= GETPOST('urlfrom','alpha');
    +$backtopage = GETPOST('backtopage','alpha');
     
     $socid=GETPOST('socid','int');
     $label=GETPOST('label');
    @@ -173,6 +174,11 @@ if (($action == 'add' || $action == 'confirmed') && $user->rights->categorie->cr
     			header("Location: ".$urlfrom);
     			exit;
     		}
    +		elseif ($backtopage)
    +		{
    +			header("Location: ".$backtopage);
    +			exit;
    +		}
     		else if ($idProdOrigin)
     		{
     			header("Location: ".DOL_URL_ROOT.'/categories/viewcat.php?id='.$idProdOrigin.'&type='.$type.'&mesg='.urlencode($langs->trans("CatCreated")));
    @@ -232,8 +238,9 @@ if ($user->rights->categorie->creer)
     		print '<input type="hidden" name="urlfrom" value="'.$urlfrom.'">';
     		print '<input type="hidden" name="action" value="add">';
     		print '<input type="hidden" name="addcat" value="addcat">';
    -		print '<input type="hidden" name="id" value="'.GETPOST('origin').'">';
    +		print '<input type="hidden" name="id" value="'.GETPOST('origin','alpha').'">';
     		print '<input type="hidden" name="type" value="'.$type.'">';
    +		print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
     		if ($origin) print '<input type="hidden" name="origin" value="'.$origin.'">';
     		if ($catorigin)	print '<input type="hidden" name="catorigin" value="'.$catorigin.'">';
     
    @@ -288,7 +295,6 @@ if ($user->rights->categorie->creer)
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php
    index c559d760f0f..843e2fc0ee6 100644
    --- a/htdocs/categories/class/api_categories.class.php
    +++ b/htdocs/categories/class/api_categories.class.php
    @@ -103,7 +103,8 @@ class Categories extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -266,7 +267,8 @@ class Categories extends DolibarrApi
          * @param   Categorie  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
    index 70b2108dd4c..480edb83390 100644
    --- a/htdocs/categories/class/categorie.class.php
    +++ b/htdocs/categories/class/categorie.class.php
    @@ -6,10 +6,11 @@
      * Copyright (C) 2006-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
      * Copyright (C) 2007       Patrick Raguin          <patrick.raguin@gmail.com>
      * Copyright (C) 2013-2016  Juanjo Menent           <jmenent@2byte.es>
    - * Copyright (C) 2013-2016  Philippe Grand          <philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018  Philippe Grand          <philippe.grand@atoo-net.com>
      * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
      * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2016       Charlie Benke           <charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -53,6 +54,9 @@ class Categorie extends CommonObject
     	const TYPE_ACCOUNT   = 'bank_account';
         const TYPE_BANK_LINE = 'bank_line';
     
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'category';
     
     
    @@ -72,6 +76,10 @@ class Categorie extends CommonObject
     		'user'         => 7,
     		'bank_line'    => 8,
     	);
    +
    +    /**
    +	 * @var array Code mapping from ID
    +	 */
     	public static $MAP_ID_TO_CODE = array(
     		0 => 'product',
     		1 => 'supplier',
    @@ -100,7 +108,8 @@ class Categorie extends CommonObject
             'bank_account' => 'account',
             'project'  => 'project',
     	);
    -	/**
    +
    +    /**
     	 * @var array Category tables mapping from type string
     	 *
     	 * @note Move to const array when PHP 5.6 will be our minimum target
    @@ -116,7 +125,8 @@ class Categorie extends CommonObject
             'bank_account'=> 'account',
             'project'  => 'project',
     	);
    -	/**
    +
    +    /**
     	 * @var array Object class mapping from type string
     	 *
     	 * @note Move to const array when PHP 5.6 will be our minimum target
    @@ -132,7 +142,8 @@ class Categorie extends CommonObject
     		'bank_account'  => 'Account',
             'project'  => 'Project',
     	);
    -	/**
    +
    +    /**
     	 * @var array Object table mapping from type string
     	 *
     	 * @note Move to const array when PHP 5.6 will be our minimum target
    @@ -148,12 +159,31 @@ class Categorie extends CommonObject
             'project'  => 'projet',
     	);
     
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='category';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='categorie';
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_parent;
    -	public $label;
    +
    +	/**
    +     * @var string Category label
    +     */
    +   	public $label;
    +
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
    +
     	/**
     	 * @var string     Color
     	 */
    @@ -176,7 +206,14 @@ class Categorie extends CommonObject
     	 */
     	public $type;
     
    -	public $cats = array();			// Categories table in memory
    +	/**
    +	 * @var array Categories table in memory
    +	 */
    +	public $cats = array();
    +
    +    /**
    +	 * @var array Mother of table
    +	 */
     	public $motherof = array();
     
     	/**
    @@ -498,112 +535,27 @@ class Categorie extends CommonObject
     				$error++;
     			}
     		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_societe";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_fournisseur";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_product";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_contact";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
    -			$sql .= " WHERE fk_categorie = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
    -				$error++;
    -			}
    -		}
    -		if (! $error)
    -		{
    -		    $sql  = "DELETE FROM ".MAIN_DB_PREFIX."bank_class";
    -		    $sql .= " WHERE fk_categ = ".$this->id;
    -		    if (!$this->db->query($sql))
    -		    {
    -		        $this->error=$this->db->lasterror();
    -		        dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
    -		        $error++;
    -		    }
    -		}
     
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie_lang";
    -			$sql .= " WHERE fk_category = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
    -				$error++;
    -			}
    -		}
    -
    -		// Delete category
    -		if (! $error)
    -		{
    -			$sql  = "DELETE FROM ".MAIN_DB_PREFIX."categorie";
    -			$sql .= " WHERE rowid = ".$this->id;
    -			if (!$this->db->query($sql))
    -			{
    -				$this->error=$this->db->lasterror();
    -				$error++;
    -			}
    -		}
    +        $arraydelete = array(
    +            'categorie_societe' => 'fk_categorie',
    +            'categorie_fournisseur' => 'fk_categorie',
    +            'categorie_product' => 'fk_categorie',
    +            'categorie_member' => 'fk_categorie',
    +            'categorie_contact' => 'fk_categorie',
    +            'categorie_account' => 'fk_categorie',
    +            'bank_class' => 'fk_categ',
    +            'categorie_lang' => 'fk_category',
    +            'categorie' => 'rowid',
    +        );
    +        foreach ($arraydelete as $key => $value) {
    +            $sql  = "DELETE FROM " . MAIN_DB_PREFIX . $key;
    +            $sql .= " WHERE ".$value." = ".$this->id;
    +            if (!$this->db->query($sql)) {
    +                $this->errors[] = $this->db->lasterror();
    +                dol_syslog("Error sql=".$sql." ".$this->error, LOG_ERR);
    +                $error++;
    +            }
    +        }
     
     		// Removed extrafields
     		if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
    @@ -628,6 +580,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Link an object to the category
     	 *
    @@ -637,6 +590,7 @@ class Categorie extends CommonObject
     	 */
     	function add_type($obj, $type)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf;
     
     		$error=0;
    @@ -711,7 +665,6 @@ class Categorie extends CommonObject
     			    $this->db->rollback();
     			    return -2;
     			}
    -
     		}
     		else
     		{
    @@ -729,6 +682,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Delete object from category
     	 *
    @@ -739,6 +693,7 @@ class Categorie extends CommonObject
     	 */
     	function del_type($obj,$type)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf;
     
     		$error=0;
    @@ -791,7 +746,7 @@ class Categorie extends CommonObject
     	 *
     	 * @param   string     $type       Type of category ('customer', 'supplier', 'contact', 'product', 'member')
     	 * @param   int        $onlyids    Return only ids of objects (consume less memory)
    -	 * @return  mixed                  -1 if KO, array of instance of object if OK
    +	 * @return  array|int              -1 if KO, array of instance of object if OK
     	 * @see containsObject
     	 */
     	function getObjectsInCateg($type, $onlyids=0)
    @@ -864,7 +819,7 @@ class Categorie extends CommonObject
     	 * @param	string	$sortorder	Sort order
     	 * @param	int		$limit		Limit for list
     	 * @param	int		$page		Page number
    -	 * @return	array				Array of categories
    +	 * @return	array|int			Array of categories, 0 if no cat, -1 on error
     	 */
     	function getListForItem($id, $type='customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
     	{
    @@ -952,6 +907,7 @@ class Categorie extends CommonObject
     		return $categories;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return childs of a category
     	 *
    @@ -959,6 +915,7 @@ class Categorie extends CommonObject
     	 */
     	function get_filles()
     	{
    +        // phpcs:enable
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
     		$sql.= " WHERE fk_parent = ".$this->id;
     
    @@ -981,6 +938,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 * 	Load this->motherof that is array(id_son=>id_parent, ...)
     	 *
    @@ -988,6 +946,7 @@ class Categorie extends CommonObject
     	 */
     	private function load_motherof()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$this->motherof=array();
    @@ -1015,6 +974,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Rebuilding the category tree as an array
     	 * Return an array of table('id','id_mere',...) trie selon arbre et avec:
    @@ -1028,10 +988,11 @@ class Categorie extends CommonObject
     	 * @param   string 	$type        	Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...).
     	 * @param   int    	$markafterid 	Removed all categories including the leaf $markafterid in category tree.
     	 *
    -	 * @return  array               	Array of categories. this->cats and this->motherof are set.
    +	 * @return  array|int               Array of categories. this->cats and this->motherof are set, -1 on error
     	 */
     	function get_full_arbo($type, $markafterid=0)
     	{
    +        // phpcs:enable
     	    global $conf, $langs;
     
     		if (! is_numeric($type)) $type = $this->MAP_ID[$type];
    @@ -1106,6 +1067,7 @@ class Categorie extends CommonObject
     		return $this->cats;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	For category id_categ and its childs available in this->cats, define property fullpath and fulllabel
     	 *
    @@ -1115,6 +1077,7 @@ class Categorie extends CommonObject
     	 */
     	function build_path_from_id_categ($id_categ,$protection=1000)
     	{
    +        // phpcs:enable
     		dol_syslog(get_class($this)."::build_path_from_id_categ id_categ=".$id_categ." protection=".$protection, LOG_DEBUG);
     
     		if (! empty($this->cats[$id_categ]['fullpath']))
    @@ -1148,6 +1111,7 @@ class Categorie extends CommonObject
     		return;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Display content of $this->cats
     	 *
    @@ -1155,6 +1119,7 @@ class Categorie extends CommonObject
     	 */
     	function debug_cats()
     	{
    +        // phpcs:enable
     		// Display $this->cats
     		foreach($this->cats as $key => $val)
     		{
    @@ -1169,15 +1134,17 @@ class Categorie extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Returns all categories
     	 *
     	 *	@param	int			$type		Type of category (0, 1, ...)
     	 *	@param	boolean		$parent		Just parent categories if true
    -	 *	@return	array					Table of Object Category
    +	 *	@return	array|int				Table of Object Category, -1 on error
     	 */
     	function get_all_categories($type=null, $parent=false)
     	{
    +        // phpcs:enable
     		if (! is_numeric($type)) $type = $this->MAP_ID[$type];
     
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie";
    @@ -1206,6 +1173,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Check if no category with same label already exists for this cat's parent or root and for this cat's type
     	 *
    @@ -1213,6 +1181,7 @@ class Categorie extends CommonObject
     	 */
     	function already_exists()
     	{
    +        // phpcs:enable
     		$type=$this->type;
     
     		if (! is_numeric($type)) $type=$this->MAP_ID[$type];
    @@ -1255,6 +1224,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Returns the top level categories (which are not girls)
     	 *
    @@ -1263,9 +1233,11 @@ class Categorie extends CommonObject
     	 */
     	function get_main_categories($type=null)
     	{
    +        // phpcs:enable
     		return $this->get_all_categories($type, true);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns the path of the category, with the names of the categories
     	 * separated by $sep (" >> " by default)
    @@ -1277,6 +1249,7 @@ class Categorie extends CommonObject
     	 */
     	function print_all_ways($sep = " &gt;&gt; ", $url='', $nocolor=0)
     	{
    +        // phpcs:enable
     		$ways = array();
     
     		$allways = $this->get_all_ways(); // Load array of categories
    @@ -1323,6 +1296,7 @@ class Categorie extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Returns an array containing the list of parent categories
     	 *
    @@ -1330,6 +1304,7 @@ class Categorie extends CommonObject
     	 */
     	function get_meres()
     	{
    +        // phpcs:enable
     		$parents = array();
     
     		$sql = "SELECT fk_parent FROM ".MAIN_DB_PREFIX."categorie";
    @@ -1357,6 +1332,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Returns in a table all possible paths to get to the category
     	 * 	starting with the major categories represented by Tables of categories
    @@ -1365,6 +1341,7 @@ class Categorie extends CommonObject
     	 */
     	function get_all_ways()
     	{
    +        // phpcs:enable
     		$ways = array();
     
     		$parents=$this->get_meres();
    @@ -1396,7 +1373,7 @@ class Categorie extends CommonObject
     	 * @param   string|int	$type   Type of category ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...)
     	 * @param   string 		$mode   'id'=Get array of category ids, 'object'=Get array of fetched category instances, 'label'=Get array of category
     	 *                      	    labels, 'id'= Get array of category IDs
    -	 * @return  mixed           	Array of category objects or < 0 if KO
    +	 * @return  array|int           Array of category objects or < 0 if KO
     	 */
     	function containing($id, $type, $mode='object')
     	{
    @@ -1478,7 +1455,7 @@ class Categorie extends CommonObject
      	 * 	@param		string		$type		Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated.
     	 * 	@param		boolean		$exact		Exact string search (true/false)
     	 * 	@param		boolean		$case		Case sensitive (true/false)
    -	 * 	@return		array					Array of category id
    +	 * 	@return		array|int				Array of category id, -1 if error
     	 */
     	function rechercher($id, $nom, $type, $exact = false, $case = false)
     	{
    @@ -1571,6 +1548,7 @@ class Categorie extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Deplace fichier uploade sous le nom $files dans le repertoire sdir
     	 *
    @@ -1580,6 +1558,7 @@ class Categorie extends CommonObject
     	 */
     	function add_photo($sdir, $file)
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
     		$dir = $sdir .'/'. get_exdir($this->id,2,0,0,$this,'category') . $this->id ."/";
    @@ -1620,6 +1599,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return tableau de toutes les photos de la categorie
     	 *
    @@ -1629,6 +1609,7 @@ class Categorie extends CommonObject
     	 */
     	function liste_photos($dir,$nbmax=0)
     	{
    +        // phpcs:enable
     		include_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php';
     
     		$nbphoto=0;
    @@ -1675,6 +1656,7 @@ class Categorie extends CommonObject
     		return $tabobj;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Efface la photo de la categorie et sa vignette
     	 *
    @@ -1683,6 +1665,7 @@ class Categorie extends CommonObject
     	 */
     	function delete_photo($file)
     	{
    +        // phpcs:enable
             require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
     	    $dir = dirname($file).'/'; // Chemin du dossier contenant l'image d'origine
    @@ -1703,6 +1686,7 @@ class Categorie extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load size of image file
     	 *
    @@ -1711,6 +1695,7 @@ class Categorie extends CommonObject
     	 */
     	function get_image_size($file)
     	{
    +        // phpcs:enable
     		$infoImg = getimagesize($file); // Recuperation des infos de l'image
     		$this->imgWidth = $infoImg[0]; // Largeur de l'image
     		$this->imgHeight = $infoImg[1]; // Hauteur de l'image
    @@ -1824,7 +1809,6 @@ class Categorie extends CommonObject
     	            {
     	                $this->label		= $obj->label;
     	                $this->description	= $obj->description;
    -
     	            }
     	            $this->multilangs["$obj->lang"]["label"]		= $obj->label;
     	            $this->multilangs["$obj->lang"]["description"]	= $obj->description;
    diff --git a/htdocs/categories/edit.php b/htdocs/categories/edit.php
    index b420847f6fd..cdfac54fb9d 100644
    --- a/htdocs/categories/edit.php
    +++ b/htdocs/categories/edit.php
    @@ -192,7 +192,6 @@ print '<div class="center"><input type="submit" class="button" name"submit" valu
     
     print '</form>';
     
    -
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php
    index 9f41c0b016a..316a21892af 100644
    --- a/htdocs/categories/index.php
    +++ b/htdocs/categories/index.php
    @@ -82,6 +82,8 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
     print '<form method="post" action="index.php?type='.$type.'">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     print '<input type="hidden" name="type" value="'.$type.'">';
    +
    +
     print '<table class="noborder nohover" width="100%">';
     print '<tr class="liste_titre">';
     print '<td colspan="3">'.$langs->trans("Search").'</td>';
    @@ -173,6 +175,8 @@ foreach($fulltree as $key => $val)
     }
     
     
    +//print_barre_liste('', 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, 0, '', 0, $newcardbutton, '', 0, 1, 1);
    +
     print '<table class="liste nohover" width="100%">';
     print '<tr class="liste_titre"><td>'.$langs->trans("Categories").'</td><td></td><td align="right">';
     if (! empty($conf->use_javascript_ajax))
    @@ -205,6 +209,6 @@ print "</table>";
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/categories/photos.php b/htdocs/categories/photos.php
    index 472a8eb9b95..095c0c611c5 100644
    --- a/htdocs/categories/photos.php
    +++ b/htdocs/categories/photos.php
    @@ -273,6 +273,6 @@ else
         print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/categories/traduction.php b/htdocs/categories/traduction.php
    index 7d71b43a81b..d3287703695 100644
    --- a/htdocs/categories/traduction.php
    +++ b/htdocs/categories/traduction.php
    @@ -269,7 +269,6 @@ if ($action == 'edit')
     	print '</div>';
     
     	print '</form>';
    -
     }
     else if ($action != 'add')
     {
    @@ -334,5 +333,6 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service
     	print '<br>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php
    index 24e70e7d587..560cb4613be 100644
    --- a/htdocs/categories/viewcat.php
    +++ b/htdocs/categories/viewcat.php
    @@ -168,7 +168,6 @@ if ($type == Categorie::TYPE_PRODUCT && $elemid && $action == 'addintocategory'
     			setEventMessages($object->error,$object->errors,'errors');
     		}
     	}
    -
     }
     
     
    @@ -697,6 +696,6 @@ if ($type == Categorie::TYPE_PROJECT)
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/collab/index.php b/htdocs/collab/index.php
    index 2c056cd0e07..e7b2ab51d7c 100644
    --- a/htdocs/collab/index.php
    +++ b/htdocs/collab/index.php
    @@ -28,9 +28,8 @@ require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    -$langs->load("admin");
    -$langs->load("other");
    -$langs->load("website");
    +// Load translation files required by the page
    +$langs->loadLangs(array("admin","other","website"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -456,9 +455,6 @@ if ($action == 'editcontent')
     
     print "</div>\n</form>\n";
     
    -
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php
    index 470a90c355f..4e8b87eb591 100644
    --- a/htdocs/comm/action/card.php
    +++ b/htdocs/comm/action/card.php
    @@ -6,7 +6,8 @@
      * Copyright (C) 2010-2013 Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2013      Florian Henry        <florian.henry@open-concept.pro>
      * Copyright (C) 2014      Cedric GROSS         <c.gross@kreiz-it.fr>
    - * Copyright (C) 2015	   Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2015       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -39,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
    @@ -250,6 +252,19 @@ if ($action == 'add')
     			}
     		}
     		$object->fk_project = isset($_POST["projectid"])?$_POST["projectid"]:0;
    +		
    +		$taskid = GETPOST('taskid','int');
    +		if(!empty($taskid)){
    +		    
    +		    $taskProject = new Task($db);
    +		    if($taskProject->fetch($taskid)>0){
    +		        $object->fk_project = $taskProject->fk_project;
    +		    }
    +		    
    +		    $object->fk_element = $taskid;
    +		    $object->elementtype = 'task';
    +		}
    +		
     		$object->datep = $datep;
     		$object->datef = $datef;
     		$object->percentage = $percentage;
    @@ -582,7 +597,6 @@ if (GETPOST('actionmove','alpha') == 'mupdate')
         {
             $action='';
         }
    -
     }
     
     // Actions to delete doc
    @@ -689,9 +703,13 @@ if ($action == 'create')
     	$datep=($datep?$datep:$object->datep);
     	if (GETPOST('datep','int',1)) $datep=dol_stringtotime(GETPOST('datep','int',1),0);
     	print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("DateActionStart").'</span></td><td>';
    -	if (GETPOST("afaire") == 1) $form->select_date($datep,'ap',1,1,0,"action",1,1,0,0,'fulldayend');
    -	else if (GETPOST("afaire") == 2) $form->select_date($datep,'ap',1,1,1,"action",1,1,0,0,'fulldayend');
    -	else $form->select_date($datep,'ap',1,1,1,"action",1,1,0,0,'fulldaystart');
    +	if (GETPOST("afaire") == 1) {
    +        print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldayend');
    +    } elseif (GETPOST("afaire") == 2) {
    +        print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +    } else {
    +        print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart');
    +    }
     	print '</td></tr>';
     
     	// Date end
    @@ -702,12 +720,17 @@ if ($action == 'create')
     		$datef=dol_time_plus_duree($datep, $conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS, 'h');
     	}
     	print '<tr><td><span id="dateend"'.(GETPOST("actioncode") == 'AC_RDV'?' class="fieldrequired"':'').'>'.$langs->trans("DateActionEnd").'</span></td><td>';
    -	if (GETPOST("afaire") == 1) $form->select_date($datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend');
    -	else if (GETPOST("afaire") == 2) $form->select_date($datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend');
    -	else $form->select_date($datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend');
    +	if (GETPOST("afaire") == 1) {
    +        print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +    } elseif (GETPOST("afaire") == 2) {
    +        print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +    } else {
    +        print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +    }
     	print '</td></tr>';
     
    -	$userepeatevent=($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);	// Dev in progress
    +    // Dev in progress
    +	$userepeatevent=($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);
     	if ($userepeatevent)
     	{
     		// Repeat
    @@ -849,7 +872,6 @@ if ($action == 'create')
     			} else {
     				print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, $events, 0, 'minwidth300');
     			}
    -
     		}
     		print '</td></tr>';
     
    @@ -866,11 +888,38 @@ if ($action == 'create')
     	{
     		// Projet associe
     		$langs->load("projects");
    +		
    +		$projectid = GETPOST('projectid', 'int');
     
    -		print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td>';
    +		print '<tr><td class="titlefieldcreate">'.$langs->trans("Project").'</td><td id="project-input-container" >';
     
    -		$numproject=$formproject->select_projects((! empty($societe->id)?$societe->id:-1), GETPOST("projectid")?GETPOST("projectid"):'', 'projectid', 0, 0, 1, 1);
    +		$numproject=$formproject->select_projects((! empty($societe->id)?$societe->id:-1), $projectid, 'projectid', 0, 0, 1, 1);
    +		
     		print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$societe->id.'&action=create">'.$langs->trans("AddProject").'</a>';
    +		$urloption='?action=create';
    +		$url = dol_buildpath('comm/action/card.php',2).$urloption;
    +		
    +		// update task list
    +		print "\n".'<script type="text/javascript">';
    +		print '$(document).ready(function () {
    +	               $("#projectid").change(function () {
    +                        var url = "'.$url.'&projectid="+$("#projectid").val();
    +                        $.get(url, function(data) {
    +                            console.log($( data ).find("#taskid").html());
    +                            if (data) $("#taskid").html( $( data ).find("#taskid").html() ).select2();
    +                        })
    +                  });
    +               })';
    +		print '</script>'."\n";
    +		
    +		print '</td></tr>';
    +		
    +		print '<tr><td class="titlefieldcreate">'.$langs->trans("Task").'</td><td id="project-task-input-container" >';
    +		
    +		$projectsListId=false;
    +		if(!empty($projectid)){ $projectsListId=$projectid; }
    +		$tid=GETPOST("projecttaskid")?GETPOST("projecttaskid"):'';
    +		$formproject->selectTasks((! empty($societe->id)?$societe->id:-1), $tid, 'taskid', 24, 0, '1', 1, 0, 0, 'maxwidth500',$projectsListId);
     		print '</td></tr>';
     	}
     	if (!empty($origin) && !empty($originid))
    @@ -1057,30 +1106,38 @@ if ($id > 0)
     
     		// Date start
     		print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("DateActionStart").'</span></td><td colspan="3">';
    -		if (GETPOST("afaire") == 1) $form->select_date($datep?$datep:$object->datep,'ap',1,1,0,"action",1,1,0,0,'fulldaystart');
    -		else if (GETPOST("afaire") == 2) $form->select_date($datep?$datep:$object->datep,'ap',1,1,1,"action",1,1,0,0,'fulldaystart');
    -		else $form->select_date($datep?$datep:$object->datep,'ap',1,1,1,"action",1,1,0,0,'fulldaystart');
    +		if (GETPOST("afaire") == 1) {
    +            print $form->selectDate($datep?$datep:$object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart');
    +        } elseif (GETPOST("afaire") == 2) {
    +            print $form->selectDate($datep?$datep:$object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart');
    +        } else {
    +            print $form->selectDate($datep?$datep:$object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart');
    +        }
     		print '</td></tr>';
     		// Date end
     		print '<tr><td>'.$langs->trans("DateActionEnd").'</td><td colspan="3">';
    -		if (GETPOST("afaire") == 1) $form->select_date($datef?$datef:$object->datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend');
    -		else if (GETPOST("afaire") == 2) $form->select_date($datef?$datef:$object->datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend');
    -		//else $form->select_date($datef?$datef:$object->datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend','ap');
    -		else $form->select_date($datef?$datef:$object->datef,'p2',1,1,1,"action",1,1,0,0,'fulldayend');
    +		if (GETPOST("afaire") == 1) {
    +            print $form->selectDate($datef?$datef:$object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +        } elseif (GETPOST("afaire") == 2) {
    +            print $form->selectDate($datef?$datef:$object->datef,'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +        } else {
    +            print $form->selectDate($datef?$datef:$object->datef,'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend');
    +        }
     		print '</td></tr>';
     
    -		$userepeatevent=($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);	// Dev in progress
    +        // Dev in progress
    +		$userepeatevent=($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0);
     		if ($userepeatevent)
     		{
     			// Repeat
     			print '<tr><td>'.$langs->trans("RepeatEvent").'</td><td colspan="3">';
     			print '<input type="hidden" name="recurid" value="'.$object->recurid.'">';
    -			$arrayrecurrulefreq=array(
    -					'no'=>$langs->trans("No"),
    -					'MONTHLY'=>$langs->trans("EveryMonth"),
    -					'WEEKLY'=>$langs->trans("EveryWeek"),
    -					//'DAYLY'=>$langs->trans("EveryDay")
    -					);
    +			$arrayrecurrulefreq = array(
    +				'no'=>$langs->trans("No"),
    +				'MONTHLY'=>$langs->trans("EveryMonth"),
    +				'WEEKLY'=>$langs->trans("EveryWeek"),
    +				//'DAYLY'=>$langs->trans("EveryDay"),
    +			);
     			$selectedrecurrulefreq='no';
     			$selectedrecurrulebymonthday='';
     			$selectedrecurrulebyday='';
    @@ -1252,10 +1309,41 @@ if ($id > 0)
     			include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
                 print '<tr>';
     			print '<td>'.$langs->trans("LinkedObject").'</td>';
    -			print '<td>'.dolGetElementUrl($object->fk_element,$object->elementtype,1);
    -			print '<input type="hidden" name="fk_element" value="'.$object->fk_element.'">';
    -			print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
    -			print '</td>';
    +			
    +			if ($object->elementtype == 'task' && ! empty($conf->projet->enabled))
    +			{
    +			    print '<td id="project-task-input-container" >';
    +			    
    +			    $urloption='?action=create'; // we use create not edit for more flexibility
    +			    $url = DOL_URL_ROOT.'/comm/action/card.php'.$urloption;
    +			    
    +			    // update task list
    +			    print "\n".'<script type="text/javascript" >';
    +			    print '$(document).ready(function () {
    +	               $("#projectid").change(function () {
    +                        var url = "'.$url.'&projectid="+$("#projectid").val();
    +                        $.get(url, function(data) {
    +                            console.log($( data ).find("#fk_element").html());
    +                            if (data) $("#fk_element").html( $( data ).find("#taskid").html() ).select2();
    +                        })
    +                  });
    +               })';
    +			    print '</script>'."\n";
    +			    
    +			    $formproject->selectTasks((! empty($societe->id)?$societe->id:-1), $object->fk_element, 'fk_element', 24, 0, 0, 1, 0, 0, 'maxwidth500',$object->fk_project);
    +			    print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
    +			    
    +			    print '</td>';
    +			}
    +			else
    +			{
    +			    print '<td>';
    +			    print dolGetElementUrl($object->fk_element,$object->elementtype,1);
    +			    print '<input type="hidden" name="fk_element" value="'.$object->fk_element.'">';
    +			    print '<input type="hidden" name="elementtype" value="'.$object->elementtype.'">';
    +			    print '</td>';
    +			}
    +			
     			print '</tr>';
     		}
     
    @@ -1625,7 +1713,6 @@ if ($id > 0)
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
    index be8ad550b39..92af9fef6da 100644
    --- a/htdocs/comm/action/class/actioncomm.class.php
    +++ b/htdocs/comm/action/class/actioncomm.class.php
    @@ -1,9 +1,11 @@
     <?php
    -/* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2011-2017 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2015	   Marcos García		<marcosgdf@gmail.com>
    +/* Copyright (C) 2002-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2011  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2011-2017  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2015	    Marcos García		    <marcosgdf@gmail.com>
    + * Copyright (C) 2018	    Nicolas ZABOURI	        <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -33,15 +35,29 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class ActionComm extends CommonObject
     {
    +    /**
    +     * @var string ID to identify managed object
    +     */
         public $element='action';
    +
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element = 'actioncomm';
    +
         public $table_rowid = 'id';
    -    public $picto='action';
    +
    +    /**
    +     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +     */
    +    public $picto = 'action';
    +
         /**
          * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
          * @var int
          */
         public $ismultientitymanaged = 1;
    +
         /**
          * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user, 2=Same than 1 but accept record if fksoc is empty
          * @var integer
    @@ -52,7 +68,7 @@ class ActionComm extends CommonObject
          * Id of the event
          * @var int
          */
    -    var $id;
    +    public $id;
     
         /**
          * Id of the event. Use $id as possible
    @@ -60,23 +76,20 @@ class ActionComm extends CommonObject
          */
         public $ref;
     
    -    var $type_id;		// Id into parent table llx_c_actioncomm (used only if option to use type is set)
    -    var $type_code;		// Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH.
    -    var $type;			// Label into parent table llx_c_actioncomm (used only if option to use type is set)
    -    var $type_color;	// Color into parent table llx_c_actioncomm (used only if option to use type is set)
    -    var $code;			// Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...)
    -
    -    var $label;
    +    public $type_id;		// Id into parent table llx_c_actioncomm (used only if option to use type is set)
    +    public $type_code;		// Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH.
    +    public $type_label;
    +    public $type;			// Label into parent table llx_c_actioncomm (used only if option to use type is set)
    +    public $type_color;	// Color into parent table llx_c_actioncomm (used only if option to use type is set)
    +    public $code;			// Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...)
     
         /**
    -     * @var string
    -     * @deprecated Use $label
    -     * @see label
    +     * @var string Agenda event label
          */
    -    public $libelle;
    +    public $label;
     
    -    var $datec;			// Date creation record (datec)
    -    var $datem;			// Date modification record (tms)
    +    public $datec;			// Date creation record (datec)
    +    public $datem;			// Date modification record (tms)
     
         /**
          * Object user that create action
    @@ -84,7 +97,7 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see authorid
          */
    -    var $author;
    +    public $author;
     
         /**
          * Object user that modified action
    @@ -92,39 +105,49 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see usermodid
          */
    -    var $usermod;
    -    var $authorid;		// Id user that create action
    -    var $usermodid;		// Id user that modified action
    +    public $usermod;
     
    -    var $datep;			// Date action start (datep)
    -    var $datef;			// Date action end (datep2)
    +    /**
    +     * Id user that create action
    +     * @var int
    +     */
    +    public $authorid;
    +
    +    /**
    +     * Id user that modified action
    +     * @var int
    +     */
    +    public $usermodid;
    +
    +    public $datep;			// Date action start (datep)
    +    public $datef;			// Date action end (datep2)
     
         /**
          * @var int -1=Unkown duration
          * @deprecated
          */
    -    var $durationp = -1;
    -    var $fulldayevent = 0;    // 1=Event on full day
    +    public $durationp = -1;
    +    public $fulldayevent = 0;    // 1=Event on full day
     
         /**
          * Milestone
          * @var int
          * @deprecated Milestone is already event with end date = start date
          */
    -    var $punctual = 1;
    -    var $percentage;    // Percentage
    -    var $location;      // Location
    +    public $punctual = 1;
    +    public $percentage;    // Percentage
    +    public $location;      // Location
     
    -	var $transparency;	// Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events)
    -    var $priority;      // Small int (0 By default)
    +	public $transparency;	// Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events)
    +    public $priority;      // Small int (0 By default)
     
    -	var $userassigned = array();	// Array of user ids
    -    var $userownerid;	// Id of user owner = fk_user_action into table
    -    var $userdoneid;	// Id of user done (deprecated)
    +	public $userassigned = array();	// Array of user ids
    +    public $userownerid;	// Id of user owner = fk_user_action into table
    +    public $userdoneid;	// Id of user done (deprecated)
     
    -    var $socpeopleassigned = array(); // Array of contact ids
    +    public $socpeopleassigned = array(); // Array of contact ids
     
    -    var $otherassigned = array(); // Array of other contact emails (not user, not contact)
    +    public $otherassigned = array(); // Array of other contact emails (not user, not contact)
     
     
     	/**
    @@ -133,7 +156,7 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see userownerid
          */
    -    var $usertodo;
    +    public $usertodo;
     
         /**
          * Object user that did action
    @@ -141,10 +164,10 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see userdoneid
          */
    -    var $userdone;
    +    public $userdone;
     
    -    var $socid;
    -    var $contactid;
    +    public $socid;
    +    public $contactid;
     
         /**
          * Company linked to action (optional)
    @@ -152,7 +175,7 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see socid
          */
    -    var $societe;
    +    public $societe;
     
         /**
          * Contact linked to action (optional)
    @@ -160,28 +183,28 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see contactid
          */
    -    var $contact;
    +    public $contact;
     
         // Properties for links to other objects
    -    var $fk_element;    // Id of record
    -    var $elementid;    // Id of record alternative for API
    -    var $elementtype;   // Type of record. This if property ->element of object linked to.
    +    public $fk_element;    // Id of record
    +    public $elementid;    // Id of record alternative for API
    +    public $elementtype;   // Type of record. This if property ->element of object linked to.
     
         // Ical
    -    var $icalname;
    -    var $icalcolor;
    +    public $icalname;
    +    public $icalcolor;
     
    -    var $actions=array();
    +    public $actions=array();
     
         // Fields for emails
    -    var $email_msgid;
    -    var $email_from;
    -    var $email_sender;
    -    var $email_to;
    -    var $email_tocc;
    -    var $email_tobcc;
    -    var $email_subject;
    -    var $errors_to;
    +    public $email_msgid;
    +    public $email_from;
    +    public $email_sender;
    +    public $email_to;
    +    public $email_tocc;
    +    public $email_tobcc;
    +    public $email_subject;
    +    public $errors_to;
     
     
         /**
    @@ -321,7 +344,7 @@ class ActionComm extends CommonObject
             $sql.= ($code?("'".$code."'"):"null").", ";
             $sql.= ((isset($this->socid) && $this->socid > 0) ? $this->socid:"null").", ";
             $sql.= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project:"null").", ";
    -        $sql.= " '".$this->db->escape($this->note)."', ";
    +        $sql.= " '".$this->db->escape($this->note_private?$this->note_private:$this->note)."', ";
             $sql.= ((isset($this->contactid) && $this->contactid > 0) ? $this->contactid:"null").", ";
             $sql.= (isset($user->id) && $user->id > 0 ? $user->id:"null").", ";
             $sql.= ($userownerid>0 ? $userownerid:"null").", ";
    @@ -378,7 +401,6 @@ class ActionComm extends CommonObject
     							$error++;
     							$this->errors[]=$this->db->lasterror();
     						}
    -
     					}
     				}
     			}
    @@ -423,7 +445,6 @@ class ActionComm extends CommonObject
                 $this->error=$this->db->lasterror();
                 return -1;
             }
    -
         }
     
     	/**
    @@ -592,6 +613,7 @@ class ActionComm extends CommonObject
                     $this->datem   				= $this->db->jdate($obj->datem);
     
                     $this->note					= $obj->note;
    +                $this->note_private			= $obj->note;
                     $this->percentage			= $obj->percentage;
     
                     $this->authorid             = $obj->fk_user_author;
    @@ -634,7 +656,6 @@ class ActionComm extends CommonObject
             }
     
             return $num;
    -
         }
     
     	/**
    @@ -682,6 +703,7 @@ class ActionComm extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Initialize this->userassigned array with list of id of user assigned to event
          *
    @@ -689,6 +711,7 @@ class ActionComm extends CommonObject
          */
         function fetch_userassigned()
         {
    +        // phpcs:enable
             $sql ="SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency";
     		$sql.=" FROM ".MAIN_DB_PREFIX."actioncomm_resources";
     		$sql.=" WHERE element_type = 'user' AND fk_actioncomm = ".$this->id;
    @@ -840,7 +863,7 @@ class ActionComm extends CommonObject
             $sql.= ", datep = ".(strval($this->datep)!='' ? "'".$this->db->idate($this->datep)."'" : 'null');
             $sql.= ", datep2 = ".(strval($this->datef)!='' ? "'".$this->db->idate($this->datef)."'" : 'null');
             $sql.= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != ''?"'".$this->db->escape($this->durationp)."'":"null");	// deprecated
    -        $sql.= ", note = ".($this->note ? "'".$this->db->escape($this->note)."'":"null");
    +        $sql.= ", note = '".$this->db->escape($this->note_private?$this->note_private:$this->note)."'";
             $sql.= ", fk_project =". ($this->fk_project > 0 ? $this->fk_project:"null");
             $sql.= ", fk_soc =". ($socid > 0 ? $socid:"null");
             $sql.= ", fk_contact =". ($contactid > 0 ? $contactid:"null");
    @@ -913,7 +936,6 @@ class ActionComm extends CommonObject
     							$error++;
     							$this->errors[]=$this->db->lasterror();
     						}
    -
     					}
     				}
     			}
    @@ -1004,6 +1026,7 @@ class ActionComm extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
    @@ -1013,7 +1036,8 @@ class ActionComm extends CommonObject
          */
         function load_board($user, $load_state_board=0)
         {
    -    	global $conf, $langs;
    +        // phpcs:enable
    +        global $conf, $langs;
     
         	if(empty($load_state_board)) $sql = "SELECT a.id, a.datep as dp";
         	else {
    @@ -1128,6 +1152,7 @@ class ActionComm extends CommonObject
             return $this->LibStatut($this->percentage,$mode,$hidenastatus,$this->datep);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *		Return label of action status
          *
    @@ -1139,63 +1164,64 @@ class ActionComm extends CommonObject
          */
         function LibStatut($percent,$mode,$hidenastatus=0,$datestart='')
         {
    +        // phpcs:enable
             global $langs;
     
             if ($mode == 0)
             {
             	if ($percent==-1 && ! $hidenastatus) return $langs->trans('StatusNotApplicable');
    -        	else if ($percent==0) return $langs->trans('StatusActionToDo').' (0%)';
    -        	else if ($percent > 0 && $percent < 100) return $langs->trans('StatusActionInProcess').' ('.$percent.'%)';
    -        	else if ($percent >= 100) return $langs->trans('StatusActionDone').' (100%)';
    +        	elseif ($percent==0) return $langs->trans('StatusActionToDo').' (0%)';
    +        	elseif ($percent > 0 && $percent < 100) return $langs->trans('StatusActionInProcess').' ('.$percent.'%)';
    +        	elseif ($percent >= 100) return $langs->trans('StatusActionDone').' (100%)';
             }
    -        else if ($mode == 1)
    +        elseif ($mode == 1)
             {
             	if ($percent==-1 && ! $hidenastatus) return $langs->trans('StatusNotApplicable');
    -        	else if ($percent==0) return $langs->trans('StatusActionToDo');
    -        	else if ($percent > 0 && $percent < 100) return $percent.'%';
    -        	else if ($percent >= 100) return $langs->trans('StatusActionDone');
    +        	elseif ($percent==0) return $langs->trans('StatusActionToDo');
    +        	elseif ($percent > 0 && $percent < 100) return $percent.'%';
    +        	elseif ($percent >= 100) return $langs->trans('StatusActionDone');
             }
    -        else if ($mode == 2)
    +        elseif ($mode == 2)
             {
             	if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9').' '.$langs->trans('StatusNotApplicable');
    -        	else if ($percent==0) return img_picto($langs->trans('StatusActionToDo'),'statut1').' '.$langs->trans('StatusActionToDo');
    -        	else if ($percent > 0 && $percent < 100) return img_picto($langs->trans('StatusActionInProcess'),'statut3').' '. $percent.'%';
    -        	else if ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6').' '.$langs->trans('StatusActionDone');
    +        	elseif ($percent==0) return img_picto($langs->trans('StatusActionToDo'),'statut1').' '.$langs->trans('StatusActionToDo');
    +        	elseif ($percent > 0 && $percent < 100) return img_picto($langs->trans('StatusActionInProcess'),'statut3').' '. $percent.'%';
    +        	elseif ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6').' '.$langs->trans('StatusActionDone');
             }
    -        else if ($mode == 3)
    +        elseif ($mode == 3)
             {
             	if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans("Status").': '.$langs->trans('StatusNotApplicable'),'statut9');
    -        	else if ($percent==0) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionToDo').' (0%)','statut1');
    -        	else if ($percent > 0 && $percent < 100) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionInProcess').' ('.$percent.'%)','statut3');
    -        	else if ($percent >= 100) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionDone').' (100%)','statut6');
    +        	elseif ($percent==0) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionToDo').' (0%)','statut1');
    +        	elseif ($percent > 0 && $percent < 100) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionInProcess').' ('.$percent.'%)','statut3');
    +        	elseif ($percent >= 100) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionDone').' (100%)','statut6');
             }
    -        else if ($mode == 4)
    +        elseif ($mode == 4)
             {
             	if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9').' '.$langs->trans('StatusNotApplicable');
    -        	else if ($percent==0) return img_picto($langs->trans('StatusActionToDo'),'statut1').' '.$langs->trans('StatusActionToDo').' (0%)';
    -        	else if ($percent > 0 && $percent < 100) return img_picto($langs->trans('StatusActionInProcess'),'statut3').' '.$langs->trans('StatusActionInProcess').' ('.$percent.'%)';
    -        	else if ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6').' '.$langs->trans('StatusActionDone').' (100%)';
    +        	elseif ($percent==0) return img_picto($langs->trans('StatusActionToDo'),'statut1').' '.$langs->trans('StatusActionToDo').' (0%)';
    +        	elseif ($percent > 0 && $percent < 100) return img_picto($langs->trans('StatusActionInProcess'),'statut3').' '.$langs->trans('StatusActionInProcess').' ('.$percent.'%)';
    +        	elseif ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6').' '.$langs->trans('StatusActionDone').' (100%)';
             }
    -        else if ($mode == 5)
    +        elseif ($mode == 5)
             {
             	if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9');
    -        	else if ($percent==0) return '0% '.img_picto($langs->trans('StatusActionToDo'),'statut1');
    -        	else if ($percent > 0 && $percent < 100) return $percent.'% '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
    -        	else if ($percent >= 100) return $langs->trans('StatusActionDone').' '.img_picto($langs->trans('StatusActionDone'),'statut6');
    +        	elseif ($percent==0) return '0% '.img_picto($langs->trans('StatusActionToDo'),'statut1');
    +        	elseif ($percent > 0 && $percent < 100) return $percent.'% '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
    +        	elseif ($percent >= 100) return $langs->trans('StatusActionDone').' '.img_picto($langs->trans('StatusActionDone'),'statut6');
             }
    -        else if ($mode == 6)
    +        elseif ($mode == 6)
             {
             	if ($percent==-1 && ! $hidenastatus) return $langs->trans('StatusNotApplicable').' '.img_picto($langs->trans('StatusNotApplicable'),'statut9');
    -        	else if ($percent==0) return $langs->trans('StatusActionToDo').' (0%) '.img_picto($langs->trans('StatusActionToDo'),'statut1');
    -        	else if ($percent > 0 && $percent < 100) return $langs->trans('StatusActionInProcess').' ('.$percent.'%) '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
    -        	else if ($percent >= 100) return $langs->trans('StatusActionDone').' (100%) '.img_picto($langs->trans('StatusActionDone'),'statut6');
    +        	elseif ($percent==0) return $langs->trans('StatusActionToDo').' (0%) '.img_picto($langs->trans('StatusActionToDo'),'statut1');
    +        	elseif ($percent > 0 && $percent < 100) return $langs->trans('StatusActionInProcess').' ('.$percent.'%) '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
    +        	elseif ($percent >= 100) return $langs->trans('StatusActionDone').' (100%) '.img_picto($langs->trans('StatusActionDone'),'statut6');
             }
    -        else if ($mode == 7)
    +        elseif ($mode == 7)
             {
                 if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9');
    -            else if ($percent==0) return '0% '.img_picto($langs->trans('StatusActionToDo'),'statut1');
    -            else if ($percent > 0 && $percent < 100) return $percent.'% '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
    -            else if ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6');
    +            elseif ($percent==0) return '0% '.img_picto($langs->trans('StatusActionToDo'),'statut1');
    +            elseif ($percent > 0 && $percent < 100) return $percent.'% '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
    +            elseif ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6');
             }
     
             return '';
    @@ -1220,7 +1246,10 @@ class ActionComm extends CommonObject
     
     		if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
     
    -		$label = $this->label;
    +                if ((!$user->rights->agenda->allactions->read && $this->author->id != $user->id) || (!$user->rights->agenda->myactions->read && $this->author->id == $user->id))
    +                    $option = 'nolink';
    +
    +                $label = $this->label;
     		if (empty($label)) $label=$this->libelle;   // For backward compatibility
     
     		$result='';
    @@ -1286,6 +1315,10 @@ class ActionComm extends CommonObject
     		$linkstart.=$linkclose.'>';
     		$linkend='</a>';
     
    +                if ($option == 'nolink') {
    +                    $linkstart = '';
    +                    $linkend = '';
    +                }
     		//print 'rrr'.$this->libelle.'rrr'.$this->label.'rrr'.$withpicto;
     
             if ($withpicto == 2)
    @@ -1329,6 +1362,7 @@ class ActionComm extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *		Export events from database into a cal file.
          *
    @@ -1341,11 +1375,12 @@ class ActionComm extends CommonObject
          */
         function build_exportfile($format,$type,$cachedelay,$filename,$filters)
         {
    +        // phpcs:enable
             global $conf,$langs,$dolibarr_main_url_root,$mysoc;
     
    -        require_once (DOL_DOCUMENT_ROOT ."/core/lib/xcal.lib.php");
    -        require_once (DOL_DOCUMENT_ROOT ."/core/lib/date.lib.php");
    -        require_once (DOL_DOCUMENT_ROOT ."/core/lib/files.lib.php");
    +        require_once DOL_DOCUMENT_ROOT ."/core/lib/xcal.lib.php";
    +        require_once DOL_DOCUMENT_ROOT ."/core/lib/date.lib.php";
    +        require_once DOL_DOCUMENT_ROOT ."/core/lib/files.lib.php";
     
             dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG);
     
    @@ -1533,8 +1568,8 @@ class ActionComm extends CommonObject
     
                 // Write file
                 if ($format == 'vcal') $result=build_calfile($format,$title,$desc,$eventarray,$outputfiletmp);
    -            if ($format == 'ical') $result=build_calfile($format,$title,$desc,$eventarray,$outputfiletmp);
    -            if ($format == 'rss')  $result=build_rssfile($format,$title,$desc,$eventarray,$outputfiletmp);
    +            elseif ($format == 'ical') $result=build_calfile($format,$title,$desc,$eventarray,$outputfiletmp);
    +            elseif ($format == 'rss')  $result=build_rssfile($format,$title,$desc,$eventarray,$outputfiletmp);
     
                 if ($result >= 0)
                 {
    @@ -1659,8 +1694,6 @@ class ActionComm extends CommonObject
     
     		// TODO Scan events of type 'email' into table llx_actioncomm_reminder with status todo, send email, then set status to done
     
    -
    -
         	// Delete also very old past events (we do not keep more than 1 month record in past)
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder WHERE dateremind < '".$this->db->jdate($now - (3600 * 24 * 32))."'";
     		$this->db->query($sql);
    @@ -1669,6 +1702,4 @@ class ActionComm extends CommonObject
     
         	return $error;
         }
    -
     }
    -
    diff --git a/htdocs/comm/action/class/actioncommreminder.class.php b/htdocs/comm/action/class/actioncommreminder.class.php
    index 4873db461f6..6631d0e375d 100644
    --- a/htdocs/comm/action/class/actioncommreminder.class.php
    +++ b/htdocs/comm/action/class/actioncommreminder.class.php
    @@ -34,14 +34,17 @@ class ActionCommReminder extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'actioncomm_reminder';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'actioncomm_reminder';
    +
     	/**
     	 * @var array  Does actioncommreminder support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 0;
    +
     	/**
     	 * @var string String with name of icon for actioncommreminder. Must be the part after the 'object_' into object_actioncommreminder.png
     	 */
    @@ -78,13 +81,28 @@ class ActionCommReminder extends CommonObject
     		'offsetunit' => array('type'=>'varchar(1)', 'label'=>'OffsetUnit', 'visible'=>1, 'enabled'=>1, 'position'=>57, 'notnull'=>1, 'comment'=>"m, h, d, w",),
     		'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'default'=>0, 'index'=>0, 'arrayofkeyval'=>array('0'=>'ToDo', '1'=>'Done')),
     	);
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
     	public $dateremind;
     	public $typeremind;
    +
    +	/**
    +	 * @var int User ID
    +	 */
     	public $fk_user;
    +
     	public $offsetvalue;
     	public $offsetunit;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	// END MODULEBUILDER PROPERTIES
     
     
    @@ -165,6 +183,7 @@ class ActionCommReminder extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -174,43 +193,38 @@ class ActionCommReminder extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
    -		if ($mode == 0)
    -		{
    -			$prefix='';
    -			if ($status == 1) return $langs->trans('Done');
    -			if ($status == 0) return $langs->trans('ToDo');
    -		}
    -		if ($mode == 1)
    +		if ($mode == 0 || $mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Done');
    -			if ($status == 0) return $langs->trans('ToDo');
    +			elseif ($status == 0) return $langs->trans('ToDo');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Done'),'statut4').' '.$langs->trans('Done');
    -			if ($status == 0) return img_picto($langs->trans('ToDo'),'statut5').' '.$langs->trans('ToDo');
    +			elseif ($status == 0) return img_picto($langs->trans('ToDo'),'statut5').' '.$langs->trans('ToDo');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Done'),'statut4');
    -			if ($status == 0) return img_picto($langs->trans('ToDo'),'statut5');
    +			elseif ($status == 0) return img_picto($langs->trans('ToDo'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Done'),'statut4').' '.$langs->trans('Done');
    -			if ($status == 0) return img_picto($langs->trans('ToDo'),'statut5').' '.$langs->trans('ToDo');
    +			elseif ($status == 0) return img_picto($langs->trans('ToDo'),'statut5').' '.$langs->trans('ToDo');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Done').' '.img_picto($langs->trans('Done'),'statut4');
    -			if ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'),'statut5');
    +			elseif ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 1) return $langs->trans('Done').' '.img_picto($langs->trans('Done'),'statut4');
    -			if ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'),'statut5');
    +			elseif ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'),'statut5');
     		}
     	}
     
    @@ -224,6 +238,4 @@ class ActionCommReminder extends CommonObject
     	{
     		$this->initAsSpecimenCommon();
     	}
    -
     }
    -
    diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php
    index f5d9c7db762..1e9dde34bde 100644
    --- a/htdocs/comm/action/class/api_agendaevents.class.php
    +++ b/htdocs/comm/action/class/api_agendaevents.class.php
    @@ -46,8 +46,8 @@ class AgendaEvents extends DolibarrApi
          */
         function __construct()
         {
    -		global $db, $conf;
    -		$this->db = $db;
    +        global $db, $conf;
    +        $this->db = $db;
             $this->actioncomm = new ActionComm($this->db);
         }
     
    @@ -99,13 +99,14 @@ class AgendaEvents extends DolibarrApi
          * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'%dol%') and (t.datec:<:'20160101')"
          * @return  array               Array of Agenda Events objects
          */
    -    function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
     
             if (! DolibarrApiAccess::$user->rights->agenda->myactions->read) {
    -        	throw new RestException(401, "Insuffisant rights to read events");
    +            throw new RestException(401, "Insuffisant rights to read events");
             }
     
             // case of external user
    @@ -218,7 +219,7 @@ class AgendaEvents extends DolibarrApi
     
     
         /**
    -     * Update Agenda Event general fields (won't touch lines of expensereport)
    +     * Update Agenda Event general fields
          *
          * @param int   $id             Id of Agenda Event to update
          * @param array $request_data   Datas
    @@ -226,7 +227,8 @@ class AgendaEvents extends DolibarrApi
          * @return int
          */
         /*
    -    function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
           if (! DolibarrApiAccess::$user->rights->agenda->myactions->create) {
     			  throw new RestException(401, "Insuffisant rights to create your Agenda Event");
     		  }
    @@ -234,20 +236,20 @@ class AgendaEvents extends DolibarrApi
     		      throw new RestException(401, "Insuffisant rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
     		  }
     
    -        $result = $this->expensereport->fetch($id);
    +        $result = $this->actioncomm->fetch($id);
             if ( ! $result ) {
    -            throw new RestException(404, 'expensereport not found');
    +            throw new RestException(404, 'actioncomm not found');
             }
     
    -		if ( ! DolibarrApi::_checkAccessToResource('expensereport',$this->expensereport->id)) {
    +		if ( ! DolibarrApi::_checkAccessToResource('actioncomm',$this->actioncomm->id)) {
     			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
     		}
             foreach($request_data as $field => $value) {
                 if ($field == 'id') continue;
    -            $this->expensereport->$field = $value;
    +            $this->actioncomm->$field = $value;
             }
     
    -        if ($this->expensereport->update($id, DolibarrApiAccess::$user,1,'','','update'))
    +        if ($this->actioncomm->update($id, DolibarrApiAccess::$user,1,'','','update'))
                 return $this->get($id);
     
             return false;
    @@ -291,7 +293,6 @@ class AgendaEvents extends DolibarrApi
                     'message' => 'Agenda Event deleted'
                 )
             );
    -
         }
     
         /**
    @@ -308,7 +309,6 @@ class AgendaEvents extends DolibarrApi
                 if (!isset($data[$field]))
                     throw new RestException(400, "$field field missing");
                 $event[$field] = $data[$field];
    -
             }
             return $event;
         }
    @@ -319,7 +319,8 @@ class AgendaEvents extends DolibarrApi
          * @param	object	$object		Object to clean
          * @return	array				Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
         	$object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php
    index d8496a9a4ff..d6c25f6d4c1 100644
    --- a/htdocs/comm/action/class/cactioncomm.class.php
    +++ b/htdocs/comm/action/class/cactioncomm.class.php
    @@ -24,24 +24,43 @@
     
     
     /**
    - *		Class to manage different types of events
    + *      Class to manage different types of events
      */
     class CActionComm
     {
    -    var $error;
    -    var $db;
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error='';
     
    -    var $id;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    var $code;
    -    var $type;
    -    var $libelle;       // deprecated
    -    var $label;
    -    var $active;
    -    var $color;
    -    var $picto;
    +    /**
    +     * @var int ID
    +     */
    +    public $id;
     
    -    var $type_actions=array();
    +    public $code;
    +    public $type;
    +    public $libelle;       // deprecated
    +
    +    /**
    +     * @var string Type of agenda event label
    +     */
    +    public $label;
    +
    +    public $active;
    +    public $color;
    +
    +    /**
    +     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +     */
    +    public $picto;
    +
    +    public $type_actions=array();
     
     
         /**
    @@ -99,6 +118,7 @@ class CActionComm
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return list of event types: array(id=>label) or array(code=>label)
          *
    @@ -112,6 +132,7 @@ class CActionComm
          */
         function liste_array($active='',$idorcode='id',$excludetype='',$onlyautoornot=0, $morefilter='', $shortlabel=0)
         {
    +        // phpcs:enable
             global $langs,$conf;
             $langs->load("commercial");
     
    @@ -210,5 +231,4 @@ class CActionComm
             $transcode=$langs->trans("Action".$this->code);
             if ($transcode != "Action".$this->code) return $transcode;
         }
    -
     }
    diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php
    index 708b52c9151..d3c2070d321 100644
    --- a/htdocs/comm/action/class/ical.class.php
    +++ b/htdocs/comm/action/class/ical.class.php
    @@ -27,7 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/xcal.lib.php';
     
     
     /**
    - *		Class to read/parse ICal calendars
    + *  Class to read/parse ICal calendars
      */
     class ICal
     {
    @@ -39,15 +39,15 @@ class ICal
         var $last_key; //Help variable save last key (multiline string)
     
     
    -	/**
    -	 * Constructor
    -	 */
    -	public function __construct()
    -	{
    +    /**
    +     * Constructor
    +     */
    +    public function __construct()
    +    {
    +    }
     
    -	}
    -
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          * Read text file, icalender text file
          *
          * @param 	string 	$file		File
    @@ -55,6 +55,7 @@ class ICal
          */
         function read_file($file)
         {
    +        // phpcs:enable
             $this->file = $file;
             $file_text='';
     
    @@ -67,6 +68,7 @@ class ICal
             return $file_text; // return all text
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Returns the number of calendar events
          *
    @@ -74,9 +76,11 @@ class ICal
          */
         function get_event_count()
         {
    +        // phpcs:enable
             return $this->event_count;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Returns the number of to do
          *
    @@ -84,6 +88,7 @@ class ICal
          */
         function get_todo_count()
         {
    +        // phpcs:enable
             return $this->todo_count;
         }
     
    @@ -195,6 +200,7 @@ class ICal
             return $this->cal;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Add to $this->ical array one value and key.
          *
    @@ -205,6 +211,7 @@ class ICal
          */
         function add_to_array($type, $key, $value)
         {
    +        // phpcs:enable
     
             //print 'type='.$type.' key='.$key.' value='.$value.'<br>'."\n";
     
    @@ -255,6 +262,7 @@ class ICal
             $this->last_key = $key;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value");
          *
    @@ -263,7 +271,8 @@ class ICal
          */
         function retun_key_value($text)
         {
    -    	/*
    +        // phpcs:enable
    +        /*
             preg_match("/([^:]+)[:]([\w\W]+)/", $text, $matches);
     
             if (empty($matches))
    @@ -275,9 +284,10 @@ class ICal
                 $matches = array_splice($matches, 1, 2);
                 return $matches;
             }*/
    -		return explode(':',$text,2);
    +        return explode(':',$text,2);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Parse RRULE  return array
          *
    @@ -286,7 +296,8 @@ class ICal
          */
         function ical_rrule($value)
         {
    -    	$result=array();
    +        // phpcs:enable
    +        $result = array();
             $rrule = explode(';',$value);
             foreach ($rrule as $line)
             {
    @@ -295,6 +306,8 @@ class ICal
             }
             return $result;
         }
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS)
          *
    @@ -303,6 +316,7 @@ class ICal
          */
         function ical_date_to_unix($ical_date)
         {
    +        // phpcs:enable
             $ical_date = str_replace('T', '', $ical_date);
             $ical_date = str_replace('Z', '', $ical_date);
     
    @@ -316,6 +330,7 @@ class ICal
             return $ntime;      // ntime is a GTM time
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return unix date from iCal date format
          *
    @@ -325,7 +340,8 @@ class ICal
          */
         function ical_dt_date($key, $value)
         {
    -    	$return_value=array();
    +        // phpcs:enable
    +        $return_value = array();
             $value = $this->ical_date_to_unix($value);
     
             // Analyse TZID
    @@ -345,6 +361,7 @@ class ICal
             return array($key,$return_value);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return sorted eventlist as array or false if calenar is empty
          *
    @@ -352,6 +369,7 @@ class ICal
          */
         function get_sort_event_list()
         {
    +        // phpcs:enable
             $temp = $this->get_event_list();
             if (!empty($temp))
             {
    @@ -364,6 +382,7 @@ class ICal
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Compare two unix timestamp
          *
    @@ -373,9 +392,11 @@ class ICal
          */
         function ical_dtstart_compare($a, $b)
         {
    +        // phpcs:enable
             return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return eventlist array (not sort eventlist array)
          *
    @@ -383,9 +404,11 @@ class ICal
          */
         function get_event_list()
         {
    +        // phpcs:enable
             return (! empty($this->cal['VEVENT'])?$this->cal['VEVENT']:'');
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return eventlist array (not sort eventlist array)
          *
    @@ -393,9 +416,11 @@ class ICal
          */
         function get_freebusy_list()
         {
    +        // phpcs:enable
             return $this->cal['VFREEBUSY'];
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return to do array (not sort to do array)
          *
    @@ -403,9 +428,11 @@ class ICal
          */
         function get_todo_list()
         {
    +        // phpcs:enable
             return $this->cal['VTODO'];
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return base calendar data
          *
    @@ -413,9 +440,11 @@ class ICal
          */
         function get_calender_data()
         {
    +        // phpcs:enable
             return $this->cal['VCALENDAR'];
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return array with all data
          *
    @@ -423,6 +452,7 @@ class ICal
          */
         function get_all_data()
         {
    +        // phpcs:enable
             return $this->cal;
         }
     }
    diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php
    index 43e5b89f115..a5998e220f7 100644
    --- a/htdocs/comm/action/document.php
    +++ b/htdocs/comm/action/document.php
    @@ -239,7 +239,7 @@ if ($object->id > 0)
     
     	print '<table class="border" width="100%">';
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -268,7 +268,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
    index c361d275882..0bc022956b1 100644
    --- a/htdocs/comm/action/index.php
    +++ b/htdocs/comm/action/index.php
    @@ -83,7 +83,7 @@ $resourceid=GETPOST("resourceid","int");
     $year=GETPOST("year","int")?GETPOST("year","int"):date("Y");
     $month=GETPOST("month","int")?GETPOST("month","int"):date("m");
     $week=GETPOST("week","int")?GETPOST("week","int"):date("W");
    -$day=GETPOST("day","int")?GETPOST("day","int"):0;
    +$day=GETPOST("day","int")?GETPOST("day","int"):date("d");
     $pid=GETPOST("projectid","int",3);
     $status=GETPOST("status",'aZ09');		// status may be 0, 50, 100, 'todo'
     $type=GETPOST("type",'az09');
    @@ -101,20 +101,23 @@ else
     if ($actioncode == '' && empty($actioncodearray)) $actioncode=(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE);
     
     if ($status == ''   && ! isset($_GET['status']) && ! isset($_POST['status'])) $status=(empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS)?'':$conf->global->AGENDA_DEFAULT_FILTER_STATUS);
    -if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $action=(empty($conf->global->AGENDA_DEFAULT_VIEW)?'show_month':$conf->global->AGENDA_DEFAULT_VIEW);
    -if ($action == 'default')
    +
    +$defaultview = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW);
    +$defaultview = (empty($user->conf->AGENDA_DEFAULT_VIEW) ? $defaultview : $user->conf->AGENDA_DEFAULT_VIEW);
    +if (empty($action) && ! isset($_GET['action']) && ! isset($_POST['action'])) $action=$defaultview;
    +if ($action == 'default')	// When action is default, we want a calendar view and not the list
     {
    -	$action = ((! empty($conf->global->AGENDA_DEFAULT_VIEW) && $conf->global->AGENDA_DEFAULT_VIEW!='show_list') ? $conf->global->AGENDA_DEFAULT_VIEW : 'show_month');
    +	$action = (($defaultview != 'show_list') ? $defaultview : 'show_month');
     }
    -if (GETPOST('viewcal') && $action != 'show_day' && $action != 'show_week')  {
    +if (GETPOST('viewcal','none') && GETPOST('action','alpha') != 'show_day' && GETPOST('action','alpha') != 'show_week')  {
         $action='show_month'; $day='';
    -}                                                   // View by month
    -if (GETPOST('viewweek') || $action == 'show_week') {
    +} // View by month
    +if (GETPOST('viewweek','none') || GETPOST('action','alpha') == 'show_week') {
         $action='show_week'; $week=($week?$week:date("W")); $day=($day?$day:date("d"));
    -}  // View by week
    -if (GETPOST('viewday') || $action == 'show_day')  {
    +} // View by week
    +if (GETPOST('viewday','none') || GETPOST('action','alpha') == 'show_day')  {
         $action='show_day'; $day=($day?$day:date("d"));
    -}                                  // View by day
    +} // View by day
     
     // Load translation files required by the page
     $langs->loadLangs(array('agenda', 'other', 'commercial'));
    @@ -663,7 +666,6 @@ if ($resql)
                 //print ' startincalendar='.dol_print_date($event->date_start_in_calendar).'-endincalendar='.dol_print_date($event->date_end_in_calendar).') was added in '.$j.' different index key of array<br>';
             }
             $i++;
    -
         }
     }
     else
    @@ -1250,8 +1252,8 @@ else    // View by day
     
     print "\n".'</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    @@ -1593,13 +1595,13 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa
                                     $cachecontacts[$event->contact->id]=$contact;
                                 }
                                 else $contact=$cachecontacts[$event->contact->id];
    -                            if ($linerelatedto) $linerelatedto.=' / ';
    +                            if ($linerelatedto) $linerelatedto.='&nbsp;';
                                 if (! empty($contact->id)) $linerelatedto.=$contact->getNomUrl(1,'',0);
                             }
                             if (! empty($event->fk_element) && $event->fk_element > 0 && ! empty($event->elementtype) && ! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT))
                             {
                                 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -                            if ($linerelatedto) $linerelatedto.=' / ';
    +                            if ($linerelatedto) $linerelatedto.='<br>';
                                 $linerelatedto.=dolGetElementUrl($event->fk_element,$event->elementtype,1);
                             }
                             if ($linerelatedto) print '<br>'.$linerelatedto;
    diff --git a/htdocs/comm/action/info.php b/htdocs/comm/action/info.php
    index 9a043a13690..2582e9b6b32 100644
    --- a/htdocs/comm/action/info.php
    +++ b/htdocs/comm/action/info.php
    @@ -114,5 +114,6 @@ print '</td></tr></table>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php
    index 2c11a1de977..02d3a16c7f3 100644
    --- a/htdocs/comm/action/list.php
    +++ b/htdocs/comm/action/list.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2017      Open-DSI             <support@open-dsi.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -189,9 +190,9 @@ $form=new Form($db);
     $userstatic=new User($db);
     $formactions=new FormActions($db);
     
    -$nav='';
    -$nav.=$form->select_date($dateselect, 'dateselect', 0, 0, 1, '', 1, 0, 1);
    -$nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
    +$nav = '';
    +$nav .= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0);
    +$nav .=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
     
     $now=dol_now();
     
    @@ -438,15 +439,17 @@ if ($resql)
     	if (! empty($arrayfields['a.label']['checked']))	print '<td class="liste_titre"><input type="text" class="maxwidth75" name="search_title" value="'.$search_title.'"></td>';
     	if (! empty($arrayfields['a.datep']['checked']))	{
     		print '<td class="liste_titre nowraponall" align="center">';
    -		print $form->select_date($datestart, 'datestart', 0, 0, 1, '', 1, 0, 1);
    +		print $form->selectDate($datestart, 'datestart', 0, 0, 1, '', 1, 0);
     		print '</td>';
     	}
     	if (! empty($arrayfields['a.datep2']['checked']))	{
     		print '<td class="liste_titre nowraponall" align="center">';
    -		print $form->select_date($dateend, 'dateend', 0, 0, 1, '', 1, 0, 1);
    +		print $form->selectDate($dateend, 'dateend', 0, 0, 1, '', 1, 0);
     		print '</td>';
     	}
    -	if (! empty($arrayfields['s.nom']['checked']))			print '<td class="liste_titre"></td>';
    +	if (! empty($arrayfields['s.nom']['checked'])) {
    +        print '<td class="liste_titre"></td>';
    +    }
     	if (! empty($arrayfields['a.fk_contact']['checked']))	print '<td class="liste_titre"></td>';
     	if (! empty($arrayfields['a.fk_element']['checked']))	print '<td class="liste_titre"></td>';
     
    @@ -640,7 +643,6 @@ if ($resql)
                   		print "&nbsp;";
     		        }
     		        print '</td>';
    -
     		}
     
     		// Extra fields
    @@ -665,14 +667,12 @@ if ($resql)
     	print '</form>';
     
     	$db->free($resql);
    -
     }
     else
     {
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php
    index 2fdfa180319..0347f73a453 100644
    --- a/htdocs/comm/action/pertype.php
    +++ b/htdocs/comm/action/pertype.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2011      Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2014      Cedric GROSS         <c.gross@kreiz-it.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -262,7 +263,7 @@ $nav.='<input type="hidden" name="begin_d" value="' . $begin_d . '">';
     $nav.='<input type="hidden" name="end_d" value="' . $end_d . '">';
     $nav.='<input type="hidden" name="showbirthday" value="' . $showbirthday . '">';
     
    -$nav.=$form->select_date($dateselect, 'dateselect', 0, 0, 1, '', 1, 0, 1);
    +$nav.= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0);
     $nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
     $nav.='</form>';
     
    @@ -542,7 +543,6 @@ if ($resql)
                 //print ' startincalendar='.dol_print_date($event->date_start_in_calendar).'-endincalendar='.dol_print_date($event->date_end_in_calendar).') was added in '.$j.' different index key of array<br>';
             }
             $i++;
    -
         }
     }
     else
    @@ -730,10 +730,8 @@ jQuery(document).ready(function() {
     });
     </script>';
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php
    index 0cf056ef3a9..b145dfa54ed 100644
    --- a/htdocs/comm/action/peruser.php
    +++ b/htdocs/comm/action/peruser.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2011      Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2014      Cedric GROSS         <c.gross@kreiz-it.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -276,7 +277,7 @@ $nav.='<input type="hidden" name="begin_d" value="' . $begin_d . '">';
     $nav.='<input type="hidden" name="end_d" value="' . $end_d . '">';
     $nav.='<input type="hidden" name="showbirthday" value="' . $showbirthday . '">';
     */
    -$nav.=$form->select_date($dateselect, 'dateselect', 0, 0, 1, '', 1, 0, 1);
    +$nav.= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0);
     $nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
     //$nav.='</form>';
     
    @@ -570,7 +571,6 @@ if ($resql)
                 //print ' startincalendar='.dol_print_date($event->date_start_in_calendar).'-endincalendar='.dol_print_date($event->date_end_in_calendar).') was added in '.$j.' different index key of array<br>';
             }
             $i++;
    -
         }
         $db->free($resql);
     }
    @@ -797,7 +797,6 @@ while($currentdaytoshow<$lastdaytoshow) {
     	echo "<br>";
     
     	$currentdaytoshow =  dol_time_plus_duree($currentdaytoshow, 7, 'd');
    -
     }
     
     echo '</div>';
    @@ -865,10 +864,8 @@ jQuery(document).ready(function() {
     });
     </script>';
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php
    index 7e4108b470b..ff1c7746afa 100644
    --- a/htdocs/comm/action/rapport/index.php
    +++ b/htdocs/comm/action/rapport/index.php
    @@ -209,5 +209,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/address.php b/htdocs/comm/address.php
    index 9c8b275d198..4b32eea153a 100644
    --- a/htdocs/comm/address.php
    +++ b/htdocs/comm/address.php
    @@ -151,7 +151,6 @@ if ($action == 'add' || $action == 'update')
                 $action= "edit";
             }
         }
    -
     }
     
     else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->societe->supprimer)
    @@ -291,7 +290,6 @@ if ($action == 'create')
             print '</div>'."\n";
     
             print '</form>'."\n";
    -
         }
     }
     elseif ($action == 'edit')
    @@ -486,7 +484,6 @@ else
             }
             print '</div>';
         }
    -
     }
     
     
    diff --git a/htdocs/comm/admin/propal_extrafields.php b/htdocs/comm/admin/propal_extrafields.php
    index 6a6aa12862a..becfabc949c 100644
    --- a/htdocs/comm/admin/propal_extrafields.php
    +++ b/htdocs/comm/admin/propal_extrafields.php
    @@ -111,6 +111,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/admin/propaldet_extrafields.php b/htdocs/comm/admin/propaldet_extrafields.php
    index 49784228fe6..7172c0e5b7c 100644
    --- a/htdocs/comm/admin/propaldet_extrafields.php
    +++ b/htdocs/comm/admin/propaldet_extrafields.php
    @@ -86,7 +86,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -99,7 +99,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -118,6 +118,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php
    index f552382bcce..d11a81f5bdb 100644
    --- a/htdocs/comm/card.php
    +++ b/htdocs/comm/card.php
    @@ -588,7 +588,7 @@ if ($object->id > 0)
     		$link=DOL_URL_ROOT.'/comm/propal/list.php?socid='.$object->id;
     		$icon='bill';
     		if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -		$boxstat.='<div class="boxstats">';
    +		$boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     		$boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     		$boxstat.='<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
     		$boxstat.='</div>';
    @@ -606,7 +606,7 @@ if ($object->id > 0)
     		$link=DOL_URL_ROOT.'/commande/list.php?socid='.$object->id;
     		$icon='bill';
     		if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -		$boxstat.='<div class="boxstats">';
    +		$boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     		$boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     		$boxstat.='<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
     		$boxstat.='</div>';
    @@ -624,7 +624,7 @@ if ($object->id > 0)
     		$link=DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->id;
     		$icon='bill';
     		if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -		$boxstat.='<div class="boxstats">';
    +		$boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     		$boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     		$boxstat.='<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
     		$boxstat.='</div>';
    @@ -640,7 +640,7 @@ if ($object->id > 0)
     		$link=DOL_URL_ROOT.'/compta/recap-compta.php?socid='.$object->id;
     		$icon='bill';
     		if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -		$boxstat.='<div class="boxstats">';
    +		$boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     		$boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     		$boxstat.='<span class="boxstatsindicator'.($outstandingOpened>0?' amountremaintopay':'').'">'.price($outstandingOpened, 1, $langs, 1, -1, -1, $conf->currency).$warn.'</span>';
     		$boxstat.='</div>';
    @@ -1301,7 +1301,6 @@ if ($object->id > 0)
     
         				if ($object->client != 0 && $object->client != 2) print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&socid='.$object->id.'">'.$langs->trans("AddBill").'</a></div>';
         				else print '<div class="inline-block divButAction"><a class="butActionRefused" title="'.dol_escape_js($langs->trans("ThirdPartyMustBeEditAsCustomer")).'" href="#">'.$langs->trans("AddBill").'</a></div>';
    -
         			}
         		}
         	}
    @@ -1344,7 +1343,6 @@ if ($object->id > 0)
             // List of done actions
     		show_actions_done($conf,$langs,$db,$object);
     	}
    -
     }
     else
     {
    @@ -1354,5 +1352,4 @@ else
     
     // End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/contact.php b/htdocs/comm/contact.php
    index aa8dae43140..b6d9f0922aa 100644
    --- a/htdocs/comm/contact.php
    +++ b/htdocs/comm/contact.php
    @@ -176,6 +176,6 @@ else
         dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php
    index e90a821b5e3..cb384408e91 100644
    --- a/htdocs/comm/index.php
    +++ b/htdocs/comm/index.php
    @@ -521,7 +521,6 @@ if (! empty($conf->societe->enabled) && $user->rights->societe->lire)
     				print '<td align="right" nowrap>'.dol_print_date($db->jdate($objp->tms),'day')."</td>";
     				print '</tr>';
     				$i++;
    -
     			}
     
     			$db->free($resql);
    @@ -580,7 +579,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->societe->lire)
     
     				$i++;
     			}
    -
     		}
     		else
     		{
    @@ -884,6 +882,6 @@ if (! empty($conf->commande->enabled) && $user->rights->commande->lire)
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/mailing/advtargetemailing.php b/htdocs/comm/mailing/advtargetemailing.php
    index 1c886e2ba2c..8aa14a45b85 100644
    --- a/htdocs/comm/mailing/advtargetemailing.php
    +++ b/htdocs/comm/mailing/advtargetemailing.php
    @@ -84,9 +84,12 @@ if (empty($template_id)) {
     	$result = $advTarget->fetch($template_id);
     }
     
    -if ($result < 0) {
    -	setEventMessage($advTarget->error, 'errors');
    -} else {
    +if ($result < 0)
    +{
    +	setEventMessages($advTarget->error, $advTarget->errors, 'errors');
    +}
    +else
    +{
     	if (! empty($advTarget->id)) {
     		$array_query = json_decode($advTarget->filtervalue, true);
     	}
    @@ -101,7 +104,7 @@ if ($action == 'loadfilter') {
     	if (! empty($template_id)) {
     		$result = $advTarget->fetch($template_id);
     		if ($result < 0) {
    -			setEventMessage($advTarget->error, 'errors');
    +			setEventMessages($advTarget->error, $advTarget->errors, 'errors');
     		} else {
     			if (! empty($advTarget->id)) {
     				$array_query = json_decode($advTarget->filtervalue, true);
    @@ -202,7 +205,7 @@ if ($action == 'add') {
     	// if ($array_query ['type_of_target'] == 1 || $array_query ['type_of_target'] == 3) {
     	$result = $advTarget->query_thirdparty($array_query);
     	if ($result < 0) {
    -		setEventMessage($advTarget->error, 'errors');
    +		setEventMessages($advTarget->error, $advTarget->errors, 'errors');
     	}
     	/*} else {
     		$advTarget->thirdparty_lines = array ();
    @@ -211,7 +214,7 @@ if ($action == 'add') {
     	if ($user_contact_query && ($array_query['type_of_target'] == 1 || $array_query['type_of_target'] == 2 || $array_query['type_of_target'] == 4)) {
     		$result = $advTarget->query_contact($array_query, 1);
     		if ($result < 0) {
    -			setEventMessage($advTarget->error, 'errors');
    +			setEventMessages($advTarget->error, $advTarget->errors, 'errors');
     		}
     		// If use contact but no result use artefact to so not use socid into add_to_target
     		if (count($advTarget->contact_lines) == 0) {
    @@ -222,7 +225,7 @@ if ($action == 'add') {
     	} else {
     		$advTarget->contact_lines = array ();
     	}
    -	
    +
     	if ((count($advTarget->thirdparty_lines) > 0) || (count($advTarget->contact_lines) > 0)) {
     		// Add targets into database
     		$obj = new mailing_advthirdparties($db);
    @@ -241,10 +244,10 @@ if ($action == 'add') {
     		exit();
     	}
     	if ($result == 0) {
    -		setEventMessage($langs->trans("WarningNoEMailsAdded"), 'warnings');
    +		setEventMessages($langs->trans("WarningNoEMailsAdded"), null, 'warnings');
     	}
     	if ($result < 0) {
    -		setEventMessage($obj->error, 'errors');
    +		setEventMessages($obj->error, $obj->errors, 'errors');
     	}
     }
     
    @@ -264,7 +267,7 @@ if ($action == 'savefilter' || $action == 'createfilter') {
     	$error = 0;
     
     	if ($action == 'createfilter' && empty($template_name)) {
    -		setEventMessage($langs->trans('ErrorFieldRequired', $langs->trans('AdvTgtOrCreateNewFilter')), 'errors');
    +		setEventMessages($langs->trans('ErrorFieldRequired', $langs->trans('AdvTgtOrCreateNewFilter')), null, 'errors');
     		$error ++;
     	}
     
    @@ -353,13 +356,13 @@ if ($action == 'savefilter' || $action == 'createfilter') {
     			$advTarget->name = $template_name;
     			$result = $advTarget->create($user);
     			if ($result < 0) {
    -				setEventMessage($advTarget->error, 'errors');
    +				setEventMessages($advTarget->error, $advTarget->errors, 'errors');
     			}
     		} elseif ($action == 'savefilter') {
    -			
    +
     			$result = $advTarget->update($user);
     			if ($result < 0) {
    -				setEventMessage($advTarget->error, 'errors');
    +				setEventMessages($advTarget->error, $advTarget->errors, 'errors');
     			}
     		}
     		$template_id = $advTarget->id;
    @@ -369,7 +372,7 @@ if ($action == 'savefilter' || $action == 'createfilter') {
     if ($action == 'deletefilter') {
     	$result = $advTarget->delete($user);
     	if ($result < 0) {
    -		setEventMessage($advTarget->error, 'errors');
    +		setEventMessages($advTarget->error, $advTarget->errors, 'errors');
     	}
     	header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
     	exit();
    @@ -462,11 +465,11 @@ if ($object->fetch($id) >= 0) {
     
     	// Show email selectors
     	if ($object->statut == 0 && $user->rights->mailing->creer) {
    -		
    +
     		include DOL_DOCUMENT_ROOT . '/core/tpl/advtarget.tpl.php';
    -		
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php
    index 97746ad9d82..28e49e9d171 100644
    --- a/htdocs/comm/mailing/card.php
    +++ b/htdocs/comm/mailing/card.php
    @@ -874,7 +874,7 @@ else
     				}
     			}
     
    -			$linkback = '<a href="'.DOL_URL_ROOT.'/comm/mailing/list.php">'.$langs->trans("BackToList").'</a>';
    +			$linkback = '<a href="'.DOL_URL_ROOT.'/comm/mailing/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
     			$morehtmlright='';
     			$nbtry = $nbok = 0;
    @@ -1165,7 +1165,6 @@ else
     			print '</div>';
     
     			dol_fiche_end();
    -
     		}
     		else
     		{
    @@ -1358,5 +1357,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php
    index 08ed54d2fc3..761a2bcc41d 100644
    --- a/htdocs/comm/mailing/cibles.php
    +++ b/htdocs/comm/mailing/cibles.php
    @@ -66,7 +66,6 @@ $modulesdir = dolGetModulesDirs('/mailings');
     $object = new Mailing($db);
     
     
    -
     /*
      * Actions
      */
    @@ -306,8 +305,8 @@ if ($object->fetch($id) >= 0)
     			$var = true;
     
     			// Loop on each submodule
    -            foreach($modulenames as $modulename)
    -            {
    +			foreach($modulenames as $modulename)
    +			{
     				// Loading Class
     				$file = $dir.$modulename.".modules.php";
     				$classname = "mailing_".$modulename;
    @@ -330,16 +329,14 @@ if ($object->fetch($id) >= 0)
     				// Si le module mailing est qualifie
     				if ($qualified)
     				{
    -					$var = ! $var;
    -
     					if ($allowaddtarget)
     					{
    -						print '<form '.$bctag[$var].' name="'.$modulename.'" action="'.$_SERVER['PHP_SELF'].'?action=add&id='.$object->id.'&module='.$modulename.'" method="POST" enctype="multipart/form-data">';
    +						print '<form class="oddeven tagtr" name="'.$modulename.'" action="'.$_SERVER['PHP_SELF'].'?action=add&id='.$object->id.'&module='.$modulename.'" method="POST" enctype="multipart/form-data">';
     						print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     					}
     					else
     					{
    -					    print '<div '.$bctag[$var].'>';
    +					    print '<div class="oddeven tagtr">';
     					}
     
     					print '<div class="tagtd">';
    @@ -646,10 +643,8 @@ if ($object->fetch($id) >= 0)
     	}
     
     	print "\n<!-- Fin liste destinataires selectionnes -->\n";
    -
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/mailing/class/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php
    index 50d9faf0637..baf48447bad 100644
    --- a/htdocs/comm/mailing/class/advtargetemailing.class.php
    +++ b/htdocs/comm/mailing/class/advtargetemailing.class.php
    @@ -28,14 +28,35 @@
      */
     class AdvanceTargetingMailing extends CommonObject
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $db; //!< To store db handler
    -	var $error; //!< To return error code (or message)
    -	var $errors = array(); //!< To return several error codes (or messages)
    -	var $element='advtargetemailing';			//!< Id that identify managed objects
    -	var $table_element='advtargetemailing';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -	var $id;
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='advtargetemailing';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='advtargetemailing';
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
     	var $name;
     	var $entity;
    @@ -54,9 +75,9 @@ class AdvanceTargetingMailing extends CommonObject
     
     
     	/**
    -	 * Constructor
    +	 *  Constructor
     	 *
    -	 * 	@param	DoliDb		$db		Database handler
    +	 *  @param  DoliDb		$db		Database handler
     	 */
     	function __construct($db)
     	{
    @@ -219,7 +240,6 @@ class AdvanceTargetingMailing extends CommonObject
     				$this->datec = $this->db->jdate($obj->datec);
     				$this->fk_user_mod = $obj->fk_user_mod;
     				$this->tms = $this->db->jdate($obj->tms);
    -
     			}
     			$this->db->free($resql);
     
    @@ -233,6 +253,7 @@ class AdvanceTargetingMailing extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load object in memory from the database
     	 *
    @@ -241,6 +262,7 @@ class AdvanceTargetingMailing extends CommonObject
     	 */
     	function fetch_by_mailing($id=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$sql = "SELECT";
     		$sql.= " t.rowid,";
    @@ -281,7 +303,6 @@ class AdvanceTargetingMailing extends CommonObject
     				$this->datec = $this->db->jdate($obj->datec);
     				$this->fk_user_mod = $obj->fk_user_mod;
     				$this->tms = $this->db->jdate($obj->tms);
    -
     			}
     			$this->db->free($resql);
     
    @@ -298,6 +319,7 @@ class AdvanceTargetingMailing extends CommonObject
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load object in memory from the database
     	 *
    @@ -307,6 +329,7 @@ class AdvanceTargetingMailing extends CommonObject
     	 */
     	function fetch_by_element($id=0, $type_element='mailing')
     	{
    +        // phpcs:enable
     		global $langs;
     		$sql = "SELECT";
     		$sql.= " t.rowid,";
    @@ -347,7 +370,6 @@ class AdvanceTargetingMailing extends CommonObject
     				$this->datec = $this->db->jdate($obj->datec);
     				$this->fk_user_mod = $obj->fk_user_mod;
     				$this->tms = $this->db->jdate($obj->tms);
    -
     			}
     			$this->db->free($resql);
     
    @@ -523,6 +545,7 @@ class AdvanceTargetingMailing extends CommonObject
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load object in memory from database
     	 *
    @@ -531,6 +554,7 @@ class AdvanceTargetingMailing extends CommonObject
     	 */
     	function query_thirdparty($arrayquery)
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		$sql = "SELECT";
    @@ -621,30 +645,26 @@ class AdvanceTargetingMailing extends CommonObject
     						if (!empty($arrayquery['options_'.$key.'_max'])) {
     							$sqlwhere[]= " (te.".$key." >= ".$arrayquery['options_'.$key.'_max']." AND te.".$key." <= ".$arrayquery['options_'.$key.'_min'].")";
     						}
    -					} else if (($extrafields->attribute_type[$key] == 'date') ||
    +					} elseif (($extrafields->attribute_type[$key] == 'date') ||
     						($extrafields->attribute_type[$key] == 'datetime')) {
     						if (!empty($arrayquery['options_'.$key.'_end_dt'])){
     							$sqlwhere[]= " (te.".$key." >= '".$this->db->idate($arrayquery['options_'.$key.'_st_dt'])."' AND te.".$key." <= '".$this->db->idate($arrayquery['options_'.$key.'_end_dt'])."')";
     						}
    -					}else if ($extrafields->attribute_type[$key] == 'boolean') {
    +					} elseif ($extrafields->attribute_type[$key] == 'boolean') {
     						if ($arrayquery['options_'.$key]!=''){
     							$sqlwhere[]= " (te.".$key." = ".$arrayquery['options_'.$key].")";
     						}
    -					}else{
    +					} else {
     						if (is_array($arrayquery['options_'.$key])) {
     							$sqlwhere[]= " (te.".$key." IN ('".implode("','",$arrayquery['options_'.$key])."'))";
     						} elseif (!empty($arrayquery['options_'.$key])) {
     							$sqlwhere[]= " (te.".$key." LIKE '".$arrayquery['options_'.$key]."')";
     						}
     					}
    -
     				}
    -
    -
     			}
     
     			if (count($sqlwhere)>0)	$sql.= " WHERE ".implode(" AND ",$sqlwhere);
    -
     		}
     
     
    @@ -676,6 +696,7 @@ class AdvanceTargetingMailing extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load object in memory from database
     	 *
    @@ -685,6 +706,7 @@ class AdvanceTargetingMailing extends CommonObject
     	 */
     	function query_contact($arrayquery, $withThirdpartyFilter = 0)
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		$sql = "SELECT";
    @@ -774,7 +796,6 @@ class AdvanceTargetingMailing extends CommonObject
     							$sqlwhere[]= " (te.".$key." LIKE '".$arrayquery['options_'.$key.'_cnct']."')";
     						}
     					}
    -
     				}
     
     				if (! empty($withThirdpartyFilter)) {
    @@ -916,7 +937,8 @@ class AdvanceTargetingMailing extends CommonObject
     	 *  									For exemple  jean;joe;jim%%;!jimo;!jima%> will target all jean, joe, start with jim but not jimo and not everythnig taht start by jima
     	 * 	@return		string		Sql to use for the where condition
     	 */
    -	public function transformToSQL($column_to_test,$criteria) {
    +    public function transformToSQL($column_to_test,$criteria)
    +    {
     		$return_sql_criteria = '(';
     
     		//This is a multiple value test
    @@ -939,7 +961,6 @@ class AdvanceTargetingMailing extends CommonObject
     			if (count($return_sql_not_like)>0) {
     				$return_sql_criteria .= ' AND (' . implode (' AND ', $return_sql_not_like).')';
     			}
    -
     		}else {
     			$return_sql_criteria .= $column_to_test . ' LIKE \''.$this->db->escape($criteria).'\'';
     		}
    @@ -948,6 +969,4 @@ class AdvanceTargetingMailing extends CommonObject
     
     		return $return_sql_criteria;
     	}
    -
    -
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
    index 7408bb27d37..19b1ce3e9b4 100644
    --- a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
    +++ b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php
    @@ -16,9 +16,9 @@
      */
     
     /**
    - * \file    comm/mailing/class/html.formadvtragetemaling.class.php
    + * \file    comm/mailing/class/html.formadvtargetemailing.class.php
      * \ingroup mailing
    - * \brief   Fichier de la classe des fonctions predefinie de composants html advtargetemaling
    + * \brief   Fichier de la classe des fonctions predefinies de composant html advtargetemailing
      */
     
     /**
    @@ -26,15 +26,23 @@
      */
     class FormAdvTargetEmailing extends Form
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 * Constructor
     	 *
     	 * @param DoliDB $db handler
     	 */
    -	function __construct($db) {
    +    function __construct($db)
    +    {
     		global $langs;
     
     		$this->db = $db;
    @@ -47,7 +55,8 @@ class FormAdvTargetEmailing extends Form
     	 * @param string $htmlname select field
     	 * @return string select field
     	 */
    -	function multiselectProspectionStatus($selected_array = array(), $htmlname = 'cust_prospect_status') {
    +    function multiselectProspectionStatus($selected_array = array(), $htmlname = 'cust_prospect_status')
    +    {
     		global $conf, $langs;
     		$options_array = array();
     
    @@ -83,7 +92,8 @@ class FormAdvTargetEmailing extends Form
     	 * @param array $selected_array or Code or Label of preselected country
     	 * @return string HTML string with select
     	 */
    -	function multiselectCountry($htmlname = 'country_id', $selected_array=array()) {
    +    function multiselectCountry($htmlname = 'country_id', $selected_array=array())
    +    {
     		global $conf, $langs;
     
     		$langs->load("dict");
    @@ -143,7 +153,8 @@ class FormAdvTargetEmailing extends Form
     	 * @param User $user User action
     	 * @return string combo list code
     	 */
    -	function multiselectselectSalesRepresentatives($htmlname, $selected_array, $user) {
    +    function multiselectselectSalesRepresentatives($htmlname, $selected_array, $user)
    +    {
     
     		global $conf;
     
    @@ -167,7 +178,6 @@ class FormAdvTargetEmailing extends Form
     				$label = $obj_usr->firstname . " " . $obj_usr->name . " (" . $obj_usr->login . ')';
     
     				$options_array [$obj_usr->rowid] = $label;
    -
     			}
     			$this->db->free ( $resql_usr );
     		} else {
    @@ -184,7 +194,8 @@ class FormAdvTargetEmailing extends Form
     	 * @param array $selected_array selected array
     	 * @return string combo list code
     	 */
    -	function multiselectselectLanguage($htmlname='', $selected_array=array()) {
    +    function multiselectselectLanguage($htmlname='', $selected_array=array())
    +    {
     
     		global $conf,$langs;
     
    @@ -311,7 +322,6 @@ class FormAdvTargetEmailing extends Form
     					$i++;
     				}
     			}
    -
     		}
     		else
     		{
    @@ -330,7 +340,8 @@ class FormAdvTargetEmailing extends Form
     	 * @param int $showempty show empty
     	 * @return string HTML combo
     	 */
    -	function advMultiselectarray($htmlname, $options_array = array(), $selected_array = array(), $showempty = 0) {
    +    function advMultiselectarray($htmlname, $options_array = array(), $selected_array = array(), $showempty = 0)
    +    {
     		global $conf, $langs;
     
     		$form=new Form($this->db);
    @@ -365,10 +376,10 @@ class FormAdvTargetEmailing extends Form
     	/**
     	 *  Return combo list of categories
     	 *
    -	 *  @param  string	$htmlname   Name of categorie
    -	 * 	@param	array	$selected_array	value selected
    -	 * 	@param	int	$type	type
    -	 *  @return	string HTML combo
    +	 *  @param  string	$htmlname  		Name of categorie
    +	 * 	@param	array	$selected_array	Value selected
    +	 * 	@param	int		$type			Type
    +	 *  @return	string 					HTML combo
     	 */
     	public function multiselectCategories($htmlname='',$selected_array = array(), $type=0)
     	{
    @@ -398,7 +409,6 @@ class FormAdvTargetEmailing extends Form
     					$i++;
     				}
     			}
    -
     		}
     		else
     		{
    @@ -417,7 +427,8 @@ class FormAdvTargetEmailing extends Form
     	 * @param	string		$type_element	Type element. Example: 'mailing'
     	 * @return	string 						HTML combo
     	 */
    -	public function selectAdvtargetemailingTemplate($htmlname='template_id', $selected=0, $showempty=0, $type_element='mailing') {
    +    public function selectAdvtargetemailingTemplate($htmlname='template_id', $selected=0, $showempty=0, $type_element='mailing')
    +    {
     		global $conf, $user, $langs;
     
     		$out = '';
    @@ -460,4 +471,4 @@ class FormAdvTargetEmailing extends Form
     		$this->db->free ( $resql );
     		return $out;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php
    index 63fc0a2caab..bc6f3beabd2 100644
    --- a/htdocs/comm/mailing/class/mailing.class.php
    +++ b/htdocs/comm/mailing/class/mailing.class.php
    @@ -31,44 +31,55 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Mailing extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='mailing';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='mailing';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='email';
     
    -	var $titre;
    -	var $sujet;
    -	var $body;
    -	var $nbemail;
    -	var $bgcolor;
    -	var $bgimage;
    +	public $titre;
    +	public $sujet;
    +	public $body;
    +	public $nbemail;
    +	public $bgcolor;
    +	public $bgimage;
     
    -	var $statut;       // Status 0=Draft, 1=Validated, 2=Sent partially, 3=Sent completely
    +	public $statut;       // Status 0=Draft, 1=Validated, 2=Sent partially, 3=Sent completely
     
    -	var $email_from;
    -	var $email_replyto;
    -	var $email_errorsto;
    +	public $email_from;
    +	public $email_replyto;
    +	public $email_errorsto;
     
    -	var $joined_file1;
    -	var $joined_file2;
    -	var $joined_file3;
    -	var $joined_file4;
    +	public $joined_file1;
    +	public $joined_file2;
    +	public $joined_file3;
    +	public $joined_file4;
     
    -	var $user_creat;
    -	var $user_valid;
    +	public $user_creat;
    +	public $user_valid;
     
    -	var $date_creat;
    -	var $date_valid;
    +	public $date_creat;
    +	public $date_valid;
     
    -	var $extraparams=array();
    +	public $extraparams=array();
     
     	public $statut_dest=array();
     	public $statuts=array();
     
     
    -	/**
    +    /**
          *  Constructor
          *
    -     *  @param      DoliDb		$db      Database handler
    +     *  @param      DoliDb      $db      Database handler
     	 */
     	function __construct($db)
     	{
    @@ -85,7 +96,6 @@ class Mailing extends CommonObject
     		$this->statut_dest[1] = 'MailingStatusSent';
     		$this->statut_dest[2] = 'MailingStatusRead';
     		$this->statut_dest[3] = 'MailingStatusReadAndUnsubscribe';    // Read but ask to not be contacted anymore
    -
     	}
     
     	/**
    @@ -352,7 +362,6 @@ class Mailing extends CommonObject
     							'source_id'=>$obj->source_id,
     							'source_type'=>$obj->source_type);
     						}
    -
     					}
     				}
     				else
    @@ -363,7 +372,6 @@ class Mailing extends CommonObject
     
     				$mailing_target->add_to_target($object->id, $target_array);
     			}
    -
     		}
     
     		unset($object->context['createfromclone']);
    @@ -432,6 +440,7 @@ class Mailing extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Delete targets emailing
     	 *
    @@ -439,6 +448,7 @@ class Mailing extends CommonObject
     	 */
     	function delete_targets()
     	{
    +        // phpcs:enable
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
     		$sql.= " WHERE fk_mailing = ".$this->id;
     
    @@ -456,6 +466,7 @@ class Mailing extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Change status of each recipient
     	 *
    @@ -464,6 +475,7 @@ class Mailing extends CommonObject
     	 */
     	function reset_targets_status($user)
     	{
    +        // phpcs:enable
     		$sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles";
     		$sql.= " SET statut = 0";
     		$sql.= " WHERE fk_mailing = ".$this->id;
    @@ -516,6 +528,81 @@ class Mailing extends CommonObject
     	}
     
     
    +	/**
    +	 *  Return a link to the object card (with optionaly the picto)
    +	 *
    +	 *	@param	int		$withpicto					Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
    +	 *	@param	string	$option						On what the link point to ('nolink', ...)
    +	 *  @param	int  	$notooltip					1=Disable tooltip
    +	 *  @param  string  $morecss            		Add more css on link
    +	 *  @param  int     $save_lastsearch_value    	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
    +	 *	@return	string								String with URL
    +	 */
    +	function getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
    +	{
    +		global $db, $conf, $langs, $hookmanager;
    +		global $dolibarr_main_authentication, $dolibarr_main_demo;
    +		global $menumanager;
    +
    +		if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
    +
    +		$result = '';
    +		$companylink = '';
    +
    +		$label = '<u>' . $langs->trans("ShowEmailing") . '</u>';
    +		$label.= '<br>';
    +		$label.= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
    +
    +		$url = DOL_URL_ROOT.'/comm/mailing/card.php?id='.$this->id;
    +
    +		if ($option != 'nolink')
    +		{
    +			// Add param to save lastsearch_values or not
    +			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
    +			if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
    +			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
    +		}
    +
    +		$linkclose='';
    +		if (empty($notooltip))
    +		{
    +			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
    +			{
    +				$label=$langs->trans("ShowEmailing");
    +				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
    +			}
    +			$linkclose.=' title="'.dol_escape_htmltag($label, 1).'"';
    +			$linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
    +
    +			/*
    +			 $hookmanager->initHooks(array('myobjectdao'));
    +			 $parameters=array('id'=>$this->id);
    +			 $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +			 if ($reshook > 0) $linkclose = $hookmanager->resPrint;
    +			 */
    +		}
    +		else $linkclose = ($morecss?' class="'.$morecss.'"':'');
    +
    +		$linkstart = '<a href="'.$url.'"';
    +		$linkstart.=$linkclose.'>';
    +		$linkend='</a>';
    +
    +		$result .= $linkstart;
    +		if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
    +		if ($withpicto != 2) $result.= $this->ref;
    +		$result .= $linkend;
    +		//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
    +
    +		global $action;
    +		$hookmanager->initHooks(array('emailingdao'));
    +		$parameters=array('id'=>$this->id, 'getnomurl'=>$result);
    +		$reshook=$hookmanager->executeHooks('getNomUrl',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +		if ($reshook > 0) $result = $hookmanager->resPrint;
    +		else $result .= $hookmanager->resPrint;
    +
    +		return $result;
    +	}
    +
     	/**
     	 *  Return label of status of emailing (draft, validated, ...)
     	 *
    @@ -527,6 +614,7 @@ class Mailing extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -536,39 +624,36 @@ class Mailing extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('mails');
     
    -		if ($mode == 0)
    +		if ($mode == 0 || $mode == 1)
     		{
     			return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 1)
    -		{
    -			return $langs->trans($this->statuts[$statut]);
    -		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut == 0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut == 1) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut == 2) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut == 3) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut == 0) return img_picto($langs->trans($this->statuts[$statut]),'statut0');
     			if ($statut == 1) return img_picto($langs->trans($this->statuts[$statut]),'statut1');
     			if ($statut == 2) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
     			if ($statut == 3) return img_picto($langs->trans($this->statuts[$statut]),'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut == 0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut == 1) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut == 2) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut == 3) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut == 0)  return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut0');
     			if ($statut == 1)  return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut1');
    @@ -596,39 +681,39 @@ class Mailing extends CommonObject
     		{
     			return $langs->trans('MailingStatusError');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $langs->trans('MailingStatusSent');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc);
     			if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6');
     			if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4');
     			if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc);
     			if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6');
     			if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4');
     			if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc);
     			if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6');
     			if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4');
     			if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     		    if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc);
     		    if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6');
     		    if ($statut==2) return $langs->trans("MailingStatusRead").' '.img_picto($langs->trans("MailingStatusRead"),'statut4');
     		    if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     		    if ($statut==-1) return $langs->trans("MailingStatusError").' '.img_error($desc);
     		    if ($statut==1) return $langs->trans("MailingStatusSent").' '.img_picto($langs->trans("MailingStatusSent"),'statut6');
    @@ -636,6 +721,4 @@ class Mailing extends CommonObject
     		    if ($statut==3) return $langs->trans("MailingStatusNotContact").' '.img_picto($langs->trans("MailingStatusNotContact"),'statut3');
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/comm/mailing/index.php b/htdocs/comm/mailing/index.php
    index 17693a1a73c..f1745b406fd 100644
    --- a/htdocs/comm/mailing/index.php
    +++ b/htdocs/comm/mailing/index.php
    @@ -182,7 +182,6 @@ if ($result)
           print '</tr>';
     	  $i++;
     	}
    -
         }
       else
         {
    @@ -210,7 +209,6 @@ if ($langs->file_exists("html/spam.html",0)) {
         print '<br>';
      }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/mailing/info.php b/htdocs/comm/mailing/info.php
    index b4f2eaeb6f3..3c1e6e2cffa 100644
    --- a/htdocs/comm/mailing/info.php
    +++ b/htdocs/comm/mailing/info.php
    @@ -75,5 +75,6 @@ if ($object->fetch($id) >= 0)
     	dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php
    index 87a390d4006..133a354723f 100644
    --- a/htdocs/comm/mailing/list.php
    +++ b/htdocs/comm/mailing/list.php
    @@ -35,15 +35,15 @@ $sortfield = GETPOST("sortfield",'alpha');
     $sortorder = GETPOST("sortorder",'alpha');
     $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
     $page = GETPOST("page",'int');
    -if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
    +if (empty($page) || $page == -1 || GETPOST('button_search','alpha') || GETPOST('button_removefilter','alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; }     // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
     $offset = $limit * $page;
     $pageprev = $page - 1;
     $pagenext = $page + 1;
     if (! $sortorder) $sortorder="DESC";
     if (! $sortfield) $sortfield="m.date_creat";
     
    -$sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));
    -$sref=GETPOST("sref", "alpha");
    +$search_all=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));
    +$search_ref=GETPOST("search_ref", "alpha") ? GETPOST("search_ref", "alpha") : GETPOST("sref", "alpha");
     $filteremail=GETPOST('filteremail','alpha');
     
     // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    @@ -59,6 +59,53 @@ $fieldstosearchall = array(
         'm.titre'=>'Ref',
     );
     
    +$object = new Mailing($db);
    +
    +
    +
    +/*
    + * Actions
    + */
    +
    +if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; }
    +if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
    +
    +$parameters=array();
    +$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))
    +{
    +	// Selection of new fields
    +	include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
    +
    +	// Purge search criteria
    +	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
    +	{
    +		/*foreach($object->fields as $key => $val)
    +		{
    +			$search[$key]='';
    +		}*/
    +		$search_ref = '';
    +		$search_all = '';
    +		$toselect='';
    +		$search_array_options=array();
    +	}
    +	if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')
    +		|| GETPOST('button_search_x','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search','alpha'))
    +	{
    +		$massaction='';     // Protection to avoid mass action if we force a new search during a mass action confirmation
    +	}
    +
    +	// Mass actions
    +	/*$objectclass='MyObject';
    +	$objectlabel='MyObject';
    +	$permtoread = $user->rights->mymodule->read;
    +	$permtodelete = $user->rights->mymodule->delete;
    +	$uploaddir = $conf->mymodule->dir_output;
    +	include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
    +	*/
    +}
     
     
     /*
    @@ -76,8 +123,8 @@ if ($filteremail)
     	$sql.= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc";
     	$sql.= " WHERE m.rowid = mc.fk_mailing AND m.entity = ".$conf->entity;
     	$sql.= " AND mc.email = '".$db->escape($filteremail)."'";
    -	if ($sref) $sql.= " AND m.rowid = '".$db->escape($sref)."'";
    -	if ($sall) $sql.= " AND (m.titre like '%".$db->escape($sall)."%' OR m.sujet like '%".$db->escape($sall)."%' OR m.body like '%".$db->escape($sall)."%')";
    +	if ($search_ref) $sql.= " AND m.rowid = '".$db->escape($search_ref)."'";
    +	if ($search_all) $sql.= " AND (m.titre like '%".$db->escape($search_all)."%' OR m.sujet like '%".$db->escape($search_all)."%' OR m.body like '%".$db->escape($search_all)."%')";
     	if (! $sortorder) $sortorder="ASC";
     	if (! $sortfield) $sortfield="m.rowid";
     	$sql.= $db->order($sortfield,$sortorder);
    @@ -88,8 +135,8 @@ else
     	$sql = "SELECT m.rowid, m.titre, m.nbemail, m.statut, m.date_creat as datec, m.date_envoi as date_envoi";
     	$sql.= " FROM ".MAIN_DB_PREFIX."mailing as m";
     	$sql.= " WHERE m.entity = ".$conf->entity;
    -	if ($sref) $sql.= " AND m.rowid = '".$db->escape($sref)."'";
    -	if ($sall) $sql.= " AND (m.titre like '%".$db->escape($sall)."%' OR m.sujet like '%".$db->escape($sall)."%' OR m.body like '%".$db->escape($sall)."%')";
    +	if ($search_ref) $sql.= " AND m.rowid = '".$db->escape($search_ref)."'";
    +	if ($search_all) $sql.= " AND (m.titre like '%".$db->escape($search_all)."%' OR m.sujet like '%".$db->escape($search_all)."%' OR m.body like '%".$db->escape($search_all)."%')";
     	if (! $sortorder) $sortorder="ASC";
     	if (! $sortfield) $sortfield="m.rowid";
     	$sql.= $db->order($sortfield,$sortorder);
    @@ -115,7 +162,7 @@ if ($result)
     
     	$i = 0;
     
    -	$param = "&sall=".urlencode($sall);
    +	$param = "&search_all=".urlencode($search_all);
     	if ($filteremail) $param.='&filteremail='.urlencode($filteremail);
     
     	print '<form method="GET" action="'.$_SERVER["PHP_SELF"].'">';
    @@ -135,11 +182,11 @@ if ($result)
     
     	print '<tr class="liste_titre_filter">';
     	print '<td class="liste_titre">';
    -	print '<input type="text" class="flat maxwidth50" name="sref" value="'.dol_escape_htmltag($sref).'">';
    +	print '<input type="text" class="flat maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
     	print '</td>';
     	// Title
     	print '<td class="liste_titre">';
    -	print '<input type="text" class="flat maxwidth100 maxwidth50onsmartphone" name="sall" value="'.dol_escape_htmltag($sall).'">';
    +	print '<input type="text" class="flat maxwidth100 maxwidth50onsmartphone" name="search_all" value="'.dol_escape_htmltag($search_all).'">';
     	print '</td>';
     	print '<td class="liste_titre">&nbsp;</td>';
     	if (! $filteremail) print '<td class="liste_titre">&nbsp;</td>';
    @@ -169,16 +216,22 @@ if ($result)
     	{
     		$obj = $db->fetch_object($result);
     
    -
    +		$email->id = $obj->rowid;
    +		$email->ref = $obj->rowid;
     
     		print "<tr>";
    -		print '<td><a href="'.DOL_URL_ROOT.'/comm/mailing/card.php?id='.$obj->rowid.'">';
    -		print img_object($langs->trans("ShowEMail"),"email").' '.stripslashes($obj->rowid).'</a></td>';
    +
    +		print '<td>';
    +		print $email->getNomUrl(1);
    +		print '</td>';
    +
     		print '<td>'.$obj->titre.'</td>';
     		// Date creation
    +
     		print '<td align="center">';
     		print dol_print_date($db->jdate($obj->datec),'day');
     		print '</td>';
    +
     		// Nb of email
     		if (! $filteremail)
     		{
    @@ -196,9 +249,11 @@ if ($result)
     			print $nbemail;
     			print '</td>';
     		}
    +
     		// Last send
     		print '<td align="center" class="nowrap">'.dol_print_date($db->jdate($obj->date_envoi),'day').'</td>';
     		print '</td>';
    +
     		// Status
     		print '<td align="right" class="nowrap">';
     		if ($filteremail)
    @@ -210,7 +265,9 @@ if ($result)
     			print $email->LibStatut($obj->statut,5);
     		}
     		print '</td>';
    +
     		print '<td></td>';
    +
     		print "</tr>\n";
     		$i++;
     	}
    @@ -224,6 +281,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/multiprix.php b/htdocs/comm/multiprix.php
    index 1e8c5c82cf4..7bbf727a517 100644
    --- a/htdocs/comm/multiprix.php
    +++ b/htdocs/comm/multiprix.php
    @@ -45,7 +45,7 @@ if ($user->societe_id > 0)
     
     if ($_POST["action"] == 'setpricelevel')
     {
    -	$soc = New Societe($db);
    +	$soc = new Societe($db);
     	$soc->fetch($id);
     	$soc->set_price_level($_POST["price_level"],$user);
     
    @@ -174,8 +174,8 @@ if ($_socid > 0)
     	{
     		dol_print_error($db);
     	}
    -
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
    index 879fcc3f5e2..f07a5cdfac8 100644
    --- a/htdocs/comm/propal/card.php
    +++ b/htdocs/comm/propal/card.php
    @@ -1,17 +1,18 @@
     <?php
    -/* Copyright (C) 2001-2007 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    +/* Copyright (C) 2001-2007  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2014 Laurent Destailleur   <eldy@users.sourceforge.net>
      * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
      * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
      * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
      * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
      * Copyright (C) 2010-2016 Juanjo Menent         <jmenent@2byte.es>
    - * Copyright (C) 2010-2015 Philippe Grand        <philippe.grand@atoo-net.com>
    + * Copyright (C) 2010-2018 Philippe Grand        <philippe.grand@atoo-net.com>
      * Copyright (C) 2012-2013 Christophe Battarel   <christophe.battarel@altairis.fr>
      * Copyright (C) 2012      Cedric Salvador       <csalvador@gpcsolutions.fr>
      * Copyright (C) 2013-2014 Florian Henry		 <florian.henry@open-concept.pro>
      * Copyright (C) 2014	   Ferran Marcet		 <fmarcet@2byte.es>
      * Copyright (C) 2016      Marcos García         <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -347,13 +348,13 @@ if (empty($reshook))
     			// If we select proposal to clone during creation (when option PROPAL_CLONE_ON_CREATE_PAGE is on)
     			if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal'))
     			{
    -				if ($object->fetch(GETPOST('copie_propal')) > 0) {
    +				if ($object->fetch(GETPOST('copie_propal','int')) > 0) {
     					$object->ref = GETPOST('ref');
     					$object->datep = $datep;
     					$object->date_livraison = $date_delivery;
     					$object->availability_id = GETPOST('availability_id');
     					$object->demand_reason_id = GETPOST('demand_reason_id');
    -					$object->fk_delivery_address = GETPOST('fk_address');
    +					$object->fk_delivery_address = GETPOST('fk_address','int');
     					$object->shipping_method_id = GETPOST('shipping_method_id', 'int');
     					$object->duree_validite = $duration;
     					$object->cond_reglement_id = GETPOST('cond_reglement_id');
    @@ -361,9 +362,9 @@ if (empty($reshook))
     					$object->fk_account = GETPOST('fk_account', 'int');
     					$object->remise_percent = GETPOST('remise_percent');
     					$object->remise_absolue = GETPOST('remise_absolue');
    -					$object->socid = GETPOST('socid');
    -					$object->contactid = GETPOST('contactid');
    -					$object->fk_project = GETPOST('projectid');
    +					$object->socid = GETPOST('socid','int');
    +					$object->contactid = GETPOST('contactid','int');
    +					$object->fk_project = GETPOST('projectid','int');
     					$object->modelpdf = GETPOST('model');
     					$object->author = $user->id; // deprecated
     					$object->note_private = GETPOST('note_private','none');
    @@ -390,8 +391,8 @@ if (empty($reshook))
     				$object->cond_reglement_id = GETPOST('cond_reglement_id');
     				$object->mode_reglement_id = GETPOST('mode_reglement_id');
     				$object->fk_account = GETPOST('fk_account', 'int');
    -				$object->contactid = GETPOST('contactid');
    -				$object->fk_project = GETPOST('projectid');
    +				$object->contactid = GETPOST('contactid','int');
    +				$object->fk_project = GETPOST('projectid','int');
     				$object->modelpdf = GETPOST('model');
     				$object->author = $user->id; // deprecated
     				$object->note_private = GETPOST('note_private','none');
    @@ -565,6 +566,16 @@ if (empty($reshook))
     						}
     					}
     
    +					if (! empty($conf->global->PROPOSAL_AUTO_ADD_AUTHOR_AS_CONTACT))
    +					{
    +						$result = $object->add_contact($user->id, 'SALESREPFOLL', 'internal');
    +						if ($result < 0)
    +						{
    +							$error++;
    +							setEventMessages($langs->trans("ErrorFailedToAddUserAsContact"), null, 'errors');
    +						}
    +					}
    +
     					if (! $error)
     					{
     						$db->commit();
    @@ -783,7 +794,7 @@ if (empty($reshook))
     				if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
     					$idprod = $res->fk_product_child;
     				} else {
    -					setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors');
    +					setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
     					$error ++;
     				}
     			}
    @@ -1026,7 +1037,7 @@ if (empty($reshook))
     			if ($tva_npr)
     				$info_bits |= 0x01;
     
    -			if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) ) && (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
     				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
     				setEventMessages($mesg, null, 'errors');
     			} else {
    @@ -1090,7 +1101,7 @@ if (empty($reshook))
     	}
     
     	// Update a line within proposal
    -	else if ($action == 'updateligne' && $usercancreate && GETPOST('save'))
    +	else if ($action == 'updateline' && $usercancreate && GETPOST('save'))
     	{
     		// Define info_bits
     		$info_bits = 0;
    @@ -1145,8 +1156,7 @@ if (empty($reshook))
     				$price_min = $product->multiprices_min [$object->thirdparty->price_level];
     
     			$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
    -
    -			if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
     				setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
     				$error ++;
     			}
    @@ -1227,7 +1237,7 @@ if (empty($reshook))
     		}
     	}
     
    -	else if ($action == 'updateligne' && $usercancreate && GETPOST('cancel','alpha'))
    +	else if ($action == 'updateline' && $usercancreate && GETPOST('cancel','alpha'))
     	{
     		header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
     		exit();
    @@ -1354,7 +1364,6 @@ if (empty($reshook))
     	$upload_dir = $conf->propal->multidir_output[$object->entity];
     	$permissioncreate=$usercancreate;
     	include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
    -
     }
     
     
    @@ -1529,7 +1538,7 @@ if ($action == 'create')
     
     	// Date
     	print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td>';
    -	$form->select_date('', '', '', '', '', "addprop", 1, 1);
    +	print $form->selectDate('', '', '', '', '', "addprop", 1, 1);
     	print '</td></tr>';
     
     	// Validaty duration
    @@ -1577,9 +1586,9 @@ if ($action == 'create')
     		$syear = date("Y", $tmpdte);
     		$smonth = date("m", $tmpdte);
     		$sday = date("d", $tmpdte);
    -		$form->select_date($syear."-".$smonth."-".$sday, 'date_livraison', '', '', '', "addprop");
    +		print $form->selectDate($syear."-".$smonth."-".$sday, 'date_livraison', '', '', '', "addprop");
     	} else {
    -		$form->select_date(-1, 'date_livraison', '', '', '', "addprop", 1, 1);
    +		print $form->selectDate(-1, 'date_livraison', '', '', '', "addprop", 1, 1);
     	}
     	print '</td></tr>';
     
    @@ -1767,7 +1776,6 @@ if ($action == 'create')
     
     		print '</table>';
     	}
    -
     } elseif ($object->id > 0) {
     	/*
     	 * Show object in view mode
    @@ -1815,7 +1823,6 @@ if ($action == 'create')
     		}
     
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('SetAcceptedRefused'), $text, 'setstatut', $formquestion, '', 1, 250);
    -
     	}
     
     	// Confirm delete
    @@ -1861,12 +1868,11 @@ if ($action == 'create')
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate', '', 0, 1);
     	}
     
    -	if (! $formconfirm) {
    -		$parameters = array('lineid' => $lineid);
    -		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    @@ -1964,7 +1970,7 @@ if ($action == 'create')
     		print '<form name="editdate" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
     		print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
     		print '<input type="hidden" name="action" value="setdate">';
    -		$form->select_date($object->date, 're', '', '', 0, "editdate");
    +		print $form->selectDate($object->date, 're', '', '', 0, "editdate");
     		print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     		print '</form>';
     	} else {
    @@ -1990,7 +1996,7 @@ if ($action == 'create')
     		print '<form name="editecheance" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
     		print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
     		print '<input type="hidden" name="action" value="setecheance">';
    -		$form->select_date($object->fin_validite, 'ech', '', '', '', "editecheance");
    +		print $form->selectDate($object->fin_validite, 'ech', '', '', '', "editecheance");
     		print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     		print '</form>';
     	} else {
    @@ -2318,7 +2324,7 @@ if ($action == 'create')
     
     	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#addline' : '#line_' . GETPOST('lineid')) . '" method="POST">
     	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
    -	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
    +	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
     	<input type="hidden" name="mode" value="">
     	<input type="hidden" name="id" value="' . $object->id . '">
     	';
    diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php
    index 39857d88365..a03624f3122 100644
    --- a/htdocs/comm/propal/class/api_proposals.class.php
    +++ b/htdocs/comm/propal/class/api_proposals.class.php
    @@ -97,7 +97,8 @@ class Proposals extends DolibarrApi
     	 * @param string    $sqlfilters         Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')"
     	 * @return  array                       Array of order objects
     	 */
    -	function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
     		global $db, $conf;
     
     		$obj_ret = array();
    @@ -215,7 +216,8 @@ class Proposals extends DolibarrApi
     	 *
     	 * @return int
     	 */
    -	function getLines($id) {
    +    function getLines($id)
    +    {
     	  if(! DolibarrApiAccess::$user->rights->propal->lire) {
     		  	throw new RestException(401);
     		  }
    @@ -381,7 +383,8 @@ class Proposals extends DolibarrApi
          * @throws 401
          * @throws 404
     	 */
    -	function deleteLine($id, $lineid) {
    +    function deleteLine($id, $lineid)
    +    {
     		if(! DolibarrApiAccess::$user->rights->propal->creer) {
     		  	throw new RestException(401);
     		}
    @@ -415,7 +418,8 @@ class Proposals extends DolibarrApi
     	 *
     	 * @return int
     	 */
    -	function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
     	  if(! DolibarrApiAccess::$user->rights->propal->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -487,7 +491,6 @@ class Proposals extends DolibarrApi
     				'message' => 'Commercial Proposal deleted'
     			)
     		);
    -
     	}
     
     	/**
    @@ -697,29 +700,29 @@ class Proposals extends DolibarrApi
     			if (!isset($data[$field]))
     				throw new RestException(400, "$field field missing");
     			$propal[$field] = $data[$field];
    -
     		}
     		return $propal;
     	}
     
     
    -	/**
    -	 * Clean sensible object datas
    -	 *
    -	 * @param   object  $object    Object to clean
    -	 * @return    array    Array of cleaned object properties
    -	 */
    -	function _cleanObjectDatas($object) {
    +    /**
    +     * Clean sensible object datas
    +     *
    +     * @param   object  $object    Object to clean
    +     * @return    array    Array of cleaned object properties
    +     */
    +    function _cleanObjectDatas($object)
    +    {
     
    -		$object = parent::_cleanObjectDatas($object);
    +        $object = parent::_cleanObjectDatas($object);
     
    -        	unset($object->note);
    -		unset($object->name);
    -		unset($object->lastname);
    -		unset($object->firstname);
    -		unset($object->civility_id);
    -		unset($object->address);
    +        unset($object->note);
    +        unset($object->name);
    +        unset($object->lastname);
    +        unset($object->firstname);
    +        unset($object->civility_id);
    +        unset($object->address);
     
    -		return $object;
    -	}
    +        return $object;
    +    }
     }
    diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php
    index e68b18ae820..e11f62bb446 100644
    --- a/htdocs/comm/propal/class/propal.class.php
    +++ b/htdocs/comm/propal/class/propal.class.php
    @@ -46,16 +46,37 @@ require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php';
      */
     class Propal extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='propal';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='propal';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line='propaldet';
    -	public $fk_element='fk_propal';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element ='fk_propal';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='propal';
    +
     	/**
     	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 * @var int
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
     	 * @var integer
    @@ -147,7 +168,12 @@ class Propal extends CommonObject
     	public $remise = 0;
     	public $remise_percent = 0;
     	public $remise_absolue = 0;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_address;
    +
     	public $address_type;
     	public $address;
     	public $availability_id;
    @@ -170,7 +196,11 @@ class Propal extends CommonObject
     	public $specimen;
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     	public $multicurrency_tx;
     	public $multicurrency_total_ht;
    @@ -223,9 +253,10 @@ class Propal extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 * 	Add line into array products
    -	 *	$this->thirdparty should be loaded
    +	 *  Add line into array products
    +	 *  $this->thirdparty should be loaded
     	 *
     	 * 	@param  int		$idproduct       	Product Id to add
     	 * 	@param  int		$qty             	Quantity
    @@ -237,6 +268,7 @@ class Propal extends CommonObject
     	 */
     	function add_product($idproduct, $qty, $remise_percent=0)
     	{
    +        // phpcs:enable
     		global $conf, $mysoc;
     
     		if (! $qty) $qty = 1;
    @@ -283,6 +315,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Adding line of fixed discount in the proposal in DB
     	 *
    @@ -291,6 +324,7 @@ class Propal extends CommonObject
     	 */
     	function insert_discount($idremise)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    @@ -1155,6 +1189,7 @@ class Propal extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Insert into DB a proposal object completely defined by its data members (ex, results from copy).
     	 *
    @@ -1164,6 +1199,7 @@ class Propal extends CommonObject
     	 */
     	function create_from($user)
     	{
    +        // phpcs:enable
     		// i love this function because $this->products is not used in create function...
     		$this->products=$this->lines;
     
    @@ -1546,6 +1582,7 @@ class Propal extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load array lines
     	 *
    @@ -1554,15 +1591,16 @@ class Propal extends CommonObject
     	 */
     	function fetch_lines($only_product=0)
     	{
    +        // phpcs:enable
     		$this->lines=array();
     
     		$sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,';
     		$sql.= ' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,';
     		$sql.= ' d.fk_unit,';
    -		$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,';
    +		$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_batch,';
     		$sql.= ' p.weight, p.weight_units, p.volume, p.volume_units,';
    -		$sql.= ' d.date_start, d.date_end';
    -		$sql.= ' ,d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
    +		$sql.= ' d.date_start, d.date_end,';
    +		$sql.= ' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
     		$sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as d';
     		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (d.fk_product = p.rowid)';
     		$sql.= ' WHERE d.fk_propal = '.$this->id;
    @@ -1591,6 +1629,7 @@ class Propal extends CommonObject
     				$line->product_type     = $objp->product_type;
     				$line->label            = $objp->custom_label;
     				$line->desc             = $objp->description;  // Description ligne
    +				$line->description      = $objp->description;  // Description ligne
     				$line->qty              = $objp->qty;
     				$line->vat_src_code     = $objp->vat_src_code;
     				$line->tva_tx           = $objp->tva_tx;
    @@ -1624,7 +1663,8 @@ class Propal extends CommonObject
     				$line->libelle			= $objp->product_label;		// TODO deprecated
     				$line->product_label	= $objp->product_label;
     				$line->product_desc     = $objp->product_desc; 		// Description produit
    -				$line->fk_product_type  = $objp->fk_product_type;
    +				$line->product_tobatch  = $objp->product_tobatch;
    +				$line->fk_product_type  = $objp->fk_product_type;	// TODO deprecated
     				$line->fk_unit          = $objp->fk_unit;
     				$line->weight = $objp->weight;
     				$line->weight_units = $objp->weight_units;
    @@ -1783,6 +1823,7 @@ class Propal extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Define proposal date
     	 *
    @@ -1793,6 +1834,7 @@ class Propal extends CommonObject
     	 */
     	function set_date($user, $date, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (empty($date))
     		{
     			$this->error='ErrorBadParameter';
    @@ -1850,6 +1892,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define end validity date
     	 *
    @@ -1860,6 +1903,7 @@ class Propal extends CommonObject
     	 */
     	function set_echeance($user, $date_fin_validite, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (! empty($user->rights->propal->creer))
     		{
     			$error=0;
    @@ -1910,6 +1954,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set delivery date
     	 *
    @@ -1920,6 +1965,7 @@ class Propal extends CommonObject
     	 */
     	function set_date_livraison($user, $date_livraison, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (! empty($user->rights->propal->creer))
     		{
     			$error=0;
    @@ -1970,6 +2016,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Set delivery
     	 *
    @@ -1980,6 +2027,7 @@ class Propal extends CommonObject
     	 */
     	function set_availability($user, $id, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT)
     		{
     			$error=0;
    @@ -2039,6 +2087,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Set source of demand
     	 *
    @@ -2049,6 +2098,7 @@ class Propal extends CommonObject
     	 */
     	function set_demand_reason($user, $id, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (! empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT)
     		{
     			$error=0;
    @@ -2110,6 +2160,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set customer reference number
     	 *
    @@ -2120,6 +2171,7 @@ class Propal extends CommonObject
     	 */
     	function set_ref_client($user, $ref_client, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (! empty($user->rights->propal->creer))
     		{
     			$error=0;
    @@ -2173,6 +2225,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set an overall discount on the proposal
     	 *
    @@ -2183,6 +2236,7 @@ class Propal extends CommonObject
     	 */
     	function set_remise_percent($user, $remise, $notrigger=0)
     	{
    +        // phpcs:enable
     		$remise=trim($remise)?trim($remise):0;
     
     		if (! empty($user->rights->propal->creer))
    @@ -2238,6 +2292,7 @@ class Propal extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set an absolute overall discount on the proposal
     	 *
    @@ -2248,6 +2303,7 @@ class Propal extends CommonObject
     	 */
     	function set_remise_absolue($user, $remise, $notrigger=0)
     	{
    +        // phpcs:enable
     		$remise=trim($remise)?trim($remise):0;
     
     		if (! empty($user->rights->propal->creer))
    @@ -2526,6 +2582,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set draft status
     	 *
    @@ -2535,6 +2592,7 @@ class Propal extends CommonObject
     	 */
     	function set_draft($user, $notrigger=0)
     	{
    +        // phpcs:enable
     		$error=0;
     
     		$this->db->begin();
    @@ -2583,6 +2641,7 @@ class Propal extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return list of proposal (eventually filtered on user) into an array
     	 *
    @@ -2598,6 +2657,7 @@ class Propal extends CommonObject
     	 */
     	function liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datep', $sortorder='DESC')
     	{
    +        // phpcs:enable
     		global $user;
     
     		$ga = array();
    @@ -2669,6 +2729,7 @@ class Propal extends CommonObject
     		return $this->InvoiceArrayList($this->id);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Returns an array with id and ref of related invoices
     	 *
    @@ -2677,6 +2738,7 @@ class Propal extends CommonObject
     	 */
     	function InvoiceArrayList($id)
     	{
    +        // phpcs:enable
     		$ga = array();
     		$linkedInvoices = array();
     
    @@ -2947,6 +3009,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Change source demand
     	 *
    @@ -2957,6 +3020,7 @@ class Propal extends CommonObject
     	 */
     	function demand_reason($demand_reason_id, $notrigger=0)
     	{
    +        // phpcs:enable
     		global $user;
     
     		if ($this->statut >= self::STATUS_DRAFT)
    @@ -3063,11 +3127,8 @@ class Propal extends CommonObject
     					$cluser->fetch($obj->fk_user_cloture);
     					$this->user_cloture     = $cluser;
     				}
    -
    -
     			}
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -3087,6 +3148,7 @@ class Propal extends CommonObject
     		return $this->LibStatut($this->statut, $mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Return label of a status (draft, validated, ...)
     	 *
    @@ -3096,6 +3158,7 @@ class Propal extends CommonObject
     	 */
     	function LibStatut($statut,$mode=1)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		// Init/load array of translation of status
    @@ -3117,21 +3180,22 @@ class Propal extends CommonObject
     
     		$statuttrans='';
     		if ($statut==self::STATUS_DRAFT) $statuttrans='statut0';
    -		if ($statut==self::STATUS_VALIDATED) $statuttrans='statut1';
    -		if ($statut==self::STATUS_SIGNED) $statuttrans='statut3';
    -		if ($statut==self::STATUS_NOTSIGNED) $statuttrans='statut5';
    -		if ($statut==self::STATUS_BILLED) $statuttrans='statut6';
    +		elseif ($statut==self::STATUS_VALIDATED) $statuttrans='statut1';
    +		elseif ($statut==self::STATUS_SIGNED) $statuttrans='statut3';
    +		elseif ($statut==self::STATUS_NOTSIGNED) $statuttrans='statut5';
    +		elseif ($statut==self::STATUS_BILLED) $statuttrans='statut6';
     
     		if ($mode == 0)	return $this->labelstatut[$statut];
    -		if ($mode == 1)	return $this->labelstatut_short[$statut];
    -		if ($mode == 2)	return img_picto($this->labelstatut_short[$statut], $statuttrans).' '.$this->labelstatut_short[$statut];
    -		if ($mode == 3)	return img_picto($this->labelstatut[$statut], $statuttrans);
    -		if ($mode == 4)	return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut];
    -		if ($mode == 5)	return '<span class="hideonsmartphone">'.$this->labelstatut_short[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    -		if ($mode == 6)	return '<span class="hideonsmartphone">'.$this->labelstatut[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    -	 }
    +		elseif ($mode == 1)	return $this->labelstatut_short[$statut];
    +		elseif ($mode == 2)	return img_picto($this->labelstatut_short[$statut], $statuttrans).' '.$this->labelstatut_short[$statut];
    +		elseif ($mode == 3)	return img_picto($this->labelstatut[$statut], $statuttrans);
    +		elseif ($mode == 4)	return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut];
    +		elseif ($mode == 5)	return '<span class="hideonsmartphone">'.$this->labelstatut_short[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    +		elseif ($mode == 6)	return '<span class="hideonsmartphone">'.$this->labelstatut[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    +	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -3141,11 +3205,12 @@ class Propal extends CommonObject
     	 */
     	function load_board($user,$mode)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$clause = " WHERE";
     
    -		$sql = "SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin";
    +		$sql = "SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
     		$sql.= " FROM ".MAIN_DB_PREFIX."propal as p";
     		if (!$user->rights->societe->client->voir && !$user->societe_id)
     		{
    @@ -3189,6 +3254,8 @@ class Propal extends CommonObject
     			while ($obj=$this->db->fetch_object($resql))
     			{
     				$response->nbtodo++;
    +				$response->total+=$obj->total_ht;
    +
     				if ($mode == 'opened')
     				{
     					$datelimit = $this->db->jdate($obj->datefin);
    @@ -3304,6 +3371,7 @@ class Propal extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb de tableau de bord
     	 *
    @@ -3311,6 +3379,7 @@ class Propal extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $user;
     
     		$this->nb=array();
    @@ -3492,103 +3561,13 @@ class Propal extends CommonObject
     	}
     
     	/**
    -	 * 	Retrieve an array of propal lines
    +	 * 	Retrieve an array of proposal lines
     	 *
     	 * 	@return int		>0 if OK, <0 if KO
     	 */
     	function getLinesArray()
     	{
    -		// TODO Duplicate with fetch_lines ? Wich one to keep ?
    -
    -		$this->lines = array();
    -
    -		$sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,';
    -		$sql.= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,';
    -		$sql.= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,';
    -		$sql.= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,';
    -		$sql.= ' pt.fk_unit,';
    -		$sql.= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,';
    -		$sql.= ' p.entity,';
    -		$sql.= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc';
    -		$sql.= ' FROM '.MAIN_DB_PREFIX.'propaldet as pt';
    -		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid';
    -		$sql.= ' WHERE pt.fk_propal = '.$this->id;
    -		$sql.= ' ORDER BY pt.rang ASC, pt.rowid';
    -
    -		dol_syslog(get_class($this).'::getLinesArray', LOG_DEBUG);
    -		$resql = $this->db->query($sql);
    -		if ($resql)
    -		{
    -			$num = $this->db->num_rows($resql);
    -			$i = 0;
    -
    -			while ($i < $num)
    -			{
    -				$obj = $this->db->fetch_object($resql);
    -
    -				$this->lines[$i]					= new PropaleLigne($this->db);
    -				$this->lines[$i]->id				= $obj->rowid; // for backward compatibility
    -				$this->lines[$i]->rowid				= $obj->rowid;
    -				$this->lines[$i]->label 			= $obj->custom_label;
    -				$this->lines[$i]->desc       		= $obj->description;
    -				$this->lines[$i]->description 		= $obj->description;
    -				$this->lines[$i]->fk_product		= $obj->fk_product;
    -				$this->lines[$i]->ref				= $obj->ref;
    -				$this->lines[$i]->product_ref		= $obj->ref;
    -				$this->lines[$i]->entity            = $obj->entity;             // Product entity
    -				$this->lines[$i]->product_label		= $obj->product_label;
    -				$this->lines[$i]->product_desc		= $obj->product_desc;
    -				$this->lines[$i]->product_tobatch   = $obj->product_tobatch;
    -				$this->lines[$i]->fk_product_type	= $obj->fk_product_type;    // deprecated
    -				$this->lines[$i]->product_type		= $obj->product_type;
    -				$this->lines[$i]->qty				= $obj->qty;
    -				$this->lines[$i]->subprice			= $obj->subprice;
    -				$this->lines[$i]->fk_remise_except 	= $obj->fk_remise_except;
    -				$this->lines[$i]->remise_percent	= $obj->remise_percent;
    -
    -				$this->lines[$i]->vat_src_code      = $obj->vat_src_code;
    -				$this->lines[$i]->tva_tx			= $obj->tva_tx;
    -				$this->lines[$i]->localtax1_tx		= $obj->localtax1_tx;
    -				$this->lines[$i]->localtax2_tx		= $obj->localtax2_tx;
    -				$this->lines[$i]->localtax1_type	= $obj->localtax1_type;
    -				$this->lines[$i]->localtax2_type	= $obj->localtax2_type;
    -				$this->lines[$i]->info_bits			= $obj->info_bits;
    -				$this->lines[$i]->total_ht			= $obj->total_ht;
    -				$this->lines[$i]->total_tva			= $obj->total_tva;
    -				$this->lines[$i]->total_ttc			= $obj->total_ttc;
    -				$this->lines[$i]->total_localtax1	= $obj->total_localtax1;
    -				$this->lines[$i]->total_localtax2	= $obj->total_localtax2;
    -				$this->lines[$i]->fk_fournprice		= $obj->fk_fournprice;
    -				$marginInfos						= getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
    -				$this->lines[$i]->pa_ht				= $marginInfos[0];
    -				$this->lines[$i]->marge_tx			= $marginInfos[1];
    -				$this->lines[$i]->marque_tx			= $marginInfos[2];
    -				$this->lines[$i]->fk_parent_line	= $obj->fk_parent_line;
    -				$this->lines[$i]->special_code		= $obj->special_code;
    -				$this->lines[$i]->rang				= $obj->rang;
    -				$this->lines[$i]->date_start		= $this->db->jdate($obj->date_start);
    -				$this->lines[$i]->date_end			= $this->db->jdate($obj->date_end);
    -				$this->lines[$i]->fk_unit			= $obj->fk_unit;
    -
    -				// Multicurrency
    -				$this->lines[$i]->fk_multicurrency 			= $obj->fk_multicurrency;
    -				$this->lines[$i]->multicurrency_code 		= $obj->multicurrency_code;
    -				$this->lines[$i]->multicurrency_subprice 	= $obj->multicurrency_subprice;
    -				$this->lines[$i]->multicurrency_total_ht 	= $obj->multicurrency_total_ht;
    -				$this->lines[$i]->multicurrency_total_tva 	= $obj->multicurrency_total_tva;
    -				$this->lines[$i]->multicurrency_total_ttc 	= $obj->multicurrency_total_ttc;
    -
    -				$i++;
    -			}
    -			$this->db->free($resql);
    -
    -			return 1;
    -		}
    -		else
    -		{
    -			$this->error=$this->db->error();
    -			return -1;
    -		}
    +		return $this->fetch_lines();
     	}
     
     	/**
    @@ -3648,7 +3627,14 @@ class Propal extends CommonObject
      */
     class PropaleLigne extends CommonObjectLine
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='propaldet';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='propaldet';
     
     	var $oldline;
    @@ -4183,6 +4169,7 @@ class PropaleLigne extends CommonObjectLine
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Update DB line fields total_xxx
     	 *	Used by migration
    @@ -4191,6 +4178,7 @@ class PropaleLigne extends CommonObjectLine
     	 */
     	function update_total()
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		// Mise a jour ligne en base
    @@ -4215,6 +4203,4 @@ class PropaleLigne extends CommonObjectLine
     			return -2;
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php
    index d6e9ee3b103..bb4e0ab56f4 100644
    --- a/htdocs/comm/propal/class/propalestats.class.php
    +++ b/htdocs/comm/propal/class/propalestats.class.php
    @@ -35,7 +35,10 @@ include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
      */
     class PropaleStats extends Stats
     {
    -    public $table_element;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element;
     
         var $socid;
         var $userid;
    diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php
    index 5e21f493c64..4e017ff13d9 100644
    --- a/htdocs/comm/propal/contact.php
    +++ b/htdocs/comm/propal/contact.php
    @@ -212,6 +212,6 @@ if ($object->id > 0)
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/propal/document.php b/htdocs/comm/propal/document.php
    index 1c8d494214d..cbdfd44383c 100644
    --- a/htdocs/comm/propal/document.php
    +++ b/htdocs/comm/propal/document.php
    @@ -94,7 +94,7 @@ if ($object->id > 0)
     	$head = propal_prepare_head($object);
     	dol_fiche_head($head, 'document', $langs->trans('Proposal'), -1, 'propal');
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -179,5 +179,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/propal/index.php b/htdocs/comm/propal/index.php
    index 0dbe2fb855e..b47a4506412 100644
    --- a/htdocs/comm/propal/index.php
    +++ b/htdocs/comm/propal/index.php
    @@ -530,7 +530,6 @@ if (! empty($conf->propal->enabled))
     //print '</td></tr></table>';
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/propal/info.php b/htdocs/comm/propal/info.php
    index 317c9902d52..7879612b099 100644
    --- a/htdocs/comm/propal/info.php
    +++ b/htdocs/comm/propal/info.php
    @@ -127,5 +127,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php
    index 980615828a5..b0cc04702db 100644
    --- a/htdocs/comm/propal/list.php
    +++ b/htdocs/comm/propal/list.php
    @@ -161,6 +161,7 @@ $arrayfields=array(
     	'p.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0),
     	'p.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0),
     	'u.login'=>array('label'=>$langs->trans("Author"), 'checked'=>1, 'position'=>10),
    +	'sale_representative'=>array('label'=>$langs->trans("SaleRepresentativesOfThirdParty"), 'checked'=>1),
     	'p.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
     	'p.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
     	'p.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
    @@ -226,7 +227,6 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     	$toselect='';
     	$search_array_options=array();
     	$search_categ_cus=0;
    -
     }
     if ($object_statut != '') $viewstatut=$object_statut;
     
    @@ -669,6 +669,10 @@ if ($resql)
     		print '<input class="flat" size="4" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'">';
     		print '</td>';
     	}
    +	if (! empty($arrayfields['sale_representative']['checked']))
    +	{
    +		print '<td class="liste_titre"></td>';
    +	}
     	// Extra fields
     	include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
     
    @@ -723,6 +727,7 @@ if ($resql)
     	if (! empty($arrayfields['p.total_vat']['checked']))      print_liste_field_titre($arrayfields['p.total_vat']['label'],$_SERVER["PHP_SELF"],'p.tva','',$param, 'align="right"',$sortfield,$sortorder);
     	if (! empty($arrayfields['p.total_ttc']['checked']))      print_liste_field_titre($arrayfields['p.total_ttc']['label'],$_SERVER["PHP_SELF"],'p.total','',$param, 'align="right"',$sortfield,$sortorder);
     	if (! empty($arrayfields['u.login']['checked']))       	  print_liste_field_titre($arrayfields['u.login']['label'],$_SERVER["PHP_SELF"],'u.login','',$param,'align="center"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['sale_representative']['checked'])) print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "","","$param",'',$sortfield,$sortorder);
     	// Extra fields
     	include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
     	// Hook fields
    @@ -945,6 +950,51 @@ if ($resql)
     			if (! $i) $totalarray['nbfield']++;
     		}
     
    +		if (! empty($arrayfields['sale_representative']['checked']))
    +		{
    +			// Sales representatives
    +			print '<td>';
    +			if ($obj->socid > 0)
    +			{
    +				$listsalesrepresentatives=$companystatic->getSalesRepresentatives($user);
    +				if ($listsalesrepresentatives < 0) dol_print_error($db);
    +				$nbofsalesrepresentative=count($listsalesrepresentatives);
    +				if ($nbofsalesrepresentative > 3)   // We print only number
    +				{
    +					print '<a href="'.DOL_URL_ROOT.'/societe/commerciaux.php?socid='.$companystatic->id.'">';
    +					print $nbofsalesrepresentative;
    +					print '</a>';
    +				}
    +				else if ($nbofsalesrepresentative > 0)
    +				{
    +					$userstatic=new User($db);
    +					$j=0;
    +					foreach($listsalesrepresentatives as $val)
    +					{
    +						$userstatic->id=$val['id'];
    +						$userstatic->lastname=$val['lastname'];
    +						$userstatic->firstname=$val['firstname'];
    +						$userstatic->email=$val['email'];
    +						$userstatic->statut=$val['statut'];
    +						$userstatic->entity=$val['entity'];
    +						$userstatic->photo=$val['photo'];
    +
    +						//print '<div class="float">':
    +						print $userstatic->getNomUrl(-2);
    +						$j++;
    +						if ($j < $nbofsalesrepresentative) print ' ';
    +						//print '</div>';
    +					}
    +				}
    +				//else print $langs->trans("NoSalesRepresentativeAffected");
    +			}
    +			else
    +			{
    +				print '&nbsp';
    +			}
    +			print '</td>';
    +		}
    +
     		// Extra fields
     		include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
     		// Fields from hook
    @@ -995,22 +1045,35 @@ if ($resql)
      	   || isset($totalarray['totalttcfield'])
      	   || isset($totalarray['totalamfield'])
      	   || isset($totalarray['totalrtpfield'])
    + 	   || isset($totalarray['totalizable'])
      	   )
     	{
     		print '<tr class="liste_total">';
     		$i=0;
     		while ($i < $totalarray['nbfield'])
     		{
    -		   $i++;
    -		   if ($i == 1)
    -		   {
    +		    $i++;
    +		    if ($i == 1)
    +		    {
     				if ($num < $limit && empty($offset)) print '<td align="left">'.$langs->trans("Total").'</td>';
     				else print '<td align="left">'.$langs->trans("Totalforthispage").'</td>';
    -		   }
    -		   elseif ($totalarray['totalhtfield'] == $i) print '<td align="right">'.price($totalarray['totalht']).'</td>';
    -		   elseif ($totalarray['totalvatfield'] == $i) print '<td align="right">'.price($totalarray['totalvat']).'</td>';
    -		   elseif ($totalarray['totalttcfield'] == $i) print '<td align="right">'.price($totalarray['totalttc']).'</td>';
    -		   else print '<td></td>';
    +		    }
    +		    elseif ($totalarray['totalhtfield'] == $i) print '<td align="right">'.price($totalarray['totalht']).'</td>';
    +		    elseif ($totalarray['totalvatfield'] == $i) print '<td align="right">'.price($totalarray['totalvat']).'</td>';
    +		    elseif ($totalarray['totalttcfield'] == $i) print '<td align="right">'.price($totalarray['totalttc']).'</td>';
    +		    elseif ($totalarray['totalizable']) {
    +                $printed = false;
    +                foreach ($totalarray['totalizable'] as $totalizable) {
    +                    if ($totalizable['pos']==$i && ! $printed) {
    +                        print '<td align="right">'.price($totalizable['total']).'</td>';
    +                        $printed = true;
    +                    }
    +                }
    +                if (! $printed) {
    +                    print '<td></td>';
    +                }
    +            }
    +		    else print '<td></td>';
     		}
     		print '</tr>';
     	}
    diff --git a/htdocs/comm/propal/note.php b/htdocs/comm/propal/note.php
    index 607cff245d9..a346f8df18f 100644
    --- a/htdocs/comm/propal/note.php
    +++ b/htdocs/comm/propal/note.php
    @@ -144,6 +144,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php
    index ac6b42c45d8..fc2b9c17ba4 100644
    --- a/htdocs/comm/propal/stats/index.php
    +++ b/htdocs/comm/propal/stats/index.php
    @@ -65,9 +65,7 @@ $langs->loadLangs(array('orders', 'companies', 'other', 'suppliers', 'supplier_p
     $form=new Form($db);
     $formpropal=new FormPropal($db);
     
    -$langs->load('propal');
    -$langs->load('other');
    -$langs->load("companies");
    +$langs->loadLangs(array('propal', 'other', 'companies'));
     
     if ($mode == 'customer')
     {
    @@ -278,6 +276,7 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
     	print '<br><br>';
     //}
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -320,7 +319,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    -
    +print '</div>';
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     
    @@ -344,7 +343,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php
    index cd49ca863e6..724e0bcce15 100644
    --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php
    +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php
    @@ -57,7 +57,7 @@ foreach($linkedObjectBlock as $key => $objectlink)
             <?php if(!empty($showImportButton) && $conf->global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES)
                 {
                     $url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$objectlink->id;
    -                print '<a class="objectlinked_importbtn" href="'.$url.'&amp;action=selectlines"  data-element="'.$objectlink->element.'"  data-id="'.$objectlink->id.'"  > <i class="fa fa-indent"></i> </a>';  
    +                print '<a class="objectlinked_importbtn" href="'.$url.'&amp;action=selectlines"  data-element="'.$objectlink->element.'"  data-id="'.$objectlink->id.'"  > <i class="fa fa-indent"></i> </a>';
                 }
             ?>
             </td>
    diff --git a/htdocs/comm/prospect/index.php b/htdocs/comm/prospect/index.php
    index 2273012696f..6d7e93af4be 100644
    --- a/htdocs/comm/prospect/index.php
    +++ b/htdocs/comm/prospect/index.php
    @@ -275,6 +275,6 @@ if ($resql)
     //print '</td></tr></table>';
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/comm/prospect/recap-prospect.php b/htdocs/comm/prospect/recap-prospect.php
    index 50127d719c8..93cfada8860 100644
    --- a/htdocs/comm/prospect/recap-prospect.php
    +++ b/htdocs/comm/prospect/recap-prospect.php
    @@ -89,5 +89,6 @@ else
       	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/recap-client.php b/htdocs/comm/recap-client.php
    index 6cd41c6c658..86c1bad0521 100644
    --- a/htdocs/comm/recap-client.php
    +++ b/htdocs/comm/recap-client.php
    @@ -89,5 +89,6 @@ else
       	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/remise.php b/htdocs/comm/remise.php
    index 6f3287b8831..f045e570c6e 100644
    --- a/htdocs/comm/remise.php
    +++ b/htdocs/comm/remise.php
    @@ -129,8 +129,9 @@ if ($socid > 0)
     
         	print '</form>';
     
    -    	llxFooter();
    -    	$db->close();
    +    	// End of page
    +        llxFooter();
    +        $db->close();
         	exit;
         }
     
    @@ -324,5 +325,6 @@ if ($socid > 0)
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php
    index 3eec109e6b3..78e4643d5e3 100644
    --- a/htdocs/comm/remx.php
    +++ b/htdocs/comm/remx.php
    @@ -998,5 +998,6 @@ if ($socid > 0)
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
    index 81e0d345229..f468bd4b146 100644
    --- a/htdocs/commande/card.php
    +++ b/htdocs/commande/card.php
    @@ -5,13 +5,14 @@
      * Copyright (C) 2005-2015	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2006		Andre Cianfarani		<acianfa@free.fr>
      * Copyright (C) 2010-2013	Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2011-2016	Philippe Grand			<philippe.grand@atoo-net.com>
    + * Copyright (C) 2011-2018	Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2012-2013	Christophe Battarel		<christophe.battarel@altairis.fr>
      * Copyright (C) 2012-2016	Marcos García			<marcosgdf@gmail.com>
      * Copyright (C) 2012       Cedric Salvador      	<csalvador@gpcsolutions.fr>
      * Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
      * Copyright (C) 2014       Ferran Marcet			<fmarcet@2byte.es>
      * Copyright (C) 2015       Jean-François Ferry		<jfefe@aternatik.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -422,7 +423,6 @@ if (empty($reshook))
     						// modified by hook
     						if ($reshook < 0)
     							$error++;
    -
     					} else {
     						setEventMessages($object->error, $object->errors, 'errors');
     						$error++;
    @@ -700,8 +700,10 @@ if (empty($reshook))
     
     				if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
     					$idprod = $res->fk_product_child;
    -				} else {
    -					setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors');
    +				}
    +				else
    +				{
    +					setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
     					$error ++;
     				}
     			}
    @@ -928,7 +930,7 @@ if (empty($reshook))
     			if ($tva_npr)
     				$info_bits |= 0x01;
     
    -			if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
     				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
     				setEventMessages($mesg, null, 'errors');
     			} else {
    @@ -1049,7 +1051,7 @@ if (empty($reshook))
     
     			$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
     
    -			if ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
     				setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
     				$error++;
     			}
    @@ -1577,7 +1579,7 @@ if ($action == 'create' && $user->rights->commande->creer)
     	}
     	// Date
     	print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td>';
    -	$form->select_date('', 're', '', '', '', "crea_commande", 1, 1);			// Always autofill date with current date
    +	print $form->selectDate('', 're', '', '', '', "crea_commande", 1, 1);			// Always autofill date with current date
     	print '</td></tr>';
     
     	// Delivery date planed
    @@ -1587,7 +1589,7 @@ if ($action == 'create' && $user->rights->commande->creer)
     		if (! empty($conf->global->DATE_LIVRAISON_WEEK_DELAY)) $datedelivery = time() + ((7*$conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60);
     		else $datedelivery=empty($conf->global->MAIN_AUTOFILL_DATE_DELIVERY)?-1:'';
     	}
    -	$form->select_date($datedelivery, 'liv_', '', '', '', "crea_commande", 1, 1);
    +	print $form->selectDate($datedelivery, 'liv_', '', '', '', "crea_commande", 1, 1);
     	print "</td></tr>";
     
     	// Conditions de reglement
    @@ -1965,12 +1967,11 @@ if ($action == 'create' && $user->rights->commande->creer)
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('CloneOrder'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
     		}
     
    -		if (! $formconfirm) {
    -			$parameters = array('lineid' => $lineid);
    -			$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -			if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -			elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -		}
    +		// Call Hook formConfirm
    +		$parameters = array('lineid' => $lineid);
    +		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     		// Print form confirm
     		print $formconfirm;
    @@ -2085,7 +2086,7 @@ if ($action == 'create' && $user->rights->commande->creer)
     			print '<form name="setdate" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
     			print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
     			print '<input type="hidden" name="action" value="setdate">';
    -			$form->select_date($object->date, 'order_', '', '', '', "setdate");
    +			print $form->selectDate($object->date, 'order_', '', '', '', "setdate");
     			print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     			print '</form>';
     		} else {
    @@ -2110,7 +2111,7 @@ if ($action == 'create' && $user->rights->commande->creer)
     			print '<form name="setdate_livraison" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
     			print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
     			print '<input type="hidden" name="action" value="setdate_livraison">';
    -			$form->select_date($object->date_livraison ? $object->date_livraison : - 1, 'liv_', '', '', '', "setdate_livraison");
    +			print $form->selectDate($object->date_livraison ? $object->date_livraison : - 1, 'liv_', '', '', '', "setdate_livraison");
     			print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     			print '</form>';
     		} else {
    @@ -2676,5 +2677,6 @@ if ($action == 'create' && $user->rights->commande->creer)
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php
    index e52da47e11b..1135a5c2502 100644
    --- a/htdocs/commande/class/api_orders.class.php
    +++ b/htdocs/commande/class/api_orders.class.php
    @@ -97,9 +97,10 @@ class Orders extends DolibarrApi
          * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
          * @return  array                               Array of order objects
          *
    -	 * @throws RestException
    +     * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -185,9 +186,9 @@ class Orders extends DolibarrApi
          */
         function post($request_data = null)
         {
    -      if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -			  throw new RestException(401, "Insuffisant rights");
    -		  }
    +        if(! DolibarrApiAccess::$user->rights->commande->creer) {
    +			throw new RestException(401, "Insuffisant rights");
    +		}
             // Check mandatory fields
             $result = $this->_validate($request_data);
     
    @@ -218,25 +219,26 @@ class Orders extends DolibarrApi
          *
          * @return int
          */
    -    function getLines($id) {
    -      if(! DolibarrApiAccess::$user->rights->commande->lire) {
    -		  	throw new RestException(401);
    -		  }
    +    function getLines($id)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->commande->lire) {
    +			throw new RestException(401);
    +		}
     
    -      $result = $this->commande->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Order not found');
    -      }
    +        $result = $this->commande->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Order not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    -      $this->commande->getLinesArray();
    -      $result = array();
    -      foreach ($this->commande->lines as $line) {
    -        array_push($result,$this->_cleanObjectDatas($line));
    -      }
    -      return $result;
    +		if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
    +        $this->commande->getLinesArray();
    +        $result = array();
    +        foreach ($this->commande->lines as $line) {
    +            array_push($result,$this->_cleanObjectDatas($line));
    +        }
    +        return $result;
         }
     
         /**
    @@ -249,21 +251,22 @@ class Orders extends DolibarrApi
          *
          * @return int
          */
    -    function postLine($id, $request_data = null) {
    -      if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function postLine($id, $request_data = null)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->commande->creer) {
    +			throw new RestException(401);
    +		}
     
    -      $result = $this->commande->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Order not found');
    -      }
    +        $result = $this->commande->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Order not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    -			$request_data = (object) $request_data;
    -      $updateRes = $this->commande->addline(
    +		if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
    +		$request_data = (object) $request_data;
    +        $updateRes = $this->commande->addline(
                             $request_data->desc,
                             $request_data->subprice,
                             $request_data->qty,
    @@ -290,15 +293,13 @@ class Orders extends DolibarrApi
                             $request_data->origin,
                             $request_data->origin_id,
                             $request_data->multicurrency_subprice
    -      );
    +        );
     
    -      if ($updateRes > 0) {
    -        return $updateRes;
    -
    -      }
    -      else {
    +        if ($updateRes > 0) {
    +            return $updateRes;
    +        } else {
     			throw new RestException(400, $this->commande->error);
    -      }
    +        }
         }
     
         /**
    @@ -312,51 +313,52 @@ class Orders extends DolibarrApi
          *
          * @return object
          */
    -    function putLine($id, $lineid, $request_data = null) {
    -      if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function putLine($id, $lineid, $request_data = null)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->commande->creer) {
    +			throw new RestException(401);
    +		}
     
    -      $result = $this->commande->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Order not found');
    -      }
    +        $result = $this->commande->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Order not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    -			$request_data = (object) $request_data;
    -      $updateRes = $this->commande->updateline(
    -                        $lineid,
    -                        $request_data->desc,
    -                        $request_data->subprice,
    -                        $request_data->qty,
    -                        $request_data->remise_percent,
    -                        $request_data->tva_tx,
    -                        $request_data->localtax1_tx,
    -                        $request_data->localtax2_tx,
    -                        'HT',
    -                        $request_data->info_bits,
    -                        $request_data->date_start,
    -                        $request_data->date_end,
    -                        $request_data->product_type,
    -                        $request_data->fk_parent_line,
    -                        0,
    -                        $request_data->fk_fournprice,
    -                        $request_data->pa_ht,
    -                        $request_data->label,
    -                        $request_data->special_code,
    -                        $request_data->array_options,
    -                        $request_data->fk_unit,
    -      					$request_data->multicurrency_subprice
    -      );
    +		if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
    +		$request_data = (object) $request_data;
    +        $updateRes = $this->commande->updateline(
    +            $lineid,
    +            $request_data->desc,
    +            $request_data->subprice,
    +            $request_data->qty,
    +            $request_data->remise_percent,
    +            $request_data->tva_tx,
    +            $request_data->localtax1_tx,
    +            $request_data->localtax2_tx,
    +            'HT',
    +            $request_data->info_bits,
    +            $request_data->date_start,
    +            $request_data->date_end,
    +            $request_data->product_type,
    +            $request_data->fk_parent_line,
    +            0,
    +            $request_data->fk_fournprice,
    +            $request_data->pa_ht,
    +            $request_data->label,
    +            $request_data->special_code,
    +            $request_data->array_options,
    +            $request_data->fk_unit,
    +      		$request_data->multicurrency_subprice
    +        );
     
    -      if ($updateRes > 0) {
    -        $result = $this->get($id);
    -        unset($result->line);
    -        return $this->_cleanObjectDatas($result);
    -      }
    -      return false;
    +        if ($updateRes > 0) {
    +            $result = $this->get($id);
    +            unset($result->line);
    +            return $this->_cleanObjectDatas($result);
    +        }
    +        return false;
         }
     
         /**
    @@ -372,30 +374,29 @@ class Orders extends DolibarrApi
          * @throws 401
          * @throws 404
          */
    -    function deleteLine($id, $lineid) {
    -      if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function deleteLine($id, $lineid)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->commande->creer) {
    +			throw new RestException(401);
    +		}
     
    -      $result = $this->commande->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Order not found');
    -      }
    +        $result = $this->commande->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Order not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    +		if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
     
    -      // TODO Check the lineid $lineid is a line of ojbect
    +        // TODO Check the lineid $lineid is a line of ojbect
     
    -      $updateRes = $this->commande->deleteline(DolibarrApiAccess::$user,$lineid);
    -      if ($updateRes > 0) {
    -        return $this->get($id);
    -      }
    -      else
    -      {
    -      	throw new RestException(405, $this->commande->error);
    -      }
    +        $updateRes = $this->commande->deleteline(DolibarrApiAccess::$user,$lineid);
    +        if ($updateRes > 0) {
    +            return $this->get($id);
    +        } else {
    +            throw new RestException(405, $this->commande->error);
    +        }
         }
     
         /**
    @@ -406,10 +407,11 @@ class Orders extends DolibarrApi
          *
          * @return int
          */
    -    function put($id, $request_data = null) {
    -      if (! DolibarrApiAccess::$user->rights->commande->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function put($id, $request_data = null)
    +    {
    +        if (! DolibarrApiAccess::$user->rights->commande->creer) {
    +			throw new RestException(401);
    +		}
     
             $result = $this->commande->fetch($id);
             if (! $result) {
    @@ -470,7 +472,6 @@ class Orders extends DolibarrApi
                     'message' => 'Order deleted'
                 )
             );
    -
         }
     
         /**
    @@ -547,24 +548,25 @@ class Orders extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function reopen($id) {
    +    function reopen($id)
    +    {
     
             if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($id)) {
    -                throw new RestException(400, 'Order ID is mandatory');
    +            throw new RestException(400, 'Order ID is mandatory');
             }
             $result = $this->commande->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Order not found');
    +            throw new RestException(404, 'Order not found');
             }
     
             $result = $this->commande->set_reopen(DolibarrApiAccess::$user);
             if( $result < 0) {
    -                throw new RestException(405, $this->commande->error);
    +            throw new RestException(405, $this->commande->error);
             }else if( $result == 0) {
    -                throw new RestException(304);
    +            throw new RestException(304);
             }
     
             return $result;
    @@ -584,22 +586,23 @@ class Orders extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function setinvoiced($id) {
    +    function setinvoiced($id)
    +    {
     
             if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($id)) {
    -                throw new RestException(400, 'Order ID is mandatory');
    +            throw new RestException(400, 'Order ID is mandatory');
             }
             $result = $this->commande->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Order not found');
    +            throw new RestException(404, 'Order not found');
             }
     
             $result = $this->commande->classifyBilled(DolibarrApiAccess::$user);
             if( $result < 0) {
    -                throw new RestException(400, $this->commande->error);
    +            throw new RestException(400, $this->commande->error);
             }
     
             $result = $this->commande->fetch($id);
    @@ -675,23 +678,23 @@ class Orders extends DolibarrApi
         function settodraft($id, $idwarehouse=-1)
         {
             if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             $result = $this->commande->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Order not found');
    +            throw new RestException(404, 'Order not found');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
     
             $result = $this->commande->set_draft(DolibarrApiAccess::$user, $idwarehouse);
             if ($result == 0) {
    -                throw new RestException(304, 'Nothing done. May be object is already closed');
    +            throw new RestException(304, 'Nothing done. May be object is already closed');
             }
             if ($result < 0) {
    -                throw new RestException(500, 'Error when closing Order: '.$this->commande->error);
    +            throw new RestException(500, 'Error when closing Order: '.$this->commande->error);
             }
     
     		$result = $this->commande->fetch($id);
    @@ -709,43 +712,44 @@ class Orders extends DolibarrApi
         }
     
     
    -     /**
    -      * Create an order using an existing proposal.
    -      *
    -      *
    -      * @param int   $proposalid       Id of the proposal
    -      *
    -      * @url     POST /createfromproposal/{proposalid}
    -      *
    -      * @return int
    -      * @throws 400
    -      * @throws 401
    -      * @throws 404
    -      * @throws 405
    -      */
    -     function createOrderFromProposal($proposalid) {
    +    /**
    +     * Create an order using an existing proposal.
    +     *
    +     *
    +     * @param int   $proposalid       Id of the proposal
    +     *
    +     * @url     POST /createfromproposal/{proposalid}
    +     *
    +     * @return int
    +     * @throws 400
    +     * @throws 401
    +     * @throws 404
    +     * @throws 405
    +     */
    +    function createOrderFromProposal($proposalid)
    +    {
     
             require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php';
     
             if(! DolibarrApiAccess::$user->rights->propal->lire) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(! DolibarrApiAccess::$user->rights->commande->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($proposalid)) {
    -                throw new RestException(400, 'Proposal ID is mandatory');
    +            throw new RestException(400, 'Proposal ID is mandatory');
             }
     
             $propal = new Propal($this->db);
             $result = $propal->fetch($proposalid);
             if( ! $result ) {
    -                throw new RestException(404, 'Proposal not found');
    +            throw new RestException(404, 'Proposal not found');
             }
     
             $result = $this->commande->createFromProposal($propal, DolibarrApiAccess::$user);
             if( $result < 0) {
    -                throw new RestException(405, $this->commande->error);
    +            throw new RestException(405, $this->commande->error);
             }
             $this->commande->fetchObjectLinked();
     
    @@ -759,7 +763,8 @@ class Orders extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -785,9 +790,8 @@ class Orders extends DolibarrApi
             $commande = array();
             foreach (Orders::$FIELDS as $field) {
                 if (!isset($data[$field]))
    -                throw new RestException(400, "$field field missing");
    +                throw new RestException(400, $field ." field missing");
                 $commande[$field] = $data[$field];
    -
             }
             return $commande;
         }
    diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
    index e1828076786..2428e6052eb 100644
    --- a/htdocs/commande/class/commande.class.php
    +++ b/htdocs/commande/class/commande.class.php
    @@ -42,108 +42,145 @@ require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php';
      */
     class Commande extends CommonOrder
     {
    -    public $element='commande';
    -    public $table_element='commande';
    -    public $table_element_line = 'commandedet';
    -    public $class_element_line = 'OrderLine';
    -    public $fk_element = 'fk_commande';
    -    public $picto = 'order';
    -    /**
    -     * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    -     * @var int
    -     */
    -    public $ismultientitymanaged = 1;
    -    /**
    -     * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
    -     * @var integer
    -     */
    -    public $restrictiononfksoc = 1;
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='commande';
     
    -    /**
    -     * {@inheritdoc}
    -     */
    -    protected $table_ref_field = 'ref';
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='commande';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
    +	public $table_element_line = 'commandedet';
    +
    +	public $class_element_line = 'OrderLine';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element = 'fk_commande';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'order';
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
    +	/**
    +	 * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
    +	 * @var integer
    +	 */
    +	public $restrictiononfksoc = 1;
    +
    +	/**
    +	 * {@inheritdoc}
    +	 */
    +	protected $table_ref_field = 'ref';
     
     	/**
     	 * Client ID
     	 * @var int
     	 */
    -    public $socid;
    +	public $socid;
     
    -    public $ref_client;
    -    public $ref_int;
    -    public $contactid;
    +	public $ref_client;
    +	public $ref_int;
    +	public $contactid;
     
     	/**
     	 * Status of the order
     	 * @var int
     	 */
    -    public $statut;
    +	public $statut;
    +
     	/**
     	 * Billed
     	 * @var int
     	 */
    -    public $billed;		// billed or not
    +	public $billed;		// billed or not
     
    -    public $brouillon;
    -    public $cond_reglement_code;
    +	public $brouillon;
    +	public $cond_reglement_code;
     
    -    public $fk_account;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_account;
     
    -    /**
    -     * It holds the label of the payment mode. Use it in case translation cannot be found.
    -     * @var string
    -     */
    -    public $mode_reglement;
    +	/**
    +	 * It holds the label of the payment mode. Use it in case translation cannot be found.
    +	 * @var string
    +	 */
    +	public $mode_reglement;
     
    -    /**
    -     * Payment mode id
    -     * @var int
    -     */
    -    public $mode_reglement_id;
    -    /**
    -     * Payment mode code
    -     * @var string
    -     */
    -    public $mode_reglement_code;
    -    /**
    -     * Availability delivery time id
    -     * @var int
    -     */
    -    public $availability_id;
    -    /**
    -     * Availability delivery time code
    -     * @var string
    -     */
    -    public $availability_code;
    -    /**
    -     * Label of availability delivery time. Use it in case translation cannot be found.
    -     * @var string
    -     */
    -    public $availability;
    +	/**
    +	 * Payment mode id
    +	 * @var int
    +	 */
    +	public $mode_reglement_id;
     
    -    public $demand_reason_id;   // Source reason. Why we receive order (after a phone campaign, ...)
    -    public $demand_reason_code;
    -    public $date;				// Date commande
    +	/**
    +	 * Payment mode code
    +	 * @var string
    +	 */
    +	public $mode_reglement_code;
    +
    +	/**
    +	 * Availability delivery time id
    +	 * @var int
    +	 */
    +	public $availability_id;
    +
    +	/**
    +	 * Availability delivery time code
    +	 * @var string
    +	 */
    +	public $availability_code;
    +
    +	/**
    +	 * Label of availability delivery time. Use it in case translation cannot be found.
    +	 * @var string
    +	 */
    +	public $availability;
    +
    +	public $demand_reason_id;   // Source reason. Why we receive order (after a phone campaign, ...)
    +	public $demand_reason_code;
    +	public $date;				// Date commande
    +  
     	/**
     	 * @deprecated
     	 * @see date
     	 */
    -    public $date_commande;
    -    public $date_livraison;	    // Date expected of shipment (date starting shipment, not the reception that occurs some days after)
    -    public $fk_remise_except;
    -    public $remise_percent;
    -    public $remise_absolue;
    -    public $info_bits;
    -    public $rang;
    -    public $special_code;
    -    public $source;			    // Order mode. How we received order (by phone, by email, ...)
    -    public $extraparams=array();
    +	public $date_commande;
     
    -    public $linked_objects=array();
    +	public $date_livraison;	    // Date expected of shipment (date starting shipment, not the reception that occurs some days after)
     
    -    public $user_author_id;
    -    public $user_valid;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_remise_except;
    +
    +	public $remise_percent;
    +	public $remise_absolue;
    +	public $info_bits;
    +	public $rang;
    +	public $special_code;
    +	public $source;			    // Order mode. How we received order (by phone, by email, ...)
    +	public $extraparams=array();
    +
    +	public $linked_objects=array();
    +
    +	public $user_author_id;
    +	public $user_valid;
     
     	/**
     	 * @var OrderLine[]
    @@ -151,7 +188,11 @@ class Commande extends CommonOrder
     	public $lines = array();
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     	public $multicurrency_tx;
     	public $multicurrency_total_ht;
    @@ -160,10 +201,10 @@ class Commande extends CommonOrder
     
     	public $oldcopy;
     
    -    /**
    -     * ERR Not enough stock
    -     */
    -    const STOCK_NOT_ENOUGH_FOR_ORDER = -3;
    +	/**
    +	 * ERR Not enough stock
    +	 */
    +	const STOCK_NOT_ENOUGH_FOR_ORDER = -3;
     
     	/**
     	 * Canceled status
    @@ -189,445 +230,449 @@ class Commande extends CommonOrder
     	const STATUS_CLOSED = 3;
     
     
    -    /**
    -     *	Constructor
    -     *
    -     *  @param		DoliDB		$db      Database handler
    -     */
    -    function __construct($db)
    -    {
    -        $this->db = $db;
    +	/**
    +	 *	Constructor
    +	 *
    +	 *  @param		DoliDB		$db      Database handler
    +	 */
    +	function __construct($db)
    +	{
    +		$this->db = $db;
     
    -        $this->remise = 0;
    -        $this->remise_percent = 0;
    +		$this->remise = 0;
    +		$this->remise_percent = 0;
     
    -        $this->products = array();
    -    }
    +		$this->products = array();
    +	}
     
    -    /**
    +	/**
     	 *  Returns the reference to the following non used Order depending on the active numbering module
     	 *  defined into COMMANDE_ADDON
     	 *
     	 *  @param	Societe		$soc  	Object thirdparty
     	 *  @return string      		Order free reference
     	 */
    -    function getNextNumRef($soc)
    -    {
    -        global $langs, $conf;
    -        $langs->load("order");
    +	function getNextNumRef($soc)
    +	{
    +		global $langs, $conf;
    +		$langs->load("order");
     
    -        if (! empty($conf->global->COMMANDE_ADDON))
    -        {
    -        	$mybool=false;
    +		if (! empty($conf->global->COMMANDE_ADDON))
    +		{
    +			$mybool=false;
     
    -        	$file = $conf->global->COMMANDE_ADDON.".php";
    +			$file = $conf->global->COMMANDE_ADDON.".php";
     			$classname = $conf->global->COMMANDE_ADDON;
     
     			// Include file with class
     			$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
     			foreach ($dirmodels as $reldir)
     			{
    -                $dir = dol_buildpath($reldir."core/modules/commande/");
    +				$dir = dol_buildpath($reldir."core/modules/commande/");
     
    -                // Load file with numbering class (if found)
    -                $mybool|=@include_once $dir.$file;
    -            }
    +				// Load file with numbering class (if found)
    +				$mybool|=@include_once $dir.$file;
    +			}
     
    -            if (! $mybool)
    -            {
    -                dol_print_error('',"Failed to include file ".$file);
    -                return '';
    -            }
    +			if (! $mybool)
    +			{
    +				dol_print_error('',"Failed to include file ".$file);
    +				return '';
    +			}
     
    -            $obj = new $classname();
    -            $numref = $obj->getNextValue($soc,$this);
    +			$obj = new $classname();
    +			$numref = $obj->getNextValue($soc,$this);
     
    -            if ($numref != "")
    -            {
    -            	return $numref;
    -            }
    -            else
    +			if ($numref != "")
    +			{
    +				return $numref;
    +			}
    +			else
     			{
     				$this->error=$obj->error;
    -            	//dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
    -            	return "";
    -            }
    -        }
    -        else
    -        {
    -            print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_ADDON_NotDefined");
    -            return "";
    -        }
    -    }
    -
    -
    -    /**
    -     *	Validate order
    -     *
    -     *	@param		User	$user     		User making status change
    -     *	@param		int		$idwarehouse	Id of warehouse to use for stock decrease
    -     *  @param		int		$notrigger		1=Does not execute triggers, 0= execute triggers
    -     *	@return  	int						<=0 if OK, 0=Nothing done, >0 if KO
    -     */
    -    function valid($user, $idwarehouse=0, $notrigger=0)
    -    {
    -        global $conf,$langs;
    -        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    -
    -        $error=0;
    -
    -        // Protection
    -        if ($this->statut == self::STATUS_VALIDATED)
    -        {
    -            dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING);
    -            return 0;
    -        }
    -
    -        if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
    -       	|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate))))
    -        {
    -            $this->error='NotEnoughPermissions';
    -            dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
    -            return -1;
    -        }
    -
    -        $now=dol_now();
    -
    -        $this->db->begin();
    -
    -        // Definition du nom de module de numerotation de commande
    -        $soc = new Societe($this->db);
    -        $soc->fetch($this->socid);
    -
    -        // Class of company linked to order
    -        $result=$soc->set_as_client();
    -
    -        // Define new ref
    -        if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
    -        {
    -            $num = $this->getNextNumRef($soc);
    -        }
    -        else
    +				//dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
    +				return "";
    +			}
    +		}
    +		else
     		{
    -            $num = $this->ref;
    -        }
    -        $this->newref = $num;
    +			print $langs->trans("Error")." ".$langs->trans("Error_COMMANDE_ADDON_NotDefined");
    +			return "";
    +		}
    +	}
     
    -        // Validate
    -        $sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    -        $sql.= " SET ref = '".$num."',";
    -        $sql.= " fk_statut = ".self::STATUS_VALIDATED.",";
    -        $sql.= " date_valid='".$this->db->idate($now)."',";
    -        $sql.= " fk_user_valid = ".$user->id;
    -        $sql.= " WHERE rowid = ".$this->id;
     
    -        dol_syslog(get_class($this)."::valid()", LOG_DEBUG);
    -        $resql=$this->db->query($sql);
    -        if (! $resql)
    -        {
    -            dol_print_error($this->db);
    -            $this->error=$this->db->lasterror();
    -            $error++;
    -        }
    +	/**
    +	 *	Validate order
    +	 *
    +	 *	@param		User	$user     		User making status change
    +	 *	@param		int		$idwarehouse	Id of warehouse to use for stock decrease
    +	 *  @param		int		$notrigger		1=Does not execute triggers, 0= execute triggers
    +	 *	@return  	int						<=0 if OK, 0=Nothing done, >0 if KO
    +	 */
    +	function valid($user, $idwarehouse=0, $notrigger=0)
    +	{
    +		global $conf,$langs;
    +		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    -        if (! $error)
    -        {
    -            // If stock is incremented on validate order, we must increment it
    -            if ($result >= 0 && ! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1)
    -            {
    -                require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
    -                $langs->load("agenda");
    +		$error=0;
     
    -                // Loop on each line
    -                $cpt=count($this->lines);
    -                for ($i = 0; $i < $cpt; $i++)
    -                {
    -                    if ($this->lines[$i]->fk_product > 0)
    -                    {
    -                        $mouvP = new MouvementStock($this->db);
    +		// Protection
    +		if ($this->statut == self::STATUS_VALIDATED)
    +		{
    +			dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING);
    +			return 0;
    +		}
    +
    +		if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
    +			|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate))))
    +		{
    +			$this->error='NotEnoughPermissions';
    +			dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
    +			return -1;
    +		}
    +
    +		$now=dol_now();
    +
    +		$this->db->begin();
    +
    +		// Definition du nom de module de numerotation de commande
    +		$soc = new Societe($this->db);
    +		$soc->fetch($this->socid);
    +
    +		// Class of company linked to order
    +		$result=$soc->set_as_client();
    +
    +		// Define new ref
    +		if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
    +		{
    +			$num = $this->getNextNumRef($soc);
    +		}
    +		else
    +		{
    +			$num = $this->ref;
    +		}
    +		$this->newref = $num;
    +
    +		// Validate
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    +		$sql.= " SET ref = '".$num."',";
    +		$sql.= " fk_statut = ".self::STATUS_VALIDATED.",";
    +		$sql.= " date_valid='".$this->db->idate($now)."',";
    +		$sql.= " fk_user_valid = ".$user->id;
    +		$sql.= " WHERE rowid = ".$this->id;
    +
    +		dol_syslog(get_class($this)."::valid()", LOG_DEBUG);
    +		$resql=$this->db->query($sql);
    +		if (! $resql)
    +		{
    +			dol_print_error($this->db);
    +			$this->error=$this->db->lasterror();
    +			$error++;
    +		}
    +
    +		if (! $error)
    +		{
    +			// If stock is incremented on validate order, we must increment it
    +			if ($result >= 0 && ! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1)
    +			{
    +				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
    +				$langs->load("agenda");
    +
    +				// Loop on each line
    +				$cpt=count($this->lines);
    +				for ($i = 0; $i < $cpt; $i++)
    +				{
    +					if ($this->lines[$i]->fk_product > 0)
    +					{
    +						$mouvP = new MouvementStock($this->db);
     						$mouvP->origin = &$this;
    -                        // We decrement stock of product (and sub-products)
    -                        $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("OrderValidatedInDolibarr",$num));
    -                        if ($result < 0)
    -                        {
    -                        	$error++;
    -                        	$this->error=$mouvP->error;
    -                        }
    -                    }
    -                    if ($error) break;
    -                }
    -            }
    -        }
    +						// We decrement stock of product (and sub-products)
    +						$result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("OrderValidatedInDolibarr",$num));
    +						if ($result < 0)
    +						{
    +							$error++;
    +							$this->error=$mouvP->error;
    +						}
    +					}
    +					if ($error) break;
    +				}
    +			}
    +		}
     
    -        if (! $error && ! $notrigger)
    -        {
    -            // Call trigger
    -            $result=$this->call_trigger('ORDER_VALIDATE',$user);
    -            if ($result < 0) $error++;
    -            // End call triggers
    -        }
    -
    -        if (! $error)
    -        {
    -            $this->oldref = $this->ref;
    -
    -            // Rename directory if dir was a temporary ref
    -            if (preg_match('/^[\(]?PROV/i', $this->ref))
    -            {
    -            	// On renomme repertoire ($this->ref = ancienne ref, $num = nouvelle ref)
    -                // in order not to lose the attachments
    -                $oldref = dol_sanitizeFileName($this->ref);
    -                $newref = dol_sanitizeFileName($num);
    -                $dirsource = $conf->commande->dir_output.'/'.$oldref;
    -                $dirdest = $conf->commande->dir_output.'/'.$newref;
    -                if (file_exists($dirsource))
    -                {
    -                    dol_syslog(get_class($this)."::valid() rename dir ".$dirsource." into ".$dirdest);
    -
    -                    if (@rename($dirsource, $dirdest))
    -                    {
    -                        dol_syslog("Rename ok");
    -                        // Rename docs starting with $oldref with $newref
    -                        $listoffiles=dol_dir_list($conf->commande->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/'));
    -                        foreach($listoffiles as $fileentry)
    -                        {
    -                        	$dirsource=$fileentry['name'];
    -                        	$dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource);
    -                        	$dirsource=$fileentry['path'].'/'.$dirsource;
    -                        	$dirdest=$fileentry['path'].'/'.$dirdest;
    -                        	@rename($dirsource, $dirdest);
    -                        }
    -                    }
    -                }
    -            }
    -        }
    -
    -        // Set new ref and current status
    -        if (! $error)
    -        {
    -            $this->ref = $num;
    -            $this->statut = self::STATUS_VALIDATED;
    -        }
    -
    -        if (! $error)
    -        {
    -            $this->db->commit();
    -            return 1;
    -        }
    -        else
    +		if (! $error && ! $notrigger)
     		{
    -            $this->db->rollback();
    -            return -1;
    -        }
    -    }
    +			// Call trigger
    +			$result=$this->call_trigger('ORDER_VALIDATE',$user);
    +			if ($result < 0) $error++;
    +			// End call triggers
    +		}
     
    -    /**
    -     *	Set draft status
    -     *
    -     *	@param	User	$user			Object user that modify
    -     *	@param	int		$idwarehouse	Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on)
    -     *	@return	int						<0 if KO, >0 if OK
    -     */
    -    function set_draft($user, $idwarehouse=-1)
    -    {
    -        global $conf,$langs;
    +		if (! $error)
    +		{
    +			$this->oldref = $this->ref;
     
    -        $error=0;
    +			// Rename directory if dir was a temporary ref
    +			if (preg_match('/^[\(]?PROV/i', $this->ref))
    +			{
    +				// On renomme repertoire ($this->ref = ancienne ref, $num = nouvelle ref)
    +				// in order not to lose the attachments
    +				$oldref = dol_sanitizeFileName($this->ref);
    +				$newref = dol_sanitizeFileName($num);
    +				$dirsource = $conf->commande->dir_output.'/'.$oldref;
    +				$dirdest = $conf->commande->dir_output.'/'.$newref;
    +				if (file_exists($dirsource))
    +				{
    +					dol_syslog(get_class($this)."::valid() rename dir ".$dirsource." into ".$dirdest);
     
    -        // Protection
    -        if ($this->statut <= self::STATUS_DRAFT)
    -        {
    -            return 0;
    -        }
    +					if (@rename($dirsource, $dirdest))
    +					{
    +						dol_syslog("Rename ok");
    +						// Rename docs starting with $oldref with $newref
    +						$listoffiles=dol_dir_list($conf->commande->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/'));
    +						foreach($listoffiles as $fileentry)
    +						{
    +							$dirsource=$fileentry['name'];
    +							$dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource);
    +							$dirsource=$fileentry['path'].'/'.$dirsource;
    +							$dirdest=$fileentry['path'].'/'.$dirdest;
    +							@rename($dirsource, $dirdest);
    +						}
    +					}
    +				}
    +			}
    +		}
     
    -        if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
    -       	|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate))))
    -        {
    -            $this->error='Permission denied';
    -            return -1;
    -        }
    +		// Set new ref and current status
    +		if (! $error)
    +		{
    +			$this->ref = $num;
    +			$this->statut = self::STATUS_VALIDATED;
    +		}
     
    -        $this->db->begin();
    +		if (! $error)
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +		else
    +		{
    +			$this->db->rollback();
    +			return -1;
    +		}
    +	}
     
    -        $sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    -        $sql.= " SET fk_statut = ".self::STATUS_DRAFT;
    -        $sql.= " WHERE rowid = ".$this->id;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Set draft status
    +	 *
    +	 *	@param	User	$user			Object user that modify
    +	 *	@param	int		$idwarehouse	Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on)
    +	 *	@return	int						<0 if KO, >0 if OK
    +	 */
    +	function set_draft($user, $idwarehouse=-1)
    +	{
    +        //phpcs:enable
    +		global $conf,$langs;
     
    -        dol_syslog(get_class($this)."::set_draft", LOG_DEBUG);
    -        if ($this->db->query($sql))
    -        {
    -            // If stock is decremented on validate order, we must reincrement it
    -            if (! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1)
    -            {
    -                $result = 0;
    +		$error=0;
     
    -                require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
    -                $langs->load("agenda");
    +		// Protection
    +		if ($this->statut <= self::STATUS_DRAFT)
    +		{
    +			return 0;
    +		}
     
    -                $num=count($this->lines);
    -                for ($i = 0; $i < $num; $i++)
    -                {
    -                    if ($this->lines[$i]->fk_product > 0)
    -                    {
    -                        $mouvP = new MouvementStock($this->db);
    -                        $mouvP->origin = &$this;
    -                        // We increment stock of product (and sub-products)
    -                        $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("OrderBackToDraftInDolibarr",$this->ref));
    -                        if ($result < 0) { $error++; $this->error=$mouvP->error; break; }
    -                    }
    -                }
    -            }
    +		if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
    +			|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate))))
    +		{
    +			$this->error='Permission denied';
    +			return -1;
    +		}
     
    -            if (!$error) {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_UNVALIDATE',$user);
    -            	if ($result < 0) $error++;
    -            }
    +		$this->db->begin();
     
    -            if (!$error) {
    -           		$this->statut=self::STATUS_DRAFT;
    -            	$this->db->commit();
    -            	return 1;
    -            }else {
    -            	$this->db->rollback();
    -            	return -1;
    -            }
    -        }
    -        else
    -        {
    -            $this->error=$this->db->error();
    -            $this->db->rollback();
    -            return -1;
    -        }
    -    }
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    +		$sql.= " SET fk_statut = ".self::STATUS_DRAFT;
    +		$sql.= " WHERE rowid = ".$this->id;
    +
    +		dol_syslog(get_class($this)."::set_draft", LOG_DEBUG);
    +		if ($this->db->query($sql))
    +		{
    +			// If stock is decremented on validate order, we must reincrement it
    +			if (! empty($conf->stock->enabled) && $conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER == 1)
    +			{
    +				$result = 0;
    +
    +				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
    +				$langs->load("agenda");
    +
    +				$num=count($this->lines);
    +				for ($i = 0; $i < $num; $i++)
    +				{
    +					if ($this->lines[$i]->fk_product > 0)
    +					{
    +						$mouvP = new MouvementStock($this->db);
    +						$mouvP->origin = &$this;
    +						// We increment stock of product (and sub-products)
    +						$result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("OrderBackToDraftInDolibarr",$this->ref));
    +						if ($result < 0) { $error++; $this->error=$mouvP->error; break; }
    +					}
    +				}
    +			}
    +
    +			if (!$error) {
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_UNVALIDATE',$user);
    +				if ($result < 0) $error++;
    +			}
    +
    +			if (!$error) {
    +				$this->statut=self::STATUS_DRAFT;
    +				$this->db->commit();
    +				return 1;
    +			}else {
    +				$this->db->rollback();
    +				return -1;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			$this->db->rollback();
    +			return -1;
    +		}
    +	}
     
     
    -    /**
    -     *	Tag the order as validated (opened)
    -     *	Function used when order is reopend after being closed.
    -     *
    -     *	@param      User	$user       Object user that change status
    -     *	@return     int         		<0 if KO, 0 if nothing is done, >0 if OK
    -     */
    -    function set_reopen($user)
    -    {
    -        $error=0;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Tag the order as validated (opened)
    +	 *	Function used when order is reopend after being closed.
    +	 *
    +	 *	@param      User	$user       Object user that change status
    +	 *	@return     int         		<0 if KO, 0 if nothing is done, >0 if OK
    +	 */
    +	function set_reopen($user)
    +	{
    +        // phpcs:enable
    +		$error=0;
     
    -        if ($this->statut != self::STATUS_CANCELED && $this->statut != self::STATUS_CLOSED)
    -        {
    -        	dol_syslog(get_class($this)."::set_reopen order has not status closed", LOG_WARNING);
    -            return 0;
    -        }
    +		if ($this->statut != self::STATUS_CANCELED && $this->statut != self::STATUS_CLOSED)
    +		{
    +			dol_syslog(get_class($this)."::set_reopen order has not status closed", LOG_WARNING);
    +			return 0;
    +		}
     
    -        $this->db->begin();
    +		$this->db->begin();
     
    -        $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    -        $sql.= ' SET fk_statut='.self::STATUS_VALIDATED.', facture=0';
    -        $sql.= ' WHERE rowid = '.$this->id;
    +		$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    +		$sql.= ' SET fk_statut='.self::STATUS_VALIDATED.', facture=0';
    +		$sql.= ' WHERE rowid = '.$this->id;
     
    -        dol_syslog(get_class($this)."::set_reopen", LOG_DEBUG);
    -        $resql = $this->db->query($sql);
    -        if ($resql)
    -        {
    -            // Call trigger
    -            $result=$this->call_trigger('ORDER_REOPEN',$user);
    -            if ($result < 0) $error++;
    -            // End call triggers
    -        }
    -        else
    -        {
    -            $error++;
    -            $this->error=$this->db->lasterror();
    -            dol_print_error($this->db);
    -        }
    +		dol_syslog(get_class($this)."::set_reopen", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if ($resql)
    +		{
    +			// Call trigger
    +			$result=$this->call_trigger('ORDER_REOPEN',$user);
    +			if ($result < 0) $error++;
    +			// End call triggers
    +		}
    +		else
    +		{
    +			$error++;
    +			$this->error=$this->db->lasterror();
    +			dol_print_error($this->db);
    +		}
     
    -        if (! $error)
    -        {
    -        	$this->statut = self::STATUS_VALIDATED;
    -        	$this->billed = 0;
    +		if (! $error)
    +		{
    +			$this->statut = self::STATUS_VALIDATED;
    +			$this->billed = 0;
     
    -            $this->db->commit();
    -            return 1;
    -        }
    -        else
    -        {
    -	        foreach($this->errors as $errmsg)
    -	        {
    -		        dol_syslog(get_class($this)."::set_reopen ".$errmsg, LOG_ERR);
    -		        $this->error.=($this->error?', '.$errmsg:$errmsg);
    -	        }
    -	        $this->db->rollback();
    -	        return -1*$error;
    -        }
    -    }
    +			$this->db->commit();
    +			return 1;
    +		}
    +		else
    +		{
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::set_reopen ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +	}
     
    -    /**
    -     *  Close order
    -     *
    -     * 	@param      User	$user       Objet user that close
    -     *  @param		int		$notrigger	1=Does not execute triggers, 0=Execute triggers
    -     *	@return		int					<0 if KO, >0 if OK
    -     */
    -    function cloture($user, $notrigger=0)
    -    {
    -        global $conf;
    +	/**
    +	 *  Close order
    +	 *
    +	 * 	@param      User	$user       Objet user that close
    +	 *  @param		int		$notrigger	1=Does not execute triggers, 0=Execute triggers
    +	 *	@return		int					<0 if KO, >0 if OK
    +	 */
    +	function cloture($user, $notrigger=0)
    +	{
    +		global $conf;
     
    -        $error=0;
    +		$error=0;
     
    -        if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
    -       	|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate)))
    -        {
    -            $this->db->begin();
    +		if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
    +			|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate)))
    +		{
    +			$this->db->begin();
     
    -            $now=dol_now();
    +			$now=dol_now();
     
    -            $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    -            $sql.= ' SET fk_statut = '.self::STATUS_CLOSED.',';
    -            $sql.= ' fk_user_cloture = '.$user->id.',';
    -            $sql.= " date_cloture = '".$this->db->idate($now)."'";
    -            $sql.= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT;
    +			$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    +			$sql.= ' SET fk_statut = '.self::STATUS_CLOSED.',';
    +			$sql.= ' fk_user_cloture = '.$user->id.',';
    +			$sql.= " date_cloture = '".$this->db->idate($now)."'";
    +			$sql.= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT;
     
    -            if ($this->db->query($sql))
    -            {
    -            	if (! $notrigger)
    -            	{
    -		            // Call trigger
    -	            	$result=$this->call_trigger('ORDER_CLOSE',$user);
    -	            	if ($result < 0) $error++;
    -		            // End call triggers
    -            	}
    +			if ($this->db->query($sql))
    +			{
    +				if (! $notrigger)
    +				{
    +					// Call trigger
    +					$result=$this->call_trigger('ORDER_CLOSE',$user);
    +					if ($result < 0) $error++;
    +					// End call triggers
    +				}
     
    -                if (! $error)
    -                {
    -                	$this->statut=self::STATUS_CLOSED;
    +				if (! $error)
    +				{
    +					$this->statut=self::STATUS_CLOSED;
     
    -                    $this->db->commit();
    -                    return 1;
    -                }
    -                else
    -                {
    -                    $this->db->rollback();
    -                    return -1;
    -                }
    -            }
    -            else
    -            {
    -                $this->error=$this->db->lasterror();
    +					$this->db->commit();
    +					return 1;
    +				}
    +				else
    +				{
    +					$this->db->rollback();
    +					return -1;
    +				}
    +			}
    +			else
    +			{
    +				$this->error=$this->db->lasterror();
     
    -                $this->db->rollback();
    -                return -1;
    -            }
    -        }
    -        return 0;
    -    }
    +				$this->db->rollback();
    +				return -1;
    +			}
    +		}
    +		return 0;
    +	}
     
    -    /**
    -     * 	Cancel an order
    -     * 	If stock is decremented on order validation, we must reincrement it
    -     *
    -     *	@param	int		$idwarehouse	Id warehouse to use for stock change.
    -     *	@return	int						<0 if KO, >0 if OK
    -     */
    +	/**
    +	 * 	Cancel an order
    +	 * 	If stock is decremented on order validation, we must reincrement it
    +	 *
    +	 *	@param	int		$idwarehouse	Id warehouse to use for stock change.
    +	 *	@return	int						<0 if KO, >0 if OK
    +	 */
     	function cancel($idwarehouse=-1)
     	{
     		global $conf,$user,$langs;
    @@ -670,10 +715,10 @@ class Commande extends CommonOrder
     
     			if (! $error)
     			{
    -	            // Call trigger
    -	            $result=$this->call_trigger('ORDER_CANCEL',$user);
    -	            if ($result < 0) $error++;
    -	            // End call triggers
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_CANCEL',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
     			}
     
     			if (! $error)
    @@ -701,24 +746,24 @@ class Commande extends CommonOrder
     		}
     	}
     
    -    /**
    -     *	Create order
    -     *	Note that this->ref can be set or empty. If empty, we will use "(PROV)"
    -     *
    -     *	@param		User	$user 		Objet user that make creation
    -     *	@param		int	    $notrigger	Disable all triggers
    -     *	@return 	int			        <0 if KO, >0 if OK
    -     */
    -    function create($user, $notrigger=0)
    -    {
    -        global $conf,$langs;
    -        $error=0;
    +	/**
    +	 *	Create order
    +	 *	Note that this->ref can be set or empty. If empty, we will use "(PROV)"
    +	 *
    +	 *	@param		User	$user 		Objet user that make creation
    +	 *	@param		int	    $notrigger	Disable all triggers
    +	 *	@return 	int			        <0 if KO, >0 if OK
    +	 */
    +	function create($user, $notrigger=0)
    +	{
    +		global $conf,$langs;
    +		$error=0;
     
    -        // Clean parameters
    -        $this->brouillon = 1;		// set command as draft
    +		// Clean parameters
    +		$this->brouillon = 1;		// set command as draft
     
     		// $date_commande is deprecated
    -        $date = ($this->date_commande ? $this->date_commande : $this->date);
    +		$date = ($this->date_commande ? $this->date_commande : $this->date);
     
     		// Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
     		if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) list($this->fk_multicurrency,$this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $date);
    @@ -730,412 +775,412 @@ class Commande extends CommonOrder
     			$this->multicurrency_tx = 1;
     		}
     
    -        dol_syslog(get_class($this)."::create user=".$user->id);
    +		dol_syslog(get_class($this)."::create user=".$user->id);
     
    -        // Check parameters
    -    	if (! empty($this->ref))	// We check that ref is not already used
    -    	{
    -    		$result=self::isExistingObject($this->element, 0, $this->ref);	// Check ref is not yet used
    -    		if ($result > 0)
    -    		{
    -    			$this->error='ErrorRefAlreadyExists';
    -    			dol_syslog(get_class($this)."::create ".$this->error,LOG_WARNING);
    -    			$this->db->rollback();
    -    			return -1;
    -    		}
    -    	}
    +		// Check parameters
    +		if (! empty($this->ref))	// We check that ref is not already used
    +		{
    +			$result=self::isExistingObject($this->element, 0, $this->ref);	// Check ref is not yet used
    +			if ($result > 0)
    +			{
    +				$this->error='ErrorRefAlreadyExists';
    +				dol_syslog(get_class($this)."::create ".$this->error,LOG_WARNING);
    +				$this->db->rollback();
    +				return -1;
    +			}
    +		}
     
    -        $soc = new Societe($this->db);
    -        $result=$soc->fetch($this->socid);
    -        if ($result < 0)
    -        {
    -            $this->error="Failed to fetch company";
    -            dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
    -            return -2;
    -        }
    -        if (! empty($conf->global->COMMANDE_REQUIRE_SOURCE) && $this->source < 0)
    -        {
    -            $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Source"));
    -            dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
    -            return -1;
    -        }
    +		$soc = new Societe($this->db);
    +		$result=$soc->fetch($this->socid);
    +		if ($result < 0)
    +		{
    +			$this->error="Failed to fetch company";
    +			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
    +			return -2;
    +		}
    +		if (! empty($conf->global->COMMANDE_REQUIRE_SOURCE) && $this->source < 0)
    +		{
    +			$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Source"));
    +			dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
    +			return -1;
    +		}
     
    -        $now=dol_now();
    +		$now=dol_now();
     
    -        $this->db->begin();
    +		$this->db->begin();
     
    -        $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande (";
    -        $sql.= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_ext, ref_client, ref_int";
    -        $sql.= ", model_pdf, fk_cond_reglement, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address";
    -        $sql.= ", fk_shipping_method";
    -        $sql.= ", fk_warehouse";
    -        $sql.= ", remise_absolue, remise_percent";
    -        $sql.= ", fk_incoterms, location_incoterms";
    -        $sql.= ", entity";
    -        $sql.= ", fk_multicurrency";
    -        $sql.= ", multicurrency_code";
    -        $sql.= ", multicurrency_tx";
    -        $sql.= ")";
    -        $sql.= " VALUES ('(PROV)', ".$this->socid.", '".$this->db->idate($now)."', ".$user->id;
    -        $sql.= ", ".($this->fk_project>0?$this->fk_project:"null");
    -        $sql.= ", '".$this->db->idate($date)."'";
    -        $sql.= ", ".($this->source>=0 && $this->source != '' ?$this->db->escape($this->source):'null');
    -        $sql.= ", '".$this->db->escape($this->note_private)."'";
    -        $sql.= ", '".$this->db->escape($this->note_public)."'";
    -        $sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null");
    -        $sql.= ", ".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null");
    -        $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
    -        $sql.= ", '".$this->db->escape($this->modelpdf)."'";
    -        $sql.= ", ".($this->cond_reglement_id>0?$this->cond_reglement_id:"null");
    -        $sql.= ", ".($this->mode_reglement_id>0?$this->mode_reglement_id:"null");
    -        $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL');
    -        $sql.= ", ".($this->availability_id>0?$this->availability_id:"null");
    -        $sql.= ", ".($this->demand_reason_id>0?$this->demand_reason_id:"null");
    -        $sql.= ", ".($this->date_livraison?"'".$this->db->idate($this->date_livraison)."'":"null");
    -        $sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:'NULL');
    -        $sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:'NULL');
    -        $sql.= ", ".($this->warehouse_id>0?$this->warehouse_id:'NULL');
    -        $sql.= ", ".($this->remise_absolue>0?$this->db->escape($this->remise_absolue):'NULL');
    -        $sql.= ", ".($this->remise_percent>0?$this->db->escape($this->remise_percent):0);
    -        $sql.= ", ".(int) $this->fk_incoterms;
    -        $sql.= ", '".$this->db->escape($this->location_incoterms)."'";
    -        $sql.= ", ".$conf->entity;
    +		$sql = "INSERT INTO ".MAIN_DB_PREFIX."commande (";
    +		$sql.= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_ext, ref_client, ref_int";
    +		$sql.= ", model_pdf, fk_cond_reglement, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address";
    +		$sql.= ", fk_shipping_method";
    +		$sql.= ", fk_warehouse";
    +		$sql.= ", remise_absolue, remise_percent";
    +		$sql.= ", fk_incoterms, location_incoterms";
    +		$sql.= ", entity";
    +		$sql.= ", fk_multicurrency";
    +		$sql.= ", multicurrency_code";
    +		$sql.= ", multicurrency_tx";
    +		$sql.= ")";
    +		$sql.= " VALUES ('(PROV)', ".$this->socid.", '".$this->db->idate($now)."', ".$user->id;
    +		$sql.= ", ".($this->fk_project>0?$this->fk_project:"null");
    +		$sql.= ", '".$this->db->idate($date)."'";
    +		$sql.= ", ".($this->source>=0 && $this->source != '' ?$this->db->escape($this->source):'null');
    +		$sql.= ", '".$this->db->escape($this->note_private)."'";
    +		$sql.= ", '".$this->db->escape($this->note_public)."'";
    +		$sql.= ", ".($this->ref_ext?"'".$this->db->escape($this->ref_ext)."'":"null");
    +		$sql.= ", ".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null");
    +		$sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
    +		$sql.= ", '".$this->db->escape($this->modelpdf)."'";
    +		$sql.= ", ".($this->cond_reglement_id>0?$this->cond_reglement_id:"null");
    +		$sql.= ", ".($this->mode_reglement_id>0?$this->mode_reglement_id:"null");
    +		$sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL');
    +		$sql.= ", ".($this->availability_id>0?$this->availability_id:"null");
    +		$sql.= ", ".($this->demand_reason_id>0?$this->demand_reason_id:"null");
    +		$sql.= ", ".($this->date_livraison?"'".$this->db->idate($this->date_livraison)."'":"null");
    +		$sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:'NULL');
    +		$sql.= ", ".($this->shipping_method_id>0?$this->shipping_method_id:'NULL');
    +		$sql.= ", ".($this->warehouse_id>0?$this->warehouse_id:'NULL');
    +		$sql.= ", ".($this->remise_absolue>0?$this->db->escape($this->remise_absolue):'NULL');
    +		$sql.= ", ".($this->remise_percent>0?$this->db->escape($this->remise_percent):0);
    +		$sql.= ", ".(int) $this->fk_incoterms;
    +		$sql.= ", '".$this->db->escape($this->location_incoterms)."'";
    +		$sql.= ", ".$conf->entity;
     		$sql.= ", ".(int) $this->fk_multicurrency;
     		$sql.= ", '".$this->db->escape($this->multicurrency_code)."'";
     		$sql.= ", ".(double) $this->multicurrency_tx;
    -        $sql.= ")";
    +		$sql.= ")";
     
    -        dol_syslog(get_class($this)."::create", LOG_DEBUG);
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    -            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'commande');
    +		dol_syslog(get_class($this)."::create", LOG_DEBUG);
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'commande');
     
    -            if ($this->id)
    -            {
    -                $fk_parent_line=0;
    -                $num=count($this->lines);
    +			if ($this->id)
    +			{
    +				$fk_parent_line=0;
    +				$num=count($this->lines);
     
    -                /*
    -                 *  Insert products details into db
    -                 */
    -                for ($i=0;$i<$num;$i++)
    -                {
    -                	$line = $this->lines[$i];
    +				/*
    +				 *  Insert products details into db
    +				 */
    +				for ($i=0;$i<$num;$i++)
    +				{
    +					$line = $this->lines[$i];
     
    -                	// Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array
    -				    //if (! is_object($line)) $line=json_decode(json_encode($line), false);  // convert recursively array into object.
    -                	if (! is_object($line)) $line = (object) $line;
    +					// Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array
    +					//if (! is_object($line)) $line=json_decode(json_encode($line), false);  // convert recursively array into object.
    +					if (! is_object($line)) $line = (object) $line;
     
    -                    // Reset fk_parent_line for no child products and special product
    -                    if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
    -                        $fk_parent_line = 0;
    -                    }
    +					// Reset fk_parent_line for no child products and special product
    +					if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
    +						$fk_parent_line = 0;
    +					}
     
     					// Complete vat rate with code
     					$vatrate = $line->tva_tx;
     					if ($line->vat_src_code && ! preg_match('/\(.*\)/', $vatrate)) $vatrate.=' ('.$line->vat_src_code.')';
     
    -                    $result = $this->addline(
    -                        $line->desc,
    -                        $line->subprice,
    -                        $line->qty,
    -                        $vatrate,
    -                        $line->localtax1_tx,
    -                        $line->localtax2_tx,
    -                        $line->fk_product,
    -                        $line->remise_percent,
    -                        $line->info_bits,
    -                        $line->fk_remise_except,
    -                        'HT',
    -                        0,
    -                        $line->date_start,
    -                        $line->date_end,
    -                        $line->product_type,
    -                        $line->rang,
    -                        $line->special_code,
    -                        $fk_parent_line,
    -                        $line->fk_fournprice,
    -                        $line->pa_ht,
    -                    	$line->label,
    -                    	$line->array_options,
    -	                    $line->fk_unit,
    -                        $this->element,
    -                        $line->id
    -                    );
    -                    if ($result < 0)
    -                    {
    -                    	if ($result != self::STOCK_NOT_ENOUGH_FOR_ORDER)
    -                    	{
    -                        	$this->error=$this->db->lasterror();
    -                        	dol_print_error($this->db);
    -                    	}
    -                        $this->db->rollback();
    -                        return -1;
    -                    }
    -                    // Defined the new fk_parent_line
    -                    if ($result > 0 && $line->product_type == 9) {
    -                        $fk_parent_line = $result;
    -                    }
    -                }
    -
    -                // update ref
    -                $initialref='(PROV'.$this->id.')';
    -                if (! empty($this->ref)) $initialref=$this->ref;
    -
    -                $sql = 'UPDATE '.MAIN_DB_PREFIX."commande SET ref='".$this->db->escape($initialref)."' WHERE rowid=".$this->id;
    -                if ($this->db->query($sql))
    -                {
    -                    if ($this->id)
    -                    {
    -                    	$this->ref = $initialref;
    -
    -                    	if (! empty($this->linkedObjectsIds) && empty($this->linked_objects))	// To use new linkedObjectsIds instead of old linked_objects
    -                    	{
    -                    		$this->linked_objects = $this->linkedObjectsIds;	// TODO Replace linked_objects with linkedObjectsIds
    -                    	}
    -
    -                        // Add object linked
    -                        if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
    -                        {
    -                        	foreach($this->linked_objects as $origin => $tmp_origin_id)
    -                        	{
    -                        	    if (is_array($tmp_origin_id))       // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
    -                        	    {
    -                        	        foreach($tmp_origin_id as $origin_id)
    -                        	        {
    -                        	            $ret = $this->add_object_linked($origin, $origin_id);
    -                        	            if (! $ret)
    -                        	            {
    -                        	                $this->error=$this->db->lasterror();
    -                        	                $error++;
    -                        	            }
    -                        	        }
    -                        	    }
    -                        	    else                                // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
    -                        	    {
    -                        	        $origin_id = $tmp_origin_id;
    -                        	        $ret = $this->add_object_linked($origin, $origin_id);
    -                        	        if (! $ret)
    -                        	        {
    -                        	            $this->error=$this->db->lasterror();
    -                        	            $error++;
    -                        	        }
    -                          	    }
    -                        	}
    -                        }
    -
    -            			if (! $error && $this->id && ! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && ! empty($this->origin) && ! empty($this->origin_id))   // Get contact from origin object
    -            			{
    -            				$originforcontact = $this->origin;
    -            				$originidforcontact = $this->origin_id;
    -                		    if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
    -                		    {
    -                		        require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
    -                		        $exp = new Expedition($this->db);
    -                		        $exp->fetch($this->origin_id);
    -                		        $exp->fetchObjectLinked();
    -                		        if (count($exp->linkedObjectsIds['commande']) > 0)
    -                		        {
    -                		            foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
    -                		            {
    -                		                $originforcontact = 'commande';
    -							            if (is_object($value)) $originidforcontact = $value->id;
    -							            else $originidforcontact = $value;
    -                		                break; // We take first one
    -                		            }
    -                		        }
    -                		    }
    -
    -                		    $sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
    -                		    $sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
    -
    -                		    $resqlcontact = $this->db->query($sqlcontact);
    -                		    if ($resqlcontact)
    -                		    {
    -                		        while($objcontact = $this->db->fetch_object($resqlcontact))
    -                		        {
    -        					        //print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
    -                		            $this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
    -                		        }
    -                		    }
    -                		    else dol_print_error($resqlcontact);
    -                		}
    -                    }
    -
    -                    if (! $error)
    -                    {
    -                   		$result=$this->insertExtraFields();
    -                   		if ($result < 0) $error++;
    -                    }
    -
    -                    if (! $error && ! $notrigger)
    -                    {
    -			            // Call trigger
    -			            $result=$this->call_trigger('ORDER_CREATE',$user);
    -			            if ($result < 0) $error++;
    -			            // End call triggers
    -                    }
    -
    -	                if (! $error)
    -	                {
    -		                $this->db->commit();
    -		                return $this->id;
    -	                }
    -	                else
    +					$result = $this->addline(
    +						$line->desc,
    +						$line->subprice,
    +						$line->qty,
    +						$vatrate,
    +						$line->localtax1_tx,
    +						$line->localtax2_tx,
    +						$line->fk_product,
    +						$line->remise_percent,
    +						$line->info_bits,
    +						$line->fk_remise_except,
    +						'HT',
    +						0,
    +						$line->date_start,
    +						$line->date_end,
    +						$line->product_type,
    +						$line->rang,
    +						$line->special_code,
    +						$fk_parent_line,
    +						$line->fk_fournprice,
    +						$line->pa_ht,
    +						$line->label,
    +						$line->array_options,
    +						$line->fk_unit,
    +						$this->element,
    +						$line->id
    +					);
    +					if ($result < 0)
     					{
    -	                	$this->db->rollback();
    -	                	return -1*$error;
    +						if ($result != self::STOCK_NOT_ENOUGH_FOR_ORDER)
    +						{
    +							$this->error=$this->db->lasterror();
    +							dol_print_error($this->db);
    +						}
    +						$this->db->rollback();
    +						return -1;
     					}
    -                }
    -                else
    +					// Defined the new fk_parent_line
    +					if ($result > 0 && $line->product_type == 9) {
    +						$fk_parent_line = $result;
    +					}
    +				}
    +
    +				// update ref
    +				$initialref='(PROV'.$this->id.')';
    +				if (! empty($this->ref)) $initialref=$this->ref;
    +
    +				$sql = 'UPDATE '.MAIN_DB_PREFIX."commande SET ref='".$this->db->escape($initialref)."' WHERE rowid=".$this->id;
    +				if ($this->db->query($sql))
    +				{
    +					if ($this->id)
    +					{
    +						$this->ref = $initialref;
    +
    +						if (! empty($this->linkedObjectsIds) && empty($this->linked_objects))	// To use new linkedObjectsIds instead of old linked_objects
    +						{
    +							$this->linked_objects = $this->linkedObjectsIds;	// TODO Replace linked_objects with linkedObjectsIds
    +						}
    +
    +						// Add object linked
    +						if (! $error && $this->id && is_array($this->linked_objects) && ! empty($this->linked_objects))
    +						{
    +							foreach($this->linked_objects as $origin => $tmp_origin_id)
    +							{
    +								if (is_array($tmp_origin_id))       // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
    +								{
    +									foreach($tmp_origin_id as $origin_id)
    +									{
    +										$ret = $this->add_object_linked($origin, $origin_id);
    +										if (! $ret)
    +										{
    +											$this->error=$this->db->lasterror();
    +											$error++;
    +										}
    +									}
    +								}
    +								else                                // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
    +								{
    +									$origin_id = $tmp_origin_id;
    +									$ret = $this->add_object_linked($origin, $origin_id);
    +									if (! $ret)
    +									{
    +										$this->error=$this->db->lasterror();
    +										$error++;
    +									}
    +								}
    +							}
    +						}
    +
    +						if (! $error && $this->id && ! empty($conf->global->MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN) && ! empty($this->origin) && ! empty($this->origin_id))   // Get contact from origin object
    +						{
    +							$originforcontact = $this->origin;
    +							$originidforcontact = $this->origin_id;
    +							if ($originforcontact == 'shipping')     // shipment and order share the same contacts. If creating from shipment we take data of order
    +							{
    +								require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php';
    +								$exp = new Expedition($this->db);
    +								$exp->fetch($this->origin_id);
    +								$exp->fetchObjectLinked();
    +								if (count($exp->linkedObjectsIds['commande']) > 0)
    +								{
    +									foreach ($exp->linkedObjectsIds['commande'] as $key => $value)
    +									{
    +										$originforcontact = 'commande';
    +										if (is_object($value)) $originidforcontact = $value->id;
    +										else $originidforcontact = $value;
    +										break; // We take first one
    +									}
    +								}
    +							}
    +
    +							$sqlcontact = "SELECT ctc.code, ctc.source, ec.fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
    +							$sqlcontact.= " WHERE element_id = ".$originidforcontact." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$originforcontact."'";
    +
    +							$resqlcontact = $this->db->query($sqlcontact);
    +							if ($resqlcontact)
    +							{
    +								while($objcontact = $this->db->fetch_object($resqlcontact))
    +								{
    +									//print $objcontact->code.'-'.$objcontact->source.'-'.$objcontact->fk_socpeople."\n";
    +									$this->add_contact($objcontact->fk_socpeople, $objcontact->code, $objcontact->source);    // May failed because of duplicate key or because code of contact type does not exists for new object
    +								}
    +							}
    +							else dol_print_error($resqlcontact);
    +						}
    +					}
    +
    +					if (! $error)
    +					{
    +						$result=$this->insertExtraFields();
    +						if ($result < 0) $error++;
    +					}
    +
    +					if (! $error && ! $notrigger)
    +					{
    +						// Call trigger
    +						$result=$this->call_trigger('ORDER_CREATE',$user);
    +						if ($result < 0) $error++;
    +						// End call triggers
    +					}
    +
    +					if (! $error)
    +					{
    +						$this->db->commit();
    +						return $this->id;
    +					}
    +					else
    +					{
    +						$this->db->rollback();
    +						return -1*$error;
    +					}
    +				}
    +				else
     				{
     					$this->error=$this->db->lasterror();
    -                    $this->db->rollback();
    -                    return -1;
    -                }
    -            }
    -        }
    -        else
    +					$this->db->rollback();
    +					return -1;
    +				}
    +			}
    +		}
    +		else
     		{
    -            dol_print_error($this->db);
    -            $this->db->rollback();
    -            return -1;
    -        }
    -    }
    +			dol_print_error($this->db);
    +			$this->db->rollback();
    +			return -1;
    +		}
    +	}
     
     
    -    /**
    -     *	Load an object from its id and create a new one in database
    -     *
    -     *	@param		int			$socid			Id of thirdparty
    -     *	@return		int							New id of clone
    -     */
    -    function createFromClone($socid=0)
    -    {
    -        global $user,$hookmanager;
    +	/**
    +	 *	Load an object from its id and create a new one in database
    +	 *
    +	 *	@param		int			$socid			Id of thirdparty
    +	 *	@return		int							New id of clone
    +	 */
    +	function createFromClone($socid=0)
    +	{
    +		global $user,$hookmanager;
     
    -        $error=0;
    +		$error=0;
     
    -        $this->context['createfromclone'] = 'createfromclone';
    +		$this->context['createfromclone'] = 'createfromclone';
     
    -        $this->db->begin();
    +		$this->db->begin();
     
     		// get lines so they will be clone
     		foreach($this->lines as $line)
     			$line->fetch_optionals();
     
    -        // Load source object
    -        $objFrom = clone $this;
    +			// Load source object
    +			$objFrom = clone $this;
     
    -        // Change socid if needed
    -        if (! empty($socid) && $socid != $this->socid)
    -        {
    -            $objsoc = new Societe($this->db);
    +			// Change socid if needed
    +			if (! empty($socid) && $socid != $this->socid)
    +			{
    +				$objsoc = new Societe($this->db);
     
    -            if ($objsoc->fetch($socid)>0)
    -            {
    -                $this->socid 				= $objsoc->id;
    -                $this->cond_reglement_id	= (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
    -                $this->mode_reglement_id	= (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
    -                $this->fk_project			= 0;
    -                $this->fk_delivery_address	= 0;
    -            }
    +				if ($objsoc->fetch($socid)>0)
    +				{
    +					$this->socid 				= $objsoc->id;
    +					$this->cond_reglement_id	= (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
    +					$this->mode_reglement_id	= (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
    +					$this->fk_project			= 0;
    +					$this->fk_delivery_address	= 0;
    +				}
     
    -            // TODO Change product price if multi-prices
    -        }
    +				// TODO Change product price if multi-prices
    +			}
     
    -        $this->id=0;
    -		$this->ref = '';
    -        $this->statut=self::STATUS_DRAFT;
    +			$this->id=0;
    +			$this->ref = '';
    +			$this->statut=self::STATUS_DRAFT;
     
    -        // Clear fields
    -        $this->user_author_id     = $user->id;
    -        $this->user_valid         = '';
    -		$this->date				  = dol_now();
    -		$this->date_commande	  = dol_now();
    -        $this->date_creation      = '';
    -        $this->date_validation    = '';
    -        $this->ref_client         = '';
    +			// Clear fields
    +			$this->user_author_id     = $user->id;
    +			$this->user_valid         = '';
    +			$this->date				  = dol_now();
    +			$this->date_commande	  = dol_now();
    +			$this->date_creation      = '';
    +			$this->date_validation    = '';
    +			$this->ref_client         = '';
     
    -        // Create clone
    -        $result=$this->create($user);
    -        if ($result < 0) $error++;
    +			// Create clone
    +			$result=$this->create($user);
    +			if ($result < 0) $error++;
     
    -        if (! $error)
    -        {
    -            // Hook of thirdparty module
    -            if (is_object($hookmanager))
    -            {
    -                $parameters=array('objFrom'=>$objFrom);
    -                $action='';
    -                $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    -                if ($reshook < 0) $error++;
    -            }
    -        }
    +			if (! $error)
    +			{
    +				// Hook of thirdparty module
    +				if (is_object($hookmanager))
    +				{
    +					$parameters=array('objFrom'=>$objFrom);
    +					$action='';
    +					$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +					if ($reshook < 0) $error++;
    +				}
    +			}
     
    -        unset($this->context['createfromclone']);
    +			unset($this->context['createfromclone']);
     
    -        // End
    -        if (! $error)
    -        {
    -            $this->db->commit();
    -            return $this->id;
    -        }
    -        else
    -        {
    -            $this->db->rollback();
    -            return -1;
    -        }
    -    }
    +			// End
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return $this->id;
    +			}
    +			else
    +			{
    +				$this->db->rollback();
    +				return -1;
    +			}
    +	}
     
     
    -    /**
    -     *  Load an object from a proposal and create a new order into database
    -     *
    -     *  @param      Object			$object 	        Object source
    -     *  @param		User			$user				User making creation
    -     *  @return     int             					<0 if KO, 0 if nothing done, 1 if OK
    -     */
    -    function createFromProposal($object, User $user)
    -    {
    -        global $conf, $hookmanager;
    +	/**
    +	 *  Load an object from a proposal and create a new order into database
    +	 *
    +	 *  @param      Object			$object 	        Object source
    +	 *  @param		User			$user				User making creation
    +	 *  @return     int             					<0 if KO, 0 if nothing done, 1 if OK
    +	 */
    +	function createFromProposal($object, User $user)
    +	{
    +		global $conf, $hookmanager;
     
     		dol_include_once('/core/class/extrafields.class.php');
     
    -        $error=0;
    +		$error=0;
     
     
    -        $this->date_commande = dol_now();
    -        $this->source = 0;
    +		$this->date_commande = dol_now();
    +		$this->source = 0;
     
    -        $num=count($object->lines);
    -        for ($i = 0; $i < $num; $i++)
    -        {
    -            $line = new OrderLine($this->db);
    +		$num=count($object->lines);
    +		for ($i = 0; $i < $num; $i++)
    +		{
    +			$line = new OrderLine($this->db);
     
    -            $line->libelle           = $object->lines[$i]->libelle;
    -            $line->label             = $object->lines[$i]->label;
    -            $line->desc              = $object->lines[$i]->desc;
    -            $line->price             = $object->lines[$i]->price;
    -            $line->subprice          = $object->lines[$i]->subprice;
    -            $line->vat_src_code      = $object->lines[$i]->vat_src_code;
    -            $line->tva_tx            = $object->lines[$i]->tva_tx;
    -            $line->localtax1_tx      = $object->lines[$i]->localtax1_tx;
    -            $line->localtax2_tx      = $object->lines[$i]->localtax2_tx;
    -            $line->qty               = $object->lines[$i]->qty;
    -            $line->fk_remise_except  = $object->lines[$i]->fk_remise_except;
    -            $line->remise_percent    = $object->lines[$i]->remise_percent;
    -            $line->fk_product        = $object->lines[$i]->fk_product;
    -            $line->info_bits         = $object->lines[$i]->info_bits;
    -            $line->product_type      = $object->lines[$i]->product_type;
    -            $line->rang              = $object->lines[$i]->rang;
    -            $line->special_code      = $object->lines[$i]->special_code;
    -            $line->fk_parent_line    = $object->lines[$i]->fk_parent_line;
    -	        $line->fk_unit			 = $object->lines[$i]->fk_unit;
    +			$line->libelle           = $object->lines[$i]->libelle;
    +			$line->label             = $object->lines[$i]->label;
    +			$line->desc              = $object->lines[$i]->desc;
    +			$line->price             = $object->lines[$i]->price;
    +			$line->subprice          = $object->lines[$i]->subprice;
    +			$line->vat_src_code      = $object->lines[$i]->vat_src_code;
    +			$line->tva_tx            = $object->lines[$i]->tva_tx;
    +			$line->localtax1_tx      = $object->lines[$i]->localtax1_tx;
    +			$line->localtax2_tx      = $object->lines[$i]->localtax2_tx;
    +			$line->qty               = $object->lines[$i]->qty;
    +			$line->fk_remise_except  = $object->lines[$i]->fk_remise_except;
    +			$line->remise_percent    = $object->lines[$i]->remise_percent;
    +			$line->fk_product        = $object->lines[$i]->fk_product;
    +			$line->info_bits         = $object->lines[$i]->info_bits;
    +			$line->product_type      = $object->lines[$i]->product_type;
    +			$line->rang              = $object->lines[$i]->rang;
    +			$line->special_code      = $object->lines[$i]->special_code;
    +			$line->fk_parent_line    = $object->lines[$i]->fk_parent_line;
    +			$line->fk_unit			 = $object->lines[$i]->fk_unit;
     
    -            $line->date_start      	= $object->lines[$i]->date_start;
    -            $line->date_end    		= $object->lines[$i]->date_end;
    +			$line->date_start      	= $object->lines[$i]->date_start;
    +			$line->date_end    		= $object->lines[$i]->date_end;
     
     			$line->fk_fournprice	= $object->lines[$i]->fk_fournprice;
     			$marginInfos			= getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
    @@ -1143,34 +1188,34 @@ class Commande extends CommonOrder
     			$line->marge_tx			= $marginInfos[1];
     			$line->marque_tx		= $marginInfos[2];
     
    -            // get extrafields from original line
    +			// get extrafields from original line
     			$object->lines[$i]->fetch_optionals();
     			foreach($object->lines[$i]->array_options as $options_key => $value)
     				$line->array_options[$options_key] = $value;
     
    -			$this->lines[$i] = $line;
    -        }
    +				$this->lines[$i] = $line;
    +		}
     
    -        $this->socid                = $object->socid;
    -        $this->fk_project           = $object->fk_project;
    -        $this->cond_reglement_id    = $object->cond_reglement_id;
    -        $this->mode_reglement_id    = $object->mode_reglement_id;
    -        $this->fk_account           = $object->fk_account;
    -        $this->availability_id      = $object->availability_id;
    -        $this->demand_reason_id     = $object->demand_reason_id;
    -        $this->date_livraison       = $object->date_livraison;
    -        $this->shipping_method_id   = $object->shipping_method_id;
    -        $this->warehouse_id         = $object->warehouse_id;
    -        $this->fk_delivery_address  = $object->fk_delivery_address;
    -        $this->contact_id           = $object->contactid;
    -        $this->ref_client           = $object->ref_client;
    -        $this->note_private         = $object->note_private;
    -        $this->note_public          = $object->note_public;
    +		$this->socid                = $object->socid;
    +		$this->fk_project           = $object->fk_project;
    +		$this->cond_reglement_id    = $object->cond_reglement_id;
    +		$this->mode_reglement_id    = $object->mode_reglement_id;
    +		$this->fk_account           = $object->fk_account;
    +		$this->availability_id      = $object->availability_id;
    +		$this->demand_reason_id     = $object->demand_reason_id;
    +		$this->date_livraison       = $object->date_livraison;
    +		$this->shipping_method_id   = $object->shipping_method_id;
    +		$this->warehouse_id         = $object->warehouse_id;
    +		$this->fk_delivery_address  = $object->fk_delivery_address;
    +		$this->contact_id           = $object->contactid;
    +		$this->ref_client           = $object->ref_client;
    +		$this->note_private         = $object->note_private;
    +		$this->note_public          = $object->note_public;
     
    -        $this->origin				= $object->element;
    -        $this->origin_id			= $object->id;
    +		$this->origin				= $object->element;
    +		$this->origin_id			= $object->id;
     
    -        // get extrafields from original line
    +		// get extrafields from original line
     		$object->fetch_optionals($object->id);
     
     		$e = new ExtraFields($this->db);
    @@ -1181,129 +1226,129 @@ class Commande extends CommonOrder
     				$this->array_options[$options_key] = $value;
     			}
     		}
    -        // Possibility to add external linked objects with hooks
    -        $this->linked_objects[$this->origin] = $this->origin_id;
    -        if (is_array($object->other_linked_objects) && ! empty($object->other_linked_objects))
    -        {
    -           	$this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
    -        }
    +		// Possibility to add external linked objects with hooks
    +		$this->linked_objects[$this->origin] = $this->origin_id;
    +		if (is_array($object->other_linked_objects) && ! empty($object->other_linked_objects))
    +		{
    +			$this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
    +		}
     
    -        $ret = $this->create($user);
    +		$ret = $this->create($user);
     
    -        if ($ret > 0)
    -        {
    -            // Actions hooked (by external module)
    -            $hookmanager->initHooks(array('orderdao'));
    +		if ($ret > 0)
    +		{
    +			// Actions hooked (by external module)
    +			$hookmanager->initHooks(array('orderdao'));
     
    -            $parameters=array('objFrom'=>$object);
    -            $action='';
    -            $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    -            if ($reshook < 0) $error++;
    +			$parameters=array('objFrom'=>$object);
    +			$action='';
    +			$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +			if ($reshook < 0) $error++;
     
    -            if (! $error)
    -            {
    -                // Ne pas passer par la commande provisoire
    -                if ($conf->global->COMMANDE_VALID_AFTER_CLOSE_PROPAL == 1)
    -                {
    -                    $this->fetch($ret);
    -                    $this->valid($user);
    -                }
    -                return $ret;
    -            }
    -            else return -1;
    -        }
    -        else return -1;
    -    }
    +			if (! $error)
    +			{
    +				// Ne pas passer par la commande provisoire
    +				if ($conf->global->COMMANDE_VALID_AFTER_CLOSE_PROPAL == 1)
    +				{
    +					$this->fetch($ret);
    +					$this->valid($user);
    +				}
    +				return $ret;
    +			}
    +			else return -1;
    +		}
    +		else return -1;
    +	}
     
     
    -    /**
    -     *	Add an order line into database (linked to product/service or not)
    -     *
    -     *	@param      string			$desc            	Description of line
    -     *	@param      float			$pu_ht    	        Unit price (without tax)
    -     *	@param      float			$qty             	Quantite
    -     * 	@param    	float			$txtva           	Force Vat rate, -1 for auto (Can contain the vat_src_code too with syntax '9.9 (CODE)')
    -     * 	@param		float			$txlocaltax1		Local tax 1 rate (deprecated, use instead txtva with code inside)
    -     * 	@param		float			$txlocaltax2		Local tax 2 rate (deprecated, use instead txtva with code inside)
    -     *	@param      int				$fk_product      	Id of product
    -     *	@param      float			$remise_percent  	Pourcentage de remise de la ligne
    -     *	@param      int				$info_bits			Bits de type de lignes
    -     *	@param      int				$fk_remise_except	Id remise
    -     *	@param      string			$price_base_type	HT or TTC
    -     *	@param      float			$pu_ttc    		    Prix unitaire TTC
    -     *	@param      int				$date_start       	Start date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    -     *	@param      int				$date_end         	End date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    -     *	@param      int				$type				Type of line (0=product, 1=service). Not used if fk_product is defined, the type of product is used.
    -     *	@param      int				$rang             	Position of line
    -     *	@param		int				$special_code		Special code (also used by externals modules!)
    -     *	@param		int				$fk_parent_line		Parent line
    -     *  @param		int				$fk_fournprice		Id supplier price
    -     *  @param		int				$pa_ht				Buying price (without tax)
    -     *  @param		string			$label				Label
    +	/**
    +	 *	Add an order line into database (linked to product/service or not)
    +	 *
    +	 *	@param      string			$desc            	Description of line
    +	 *	@param      float			$pu_ht    	        Unit price (without tax)
    +	 *	@param      float			$qty             	Quantite
    +	 * 	@param    	float			$txtva           	Force Vat rate, -1 for auto (Can contain the vat_src_code too with syntax '9.9 (CODE)')
    +	 * 	@param		float			$txlocaltax1		Local tax 1 rate (deprecated, use instead txtva with code inside)
    +	 * 	@param		float			$txlocaltax2		Local tax 2 rate (deprecated, use instead txtva with code inside)
    +	 *	@param      int				$fk_product      	Id of product
    +	 *	@param      float			$remise_percent  	Pourcentage de remise de la ligne
    +	 *	@param      int				$info_bits			Bits de type de lignes
    +	 *	@param      int				$fk_remise_except	Id remise
    +	 *	@param      string			$price_base_type	HT or TTC
    +	 *	@param      float			$pu_ttc    		    Prix unitaire TTC
    +	 *	@param      int				$date_start       	Start date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    +	 *	@param      int				$date_end         	End date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    +	 *	@param      int				$type				Type of line (0=product, 1=service). Not used if fk_product is defined, the type of product is used.
    +	 *	@param      int				$rang             	Position of line
    +	 *	@param		int				$special_code		Special code (also used by externals modules!)
    +	 *	@param		int				$fk_parent_line		Parent line
    +	 *  @param		int				$fk_fournprice		Id supplier price
    +	 *  @param		int				$pa_ht				Buying price (without tax)
    +	 *  @param		string			$label				Label
     	 *  @param		array			$array_options		extrafields array. Example array('options_codeforfield1'=>'valueforfield1', 'options_codeforfield2'=>'valueforfield2', ...)
    -     * 	@param 		string			$fk_unit 			Code of the unit to use. Null to use the default one
    -     * 	@param		string		    $origin				'order', ...
    -     *  @param		int			    $origin_id			Id of origin object
    +	 * 	@param 		string			$fk_unit 			Code of the unit to use. Null to use the default one
    +	 * 	@param		string		    $origin				'order', ...
    +	 *  @param		int			    $origin_id			Id of origin object
     	 * 	@param		double			$pu_ht_devise		Unit price in currency
    -     *	@return     int             					>0 if OK, <0 if KO
    -     *
    -     *	@see        add_product
    -     *
    -     *	Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
    -     *	de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
    -     *	par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit)
    -     *	et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
    -     */
    +	 *	@return     int             					>0 if OK, <0 if KO
    +	 *
    +	 *	@see        add_product
    +	 *
    +	 *	Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
    +	 *	de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
    +	 *	par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit)
    +	 *	et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
    +	 */
     	function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $info_bits=0, $fk_remise_except=0, $price_base_type='HT', $pu_ttc=0, $date_start='', $date_end='', $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht=0, $label='',$array_options=0, $fk_unit=null, $origin='', $origin_id=0, $pu_ht_devise = 0)
    -    {
    -    	global $mysoc, $conf, $langs, $user;
    +	{
    +		global $mysoc, $conf, $langs, $user;
     
     		$logtext = "::addline commandeid=$this->id, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_percent=$remise_percent";
     		$logtext.= ", info_bits=$info_bits, fk_remise_except=$fk_remise_except, price_base_type=$price_base_type, pu_ttc=$pu_ttc, date_start=$date_start";
     		$logtext.= ", date_end=$date_end, type=$type special_code=$special_code, fk_unit=$fk_unit, origin=$origin, origin_id=$origin_id, pu_ht_devise=$pu_ht_devise";
    -        dol_syslog(get_class($this).$logtext, LOG_DEBUG);
    +		dol_syslog(get_class($this).$logtext, LOG_DEBUG);
     
    -        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    +		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
     
    -        // Clean parameters
    -        if (empty($remise_percent)) $remise_percent=0;
    -        if (empty($qty)) $qty=0;
    -        if (empty($info_bits)) $info_bits=0;
    -        if (empty($rang)) $rang=0;
    -        if (empty($txtva)) $txtva=0;
    -        if (empty($txlocaltax1)) $txlocaltax1=0;
    -        if (empty($txlocaltax2)) $txlocaltax2=0;
    -        if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
    -        if (empty($this->fk_multicurrency)) $this->fk_multicurrency=0;
    +		// Clean parameters
    +		if (empty($remise_percent)) $remise_percent=0;
    +		if (empty($qty)) $qty=0;
    +		if (empty($info_bits)) $info_bits=0;
    +		if (empty($rang)) $rang=0;
    +		if (empty($txtva)) $txtva=0;
    +		if (empty($txlocaltax1)) $txlocaltax1=0;
    +		if (empty($txlocaltax2)) $txlocaltax2=0;
    +		if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
    +		if (empty($this->fk_multicurrency)) $this->fk_multicurrency=0;
     
    -        $remise_percent=price2num($remise_percent);
    -        $qty=price2num($qty);
    -        $pu_ht=price2num($pu_ht);
    -        $pu_ht_devise=price2num($pu_ht_devise);
    -        $pu_ttc=price2num($pu_ttc);
    -    	$pa_ht=price2num($pa_ht);
    -        $txtva = price2num($txtva);
    -        $txlocaltax1 = price2num($txlocaltax1);
    -        $txlocaltax2 = price2num($txlocaltax2);
    -        if ($price_base_type=='HT')
    -        {
    -            $pu=$pu_ht;
    -        }
    -        else
    -        {
    -            $pu=$pu_ttc;
    -        }
    -        $label=trim($label);
    -        $desc=trim($desc);
    +		$remise_percent=price2num($remise_percent);
    +		$qty=price2num($qty);
    +		$pu_ht=price2num($pu_ht);
    +		$pu_ht_devise=price2num($pu_ht_devise);
    +		$pu_ttc=price2num($pu_ttc);
    +		$pa_ht=price2num($pa_ht);
    +		$txtva = price2num($txtva);
    +		$txlocaltax1 = price2num($txlocaltax1);
    +		$txlocaltax2 = price2num($txlocaltax2);
    +		if ($price_base_type=='HT')
    +		{
    +			$pu=$pu_ht;
    +		}
    +		else
    +		{
    +			$pu=$pu_ttc;
    +		}
    +		$label=trim($label);
    +		$desc=trim($desc);
     
    -        // Check parameters
    -        if ($type < 0) return -1;
    +		// Check parameters
    +		if ($type < 0) return -1;
     
    -        if ($this->statut == self::STATUS_DRAFT)
    -        {
    -            $this->db->begin();
    +		if ($this->statut == self::STATUS_DRAFT)
    +		{
    +			$this->db->begin();
     
    -        	$product_type=$type;
    +			$product_type=$type;
     			if (!empty($fk_product))
     			{
     				$product=new Product($this->db);
    @@ -1312,105 +1357,105 @@ class Commande extends CommonOrder
     
     				if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER) && $product_type == 0 && $product->stock_reel < $qty)
     				{
    -                    $langs->load("errors");
    -				    $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnOrder', $product->ref);
    +					$langs->load("errors");
    +					$this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnOrder', $product->ref);
     					dol_syslog(get_class($this)."::addline error=Product ".$product->ref.": ".$this->error, LOG_ERR);
     					$this->db->rollback();
     					return self::STOCK_NOT_ENOUGH_FOR_ORDER;
     				}
     			}
     			// Calcul du total TTC et de la TVA pour la ligne a partir de
    -            // qty, pu, remise_percent et txtva
    -            // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
    -            // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
    +			// qty, pu, remise_percent et txtva
    +			// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
    +			// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
     
    -            $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc);
    +			$localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc);
     
    -       		// Clean vat code
    -    		$vat_src_code='';
    -    		if (preg_match('/\((.*)\)/', $txtva, $reg))
    -    		{
    -    		    $vat_src_code = $reg[1];
    -    		    $txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
    -    		}
    +			// Clean vat code
    +			$vat_src_code='';
    +			if (preg_match('/\((.*)\)/', $txtva, $reg))
    +			{
    +				$vat_src_code = $reg[1];
    +				$txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
    +			}
     
    -            $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
    +			$tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
     
    -            /*var_dump($txlocaltax1);
    -            var_dump($txlocaltax2);
    -            var_dump($localtaxes_type);
    -            var_dump($tabprice);
    -            var_dump($tabprice[9]);
    -            var_dump($tabprice[10]);
    -            exit;*/
    +			/*var_dump($txlocaltax1);
    +			 var_dump($txlocaltax2);
    +			 var_dump($localtaxes_type);
    +			 var_dump($tabprice);
    +			 var_dump($tabprice[9]);
    +			 var_dump($tabprice[10]);
    +			 exit;*/
     
    -            $total_ht  = $tabprice[0];
    -            $total_tva = $tabprice[1];
    -            $total_ttc = $tabprice[2];
    -            $total_localtax1 = $tabprice[9];
    -            $total_localtax2 = $tabprice[10];
    +			$total_ht  = $tabprice[0];
    +			$total_tva = $tabprice[1];
    +			$total_ttc = $tabprice[2];
    +			$total_localtax1 = $tabprice[9];
    +			$total_localtax2 = $tabprice[10];
     			$pu_ht = $tabprice[3];
     
     			// MultiCurrency
     			$multicurrency_total_ht  = $tabprice[16];
    -            $multicurrency_total_tva = $tabprice[17];
    -            $multicurrency_total_ttc = $tabprice[18];
    +			$multicurrency_total_tva = $tabprice[17];
    +			$multicurrency_total_ttc = $tabprice[18];
     			$pu_ht_devise = $tabprice[19];
     
    -            // Rang to use
    -            $rangtouse = $rang;
    -            if ($rangtouse == -1)
    -            {
    -                $rangmax = $this->line_max($fk_parent_line);
    -                $rangtouse = $rangmax + 1;
    -            }
    +			// Rang to use
    +			$rangtouse = $rang;
    +			if ($rangtouse == -1)
    +			{
    +				$rangmax = $this->line_max($fk_parent_line);
    +				$rangtouse = $rangmax + 1;
    +			}
     
    -            // TODO A virer
    -            // Anciens indicateurs: $price, $remise (a ne plus utiliser)
    -            $price = $pu;
    -            $remise = 0;
    -            if ($remise_percent > 0)
    -            {
    -                $remise = round(($pu * $remise_percent / 100), 2);
    -                $price = $pu - $remise;
    -            }
    +			// TODO A virer
    +			// Anciens indicateurs: $price, $remise (a ne plus utiliser)
    +			$price = $pu;
    +			$remise = 0;
    +			if ($remise_percent > 0)
    +			{
    +				$remise = round(($pu * $remise_percent / 100), 2);
    +				$price = $pu - $remise;
    +			}
     
    -            // Insert line
    -            $this->line=new OrderLine($this->db);
    +			// Insert line
    +			$this->line=new OrderLine($this->db);
     
    -            $this->line->context = $this->context;
    +			$this->line->context = $this->context;
     
    -            $this->line->fk_commande=$this->id;
    -            $this->line->label=$label;
    -            $this->line->desc=$desc;
    -            $this->line->qty=$qty;
    +			$this->line->fk_commande=$this->id;
    +			$this->line->label=$label;
    +			$this->line->desc=$desc;
    +			$this->line->qty=$qty;
     
    -            $this->line->vat_src_code=$vat_src_code;
    -            $this->line->tva_tx=$txtva;
    -            $this->line->localtax1_tx=($total_localtax1?$localtaxes_type[1]:0);
    -            $this->line->localtax2_tx=($total_localtax2?$localtaxes_type[3]:0);
    -            $this->line->localtax1_type=$localtaxes_type[0];
    -            $this->line->localtax2_type=$localtaxes_type[2];
    -            $this->line->fk_product=$fk_product;
    +			$this->line->vat_src_code=$vat_src_code;
    +			$this->line->tva_tx=$txtva;
    +			$this->line->localtax1_tx=($total_localtax1?$localtaxes_type[1]:0);
    +			$this->line->localtax2_tx=($total_localtax2?$localtaxes_type[3]:0);
    +			$this->line->localtax1_type=$localtaxes_type[0];
    +			$this->line->localtax2_type=$localtaxes_type[2];
    +			$this->line->fk_product=$fk_product;
     			$this->line->product_type=$product_type;
    -            $this->line->fk_remise_except=$fk_remise_except;
    -            $this->line->remise_percent=$remise_percent;
    -            $this->line->subprice=$pu_ht;
    -            $this->line->rang=$rangtouse;
    -            $this->line->info_bits=$info_bits;
    -            $this->line->total_ht=$total_ht;
    -            $this->line->total_tva=$total_tva;
    -            $this->line->total_localtax1=$total_localtax1;
    -            $this->line->total_localtax2=$total_localtax2;
    -            $this->line->total_ttc=$total_ttc;
    -            $this->line->special_code=$special_code;
    -            $this->line->origin=$origin;
    -            $this->line->origin_id=$origin_id;
    -            $this->line->fk_parent_line=$fk_parent_line;
    -	        $this->line->fk_unit=$fk_unit;
    +			$this->line->fk_remise_except=$fk_remise_except;
    +			$this->line->remise_percent=$remise_percent;
    +			$this->line->subprice=$pu_ht;
    +			$this->line->rang=$rangtouse;
    +			$this->line->info_bits=$info_bits;
    +			$this->line->total_ht=$total_ht;
    +			$this->line->total_tva=$total_tva;
    +			$this->line->total_localtax1=$total_localtax1;
    +			$this->line->total_localtax2=$total_localtax2;
    +			$this->line->total_ttc=$total_ttc;
    +			$this->line->special_code=$special_code;
    +			$this->line->origin=$origin;
    +			$this->line->origin_id=$origin_id;
    +			$this->line->fk_parent_line=$fk_parent_line;
    +			$this->line->fk_unit=$fk_unit;
     
    -            $this->line->date_start=$date_start;
    -            $this->line->date_end=$date_end;
    +			$this->line->date_start=$date_start;
    +			$this->line->date_end=$date_end;
     
     			$this->line->fk_fournprice = $fk_fournprice;
     			$this->line->pa_ht = $pa_ht;
    @@ -1420,187 +1465,190 @@ class Commande extends CommonOrder
     			$this->line->multicurrency_code			= $this->multicurrency_code;
     			$this->line->multicurrency_subprice		= $pu_ht_devise;
     			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
    -            $this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
    -            $this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
    +			$this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
    +			$this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
     
    -            // TODO Ne plus utiliser
    -            $this->line->price=$price;
    -            $this->line->remise=$remise;
    +			// TODO Ne plus utiliser
    +			$this->line->price=$price;
    +			$this->line->remise=$remise;
     
     			if (is_array($array_options) && count($array_options)>0) {
     				$this->line->array_options=$array_options;
     			}
     
    -            $result=$this->line->insert($user);
    -            if ($result > 0)
    -            {
    -                // Reorder if child line
    -                if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
    +			$result=$this->line->insert($user);
    +			if ($result > 0)
    +			{
    +				// Reorder if child line
    +				if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
     
    -                // Mise a jour informations denormalisees au niveau de la commande meme
    -                $result=$this->update_price(1,'auto',0,$mysoc);	// This method is designed to add line from user input so total calculation must be done using 'auto' mode.
    -                if ($result > 0)
    -                {
    -                    $this->db->commit();
    -                    return $this->line->rowid;
    -                }
    -                else
    -                {
    -                    $this->db->rollback();
    -                    return -1;
    -                }
    -            }
    -            else
    -            {
    -                $this->error=$this->line->error;
    -                dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR);
    -                $this->db->rollback();
    -                return -2;
    -            }
    -        }
    +				// Mise a jour informations denormalisees au niveau de la commande meme
    +				$result=$this->update_price(1,'auto',0,$mysoc);	// This method is designed to add line from user input so total calculation must be done using 'auto' mode.
    +				if ($result > 0)
    +				{
    +					$this->db->commit();
    +					return $this->line->rowid;
    +				}
    +				else
    +				{
    +					$this->db->rollback();
    +					return -1;
    +				}
    +			}
    +			else
    +			{
    +				$this->error=$this->line->error;
    +				dol_syslog(get_class($this)."::addline error=".$this->error, LOG_ERR);
    +				$this->db->rollback();
    +				return -2;
    +			}
    +		}
     		else
     		{
    -            dol_syslog(get_class($this)."::addline status of order must be Draft to allow use of ->addline()", LOG_ERR);
    +			dol_syslog(get_class($this)."::addline status of order must be Draft to allow use of ->addline()", LOG_ERR);
     			return -3;
    -        }
    -    }
    +		}
    +	}
     
     
    -    /**
    -     *	Add line into array
    -     *	$this->client must be loaded
    -     *
    -     *	@param		int				$idproduct			Product Id
    -     *	@param		float			$qty				Quantity
    -     *	@param		float			$remise_percent		Product discount relative
    -     * 	@param    	int		$date_start         Start date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    -     * 	@param    	int		$date_end           End date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    -     * 	@return    	void
    -     *
    -     *	TODO	Remplacer les appels a cette fonction par generation objet Ligne
    -     *			insere dans tableau $this->products
    -     */
    -    function add_product($idproduct, $qty, $remise_percent=0.0, $date_start='', $date_end='')
    -    {
    -        global $conf, $mysoc;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Add line into array
    +	 *	$this->client must be loaded
    +	 *
    +	 *	@param		int				$idproduct			Product Id
    +	 *	@param		float			$qty				Quantity
    +	 *	@param		float			$remise_percent		Product discount relative
    +	 * 	@param    	int		$date_start         Start date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    +	 * 	@param    	int		$date_end           End date of the line - Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    +	 * 	@return    	void
    +	 *
    +	 *	TODO	Remplacer les appels a cette fonction par generation objet Ligne
    +	 *			insere dans tableau $this->products
    +	 */
    +	function add_product($idproduct, $qty, $remise_percent=0.0, $date_start='', $date_end='')
    +	{
    +        // phpcs:enable
    +		global $conf, $mysoc;
     
    -        if (! $qty) $qty = 1;
    +		if (! $qty) $qty = 1;
     
    -        if ($idproduct > 0)
    -        {
    -            $prod=new Product($this->db);
    -            $prod->fetch($idproduct);
    +		if ($idproduct > 0)
    +		{
    +			$prod=new Product($this->db);
    +			$prod->fetch($idproduct);
     
    -            $tva_tx = get_default_tva($mysoc,$this->thirdparty,$prod->id);
    -            $tva_npr = get_default_npr($mysoc,$this->thirdparty,$prod->id);
    -            if (empty($tva_tx)) $tva_npr=0;
    -            $vat_src_code = '';     // May be defined into tva_tx
    +			$tva_tx = get_default_tva($mysoc,$this->thirdparty,$prod->id);
    +			$tva_npr = get_default_npr($mysoc,$this->thirdparty,$prod->id);
    +			if (empty($tva_tx)) $tva_npr=0;
    +			$vat_src_code = '';     // May be defined into tva_tx
     
    -            $localtax1_tx=get_localtax($tva_tx,1,$this->thirdparty,$mysoc,$tva_npr);
    -            $localtax2_tx=get_localtax($tva_tx,2,$this->thirdparty,$mysoc,$tva_npr);
    +			$localtax1_tx=get_localtax($tva_tx,1,$this->thirdparty,$mysoc,$tva_npr);
    +			$localtax2_tx=get_localtax($tva_tx,2,$this->thirdparty,$mysoc,$tva_npr);
     
    -            // multiprix
    -            if($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level)
    -            $price = $prod->multiprices[$this->thirdparty->price_level];
    -            else
    -            $price = $prod->price;
    +			// multiprix
    +			if($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
    +				$price = $prod->multiprices[$this->thirdparty->price_level];
    +			} else {
    +				$price = $prod->price;
    +			}
     
    -            $line=new OrderLine($this->db);
    +			$line=new OrderLine($this->db);
     
    -            $line->context = $this->context;
    +			$line->context = $this->context;
     
    -            $line->fk_product=$idproduct;
    -            $line->desc=$prod->description;
    -            $line->qty=$qty;
    -            $line->subprice=$price;
    -            $line->remise_percent=$remise_percent;
    -            $line->vat_src_code=$vat_src_code;
    -            $line->tva_tx=$tva_tx;
    -            $line->localtax1_tx=$localtax1_tx;
    -            $line->localtax2_tx=$localtax2_tx;
    -            $line->ref=$prod->ref;
    -            $line->libelle=$prod->label;
    -            $line->product_desc=$prod->description;
    -	        $line->fk_unit=$prod->fk_unit;
    +			$line->fk_product=$idproduct;
    +			$line->desc=$prod->description;
    +			$line->qty=$qty;
    +			$line->subprice=$price;
    +			$line->remise_percent=$remise_percent;
    +			$line->vat_src_code=$vat_src_code;
    +			$line->tva_tx=$tva_tx;
    +			$line->localtax1_tx=$localtax1_tx;
    +			$line->localtax2_tx=$localtax2_tx;
    +			$line->ref=$prod->ref;
    +			$line->libelle=$prod->label;
    +			$line->product_desc=$prod->description;
    +			$line->fk_unit=$prod->fk_unit;
     
    -            // Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    -            // Save the start and end date of the line in the object
    -            if ($date_start) { $line->date_start = $date_start; }
    -            if ($date_end)   { $line->date_end = $date_end; }
    +			// Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    +			// Save the start and end date of the line in the object
    +			if ($date_start) { $line->date_start = $date_start; }
    +			if ($date_end)   { $line->date_end = $date_end; }
     
    -            $this->lines[] = $line;
    +			$this->lines[] = $line;
     
    -            /** POUR AJOUTER AUTOMATIQUEMENT LES SOUSPRODUITS a LA COMMANDE
    -             if (! empty($conf->global->PRODUIT_SOUSPRODUITS))
    -             {
    -             $prod = new Product($this->db);
    -             $prod->fetch($idproduct);
    -             $prod -> get_sousproduits_arbo();
    -             $prods_arbo = $prod->get_arbo_each_prod();
    -             if(count($prods_arbo) > 0)
    -             {
    -             foreach($prods_arbo as $key => $value)
    -             {
    -             // print "id : ".$value[1].' :qty: '.$value[0].'<br>';
    -             if(! in_array($value[1],$this->products))
    -             $this->add_product($value[1], $value[0]);
    +			/** POUR AJOUTER AUTOMATIQUEMENT LES SOUSPRODUITS a LA COMMANDE
    +			 if (! empty($conf->global->PRODUIT_SOUSPRODUITS))
    +			 {
    +			 $prod = new Product($this->db);
    +			 $prod->fetch($idproduct);
    +			 $prod -> get_sousproduits_arbo();
    +			 $prods_arbo = $prod->get_arbo_each_prod();
    +			 if(count($prods_arbo) > 0)
    +			 {
    +			 foreach($prods_arbo as $key => $value)
    +			 {
    +			 // print "id : ".$value[1].' :qty: '.$value[0].'<br>';
    +			 if(! in_array($value[1],$this->products))
    +			 $this->add_product($value[1], $value[0]);
     
    -             }
    -             }
    +			 }
    +			 }
     
    -             }
    -             **/
    -        }
    -    }
    +			 }
    +			 **/
    +		}
    +	}
     
     
    -    /**
    -     *	Get object and lines from database
    -     *
    -     *	@param      int			$id       		Id of object to load
    -     * 	@param		string		$ref			Ref of object
    -     * 	@param		string		$ref_ext		External reference of object
    -     * 	@param		string		$ref_int		Internal reference of other object
    -     *	@return     int         				>0 if OK, <0 if KO, 0 if not found
    -     */
    -    function fetch($id, $ref='', $ref_ext='', $ref_int='')
    -    {
    +	/**
    +	 *	Get object and lines from database
    +	 *
    +	 *	@param      int			$id       		Id of object to load
    +	 * 	@param		string		$ref			Ref of object
    +	 * 	@param		string		$ref_ext		External reference of object
    +	 * 	@param		string		$ref_int		Internal reference of other object
    +	 *	@return     int         				>0 if OK, <0 if KO, 0 if not found
    +	 */
    +	function fetch($id, $ref='', $ref_ext='', $ref_int='')
    +	{
     
    -        // Check parameters
    -        if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
    +		// Check parameters
    +		if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
     
    -        $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_statut';
    -        $sql.= ', c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason';
    -        $sql.= ', c.fk_account';
    -        $sql.= ', c.date_commande';
    -        $sql.= ', c.date_livraison';
    -        $sql.= ', c.fk_shipping_method';
    -        $sql.= ', c.fk_warehouse';
    -        $sql.= ', c.fk_projet, c.remise_percent, c.remise, c.remise_absolue, c.source, c.facture as billed';
    -        $sql.= ', c.note_private, c.note_public, c.ref_client, c.ref_ext, c.ref_int, c.model_pdf, c.last_main_doc, c.fk_delivery_address, c.extraparams';
    -        $sql.= ', c.fk_incoterms, c.location_incoterms';
    +		$sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_statut';
    +		$sql.= ', c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason';
    +		$sql.= ', c.fk_account';
    +		$sql.= ', c.date_commande, c.date_valid, c.tms';
    +		$sql.= ', c.date_livraison';
    +		$sql.= ', c.fk_shipping_method';
    +		$sql.= ', c.fk_warehouse';
    +		$sql.= ', c.fk_projet, c.remise_percent, c.remise, c.remise_absolue, c.source, c.facture as billed';
    +		$sql.= ', c.note_private, c.note_public, c.ref_client, c.ref_ext, c.ref_int, c.model_pdf, c.last_main_doc, c.fk_delivery_address, c.extraparams';
    +		$sql.= ', c.fk_incoterms, c.location_incoterms';
     		$sql.= ", c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multicurrency_total_ht, c.multicurrency_total_tva, c.multicurrency_total_ttc";
    -        $sql.= ", i.libelle as libelle_incoterms";
    -        $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
    -        $sql.= ', cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle, cr.libelle_facture as cond_reglement_libelle_doc';
    -        $sql.= ', ca.code as availability_code, ca.label as availability_label';
    -        $sql.= ', dr.code as demand_reason_code';
    -        $sql.= ' FROM '.MAIN_DB_PREFIX.'commande as c';
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON c.fk_cond_reglement = cr.rowid';
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON c.fk_mode_reglement = p.id';
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON c.fk_availability = ca.rowid';
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON c.fk_input_reason = ca.rowid';
    +		$sql.= ", i.libelle as libelle_incoterms";
    +		$sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle';
    +		$sql.= ', cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle, cr.libelle_facture as cond_reglement_libelle_doc';
    +		$sql.= ', ca.code as availability_code, ca.label as availability_label';
    +		$sql.= ', dr.code as demand_reason_code';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'commande as c';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON c.fk_cond_reglement = cr.rowid';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as p ON c.fk_mode_reglement = p.id';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON c.fk_availability = ca.rowid';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON c.fk_input_reason = ca.rowid';
     		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid';
     
     		if ($id) $sql.= " WHERE c.rowid=".$id;
     		else $sql.= " WHERE c.entity IN (".getEntity('commande').")"; // Dont't use entity if you use rowid
     
    -        if ($ref)     $sql.= " AND c.ref='".$this->db->escape($ref)."'";
    -        if ($ref_ext) $sql.= " AND c.ref_ext='".$this->db->escape($ref_ext)."'";
    -        if ($ref_int) $sql.= " AND c.ref_int='".$this->db->escape($ref_int)."'";
    +		if ($ref)     $sql.= " AND c.ref='".$this->db->escape($ref)."'";
    +		if ($ref_ext) $sql.= " AND c.ref_ext='".$this->db->escape($ref_ext)."'";
    +		if ($ref_int) $sql.= " AND c.ref_int='".$this->db->escape($ref_int)."'";
     
    -        dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
    -        $result = $this->db->query($sql);
    +		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
    +		$result = $this->db->query($sql);
     		if ($result)
     		{
     			$obj = $this->db->fetch_object($result);
    @@ -1609,50 +1657,53 @@ class Commande extends CommonOrder
     				$this->id					= $obj->rowid;
     				$this->entity				= $obj->entity;
     
    -                $this->ref					= $obj->ref;
    -                $this->ref_client			= $obj->ref_client;
    -                $this->ref_customer			= $obj->ref_client;
    -                $this->ref_ext				= $obj->ref_ext;
    -                $this->ref_int				= $obj->ref_int;
    -                $this->socid				= $obj->fk_soc;
    -                $this->statut				= $obj->fk_statut;
    -                $this->user_author_id		= $obj->fk_user_author;
    -                $this->user_valid           = $obj->fk_user_valid;
    -                $this->total_ht				= $obj->total_ht;
    -                $this->total_tva			= $obj->total_tva;
    -                $this->total_localtax1		= $obj->total_localtax1;
    -                $this->total_localtax2		= $obj->total_localtax2;
    -                $this->total_ttc			= $obj->total_ttc;
    -                $this->date					= $this->db->jdate($obj->date_commande);
    -                $this->date_commande		= $this->db->jdate($obj->date_commande);
    -                $this->remise				= $obj->remise;
    -                $this->remise_percent		= $obj->remise_percent;
    -                $this->remise_absolue		= $obj->remise_absolue;
    -                $this->source				= $obj->source;
    -                $this->billed				= $obj->billed;
    -                $this->note					= $obj->note_private;	// deprecated
    -                $this->note_private			= $obj->note_private;
    -                $this->note_public			= $obj->note_public;
    -                $this->fk_project			= $obj->fk_projet;
    -                $this->modelpdf				= $obj->model_pdf;
    -                $this->last_main_doc		= $obj->last_main_doc;
    -                $this->mode_reglement_id	= $obj->fk_mode_reglement;
    -                $this->mode_reglement_code	= $obj->mode_reglement_code;
    -                $this->mode_reglement		= $obj->mode_reglement_libelle;
    -                $this->cond_reglement_id	= $obj->fk_cond_reglement;
    -                $this->cond_reglement_code	= $obj->cond_reglement_code;
    -                $this->cond_reglement		= $obj->cond_reglement_libelle;
    -                $this->cond_reglement_doc	= $obj->cond_reglement_libelle_doc;
    -                $this->fk_account           = $obj->fk_account;
    -                $this->availability_id		= $obj->fk_availability;
    -                $this->availability_code	= $obj->availability_code;
    -                $this->availability	    	= $obj->availability_label;
    -                $this->demand_reason_id		= $obj->fk_input_reason;
    -                $this->demand_reason_code	= $obj->demand_reason_code;
    -                $this->date_livraison		= $this->db->jdate($obj->date_livraison);
    -                $this->shipping_method_id   = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null;
    -                $this->warehouse_id           = ($obj->fk_warehouse>0)?$obj->fk_warehouse:null;
    -                $this->fk_delivery_address	= $obj->fk_delivery_address;
    +				$this->ref					= $obj->ref;
    +				$this->ref_client			= $obj->ref_client;
    +				$this->ref_customer			= $obj->ref_client;
    +				$this->ref_ext				= $obj->ref_ext;
    +				$this->ref_int				= $obj->ref_int;
    +				$this->socid				= $obj->fk_soc;
    +				$this->statut				= $obj->fk_statut;
    +				$this->user_author_id		= $obj->fk_user_author;
    +				$this->user_valid           = $obj->fk_user_valid;
    +				$this->total_ht				= $obj->total_ht;
    +				$this->total_tva			= $obj->total_tva;
    +				$this->total_localtax1		= $obj->total_localtax1;
    +				$this->total_localtax2		= $obj->total_localtax2;
    +				$this->total_ttc			= $obj->total_ttc;
    +				$this->date					= $this->db->jdate($obj->date_commande);
    +				$this->date_commande		= $this->db->jdate($obj->date_commande);
    +				$this->date_creation		= $this->db->jdate($obj->date_creation);
    +				$this->date_validation		= $this->db->jdate($obj->date_valid);
    +				$this->date_modification		= $this->db->jdate($obj->tms);
    +				$this->remise				= $obj->remise;
    +				$this->remise_percent		= $obj->remise_percent;
    +				$this->remise_absolue		= $obj->remise_absolue;
    +				$this->source				= $obj->source;
    +				$this->billed				= $obj->billed;
    +				$this->note					= $obj->note_private;	// deprecated
    +				$this->note_private			= $obj->note_private;
    +				$this->note_public			= $obj->note_public;
    +				$this->fk_project			= $obj->fk_projet;
    +				$this->modelpdf				= $obj->model_pdf;
    +				$this->last_main_doc		= $obj->last_main_doc;
    +				$this->mode_reglement_id	= $obj->fk_mode_reglement;
    +				$this->mode_reglement_code	= $obj->mode_reglement_code;
    +				$this->mode_reglement		= $obj->mode_reglement_libelle;
    +				$this->cond_reglement_id	= $obj->fk_cond_reglement;
    +				$this->cond_reglement_code	= $obj->cond_reglement_code;
    +				$this->cond_reglement		= $obj->cond_reglement_libelle;
    +				$this->cond_reglement_doc	= $obj->cond_reglement_libelle_doc;
    +				$this->fk_account           = $obj->fk_account;
    +				$this->availability_id		= $obj->fk_availability;
    +				$this->availability_code	= $obj->availability_code;
    +				$this->availability	    	= $obj->availability_label;
    +				$this->demand_reason_id		= $obj->fk_input_reason;
    +				$this->demand_reason_code	= $obj->demand_reason_code;
    +				$this->date_livraison		= $this->db->jdate($obj->date_livraison);
    +				$this->shipping_method_id   = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null;
    +				$this->warehouse_id           = ($obj->fk_warehouse>0)?$obj->fk_warehouse:null;
    +				$this->fk_delivery_address	= $obj->fk_delivery_address;
     
     				//Incoterms
     				$this->fk_incoterms = $obj->fk_incoterms;
    @@ -1667,207 +1718,211 @@ class Commande extends CommonOrder
     				$this->multicurrency_total_tva 	= $obj->multicurrency_total_tva;
     				$this->multicurrency_total_ttc 	= $obj->multicurrency_total_ttc;
     
    -                $this->extraparams			= (array) json_decode($obj->extraparams, true);
    +				$this->extraparams			= (array) json_decode($obj->extraparams, true);
     
    -                $this->lines				= array();
    +				$this->lines				= array();
     
    -                if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1;
    +				if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1;
     
    -                // Retreive all extrafield
    -                // fetch optionals attributes and labels
    -                $this->fetch_optionals();
    +				// Retreive all extrafield
    +				// fetch optionals attributes and labels
    +				$this->fetch_optionals();
     
    -                $this->db->free($result);
    +				$this->db->free($result);
     
    -                /*
    -                 * Lines
    -                 */
    -                $result=$this->fetch_lines();
    -                if ($result < 0)
    -                {
    -                    return -3;
    -                }
    -                return 1;
    -            }
    -            else
    -            {
    -                $this->error='Order with id '.$id.' not found sql='.$sql;
    -                return 0;
    -            }
    -        }
    -        else
    -        {
    -            $this->error=$this->db->error();
    -            return -1;
    -        }
    -    }
    +				/*
    +				 * Lines
    +				 */
    +				$result=$this->fetch_lines();
    +				if ($result < 0)
    +				{
    +					return -3;
    +				}
    +				return 1;
    +			}
    +			else
    +			{
    +				$this->error='Order with id '.$id.' not found sql='.$sql;
    +				return 0;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			return -1;
    +		}
    +	}
     
     
    -    /**
    -     *	Adding line of fixed discount in the order in DB
    -     *
    -     *	@param     int	$idremise			Id de la remise fixe
    -     *	@return    int          			>0 si ok, <0 si ko
    -     */
    -    function insert_discount($idremise)
    -    {
    -        global $langs;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Adding line of fixed discount in the order in DB
    +	 *
    +	 *	@param     int	$idremise			Id de la remise fixe
    +	 *	@return    int          			>0 si ok, <0 si ko
    +	 */
    +	function insert_discount($idremise)
    +	{
    +        // phpcs:enable
    +		global $langs;
     
    -        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    -        include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
    +		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    +		include_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
     
    -        $this->db->begin();
    +		$this->db->begin();
     
    -        $remise=new DiscountAbsolute($this->db);
    -        $result=$remise->fetch($idremise);
    +		$remise=new DiscountAbsolute($this->db);
    +		$result=$remise->fetch($idremise);
     
    -        if ($result > 0)
    -        {
    -            if ($remise->fk_facture)	// Protection against multiple submission
    -            {
    -                $this->error=$langs->trans("ErrorDiscountAlreadyUsed");
    -                $this->db->rollback();
    -                return -5;
    -            }
    +		if ($result > 0)
    +		{
    +			if ($remise->fk_facture)	// Protection against multiple submission
    +			{
    +				$this->error=$langs->trans("ErrorDiscountAlreadyUsed");
    +				$this->db->rollback();
    +				return -5;
    +			}
     
    -            $line = new OrderLine($this->db);
    +			$line = new OrderLine($this->db);
     
    -            $line->fk_commande=$this->id;
    -            $line->fk_remise_except=$remise->id;
    -            $line->desc=$remise->description;   	// Description ligne
    -            $line->vat_src_code=$remise->vat_src_code;
    -            $line->tva_tx=$remise->tva_tx;
    -            $line->subprice=-$remise->amount_ht;
    -            $line->price=-$remise->amount_ht;
    -            $line->fk_product=0;					// Id produit predefini
    -            $line->qty=1;
    -            $line->remise=0;
    -            $line->remise_percent=0;
    -            $line->rang=-1;
    -            $line->info_bits=2;
    +			$line->fk_commande=$this->id;
    +			$line->fk_remise_except=$remise->id;
    +			$line->desc=$remise->description;   	// Description ligne
    +			$line->vat_src_code=$remise->vat_src_code;
    +			$line->tva_tx=$remise->tva_tx;
    +			$line->subprice=-$remise->amount_ht;
    +			$line->price=-$remise->amount_ht;
    +			$line->fk_product=0;					// Id produit predefini
    +			$line->qty=1;
    +			$line->remise=0;
    +			$line->remise_percent=0;
    +			$line->rang=-1;
    +			$line->info_bits=2;
     
    -            $line->total_ht  = -$remise->amount_ht;
    -            $line->total_tva = -$remise->amount_tva;
    -            $line->total_ttc = -$remise->amount_ttc;
    +			$line->total_ht  = -$remise->amount_ht;
    +			$line->total_tva = -$remise->amount_tva;
    +			$line->total_ttc = -$remise->amount_ttc;
     
    -            $result=$line->insert();
    -            if ($result > 0)
    -            {
    -                $result=$this->update_price(1);
    -                if ($result > 0)
    -                {
    -                    $this->db->commit();
    -                    return 1;
    -                }
    -                else
    -                {
    -                    $this->db->rollback();
    -                    return -1;
    -                }
    -            }
    -            else
    -            {
    -                $this->error=$line->error;
    -                $this->db->rollback();
    -                return -2;
    -            }
    -        }
    -        else
    -        {
    -            $this->db->rollback();
    -            return -2;
    -        }
    -    }
    +			$result=$line->insert();
    +			if ($result > 0)
    +			{
    +				$result=$this->update_price(1);
    +				if ($result > 0)
    +				{
    +					$this->db->commit();
    +					return 1;
    +				}
    +				else
    +				{
    +					$this->db->rollback();
    +					return -1;
    +				}
    +			}
    +			else
    +			{
    +				$this->error=$line->error;
    +				$this->db->rollback();
    +				return -2;
    +			}
    +		}
    +		else
    +		{
    +			$this->db->rollback();
    +			return -2;
    +		}
    +	}
     
     
    -    /**
    -     *	Load array lines
    -     *
    -     *	@param		int		$only_product	Return only physical products
    -     *	@return		int						<0 if KO, >0 if OK
    -     */
    -    function fetch_lines($only_product=0)
    -    {
    -        $this->lines=array();
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Load array lines
    +	 *
    +	 *	@param		int		$only_product	Return only physical products
    +	 *	@return		int						<0 if KO, >0 if OK
    +	 */
    +	function fetch_lines($only_product=0)
    +	{
    +        // phpcs:enable
    +		$this->lines=array();
     
    -        $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.label as custom_label, l.description, l.price, l.qty, l.vat_src_code, l.tva_tx,';
    -        $sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.fk_remise_except, l.remise_percent, l.subprice, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht, l.rang, l.info_bits, l.special_code,';
    -        $sql.= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,';
    -	    $sql.= ' l.fk_unit,';
    +		$sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.label as custom_label, l.description, l.price, l.qty, l.vat_src_code, l.tva_tx,';
    +		$sql.= ' l.localtax1_tx, l.localtax2_tx, l.localtax1_type, l.localtax2_type, l.fk_remise_except, l.remise_percent, l.subprice, l.fk_product_fournisseur_price as fk_fournprice, l.buy_price_ht as pa_ht, l.rang, l.info_bits, l.special_code,';
    +		$sql.= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,';
    +		$sql.= ' l.fk_unit,';
     		$sql.= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,';
    -        $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch,';
    -        $sql.= ' p.weight, p.weight_units, p.volume, p.volume_units';
    -        $sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l';
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)';
    -        $sql.= ' WHERE l.fk_commande = '.$this->id;
    -        if ($only_product) $sql .= ' AND p.fk_product_type = 0';
    -        $sql .= ' ORDER BY l.rang, l.rowid';
    +		$sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch,';
    +		$sql.= ' p.weight, p.weight_units, p.volume, p.volume_units';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as l';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)';
    +		$sql.= ' WHERE l.fk_commande = '.$this->id;
    +		if ($only_product) $sql .= ' AND p.fk_product_type = 0';
    +		$sql .= ' ORDER BY l.rang, l.rowid';
     
    -        dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
    -        $result = $this->db->query($sql);
    -        if ($result)
    -        {
    -            $num = $this->db->num_rows($result);
    +		dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG);
    +		$result = $this->db->query($sql);
    +		if ($result)
    +		{
    +			$num = $this->db->num_rows($result);
     
    -            $i = 0;
    -            while ($i < $num)
    -            {
    -                $objp = $this->db->fetch_object($result);
    +			$i = 0;
    +			while ($i < $num)
    +			{
    +				$objp = $this->db->fetch_object($result);
     
    -                $line = new OrderLine($this->db);
    +				$line = new OrderLine($this->db);
     
    -                $line->rowid            = $objp->rowid;
    -                $line->id               = $objp->rowid;
    -                $line->fk_commande      = $objp->fk_commande;
    -                $line->commande_id      = $objp->fk_commande;
    -                $line->label            = $objp->custom_label;
    -                $line->desc             = $objp->description;
    -                $line->description      = $objp->description;		// Description line
    -                $line->product_type     = $objp->product_type;
    -                $line->qty              = $objp->qty;
    +				$line->rowid            = $objp->rowid;
    +				$line->id               = $objp->rowid;
    +				$line->fk_commande      = $objp->fk_commande;
    +				$line->commande_id      = $objp->fk_commande;
    +				$line->label            = $objp->custom_label;
    +				$line->desc             = $objp->description;
    +				$line->description      = $objp->description;		// Description line
    +				$line->product_type     = $objp->product_type;
    +				$line->qty              = $objp->qty;
     
    -                $line->vat_src_code     = $objp->vat_src_code;
    -                $line->tva_tx           = $objp->tva_tx;
    -	            $line->localtax1_tx     = $objp->localtax1_tx;
    -                $line->localtax2_tx     = $objp->localtax2_tx;
    -	            $line->localtax1_type	= $objp->localtax1_type;
    -	            $line->localtax2_type	= $objp->localtax2_type;
    -	            $line->total_ht         = $objp->total_ht;
    -                $line->total_ttc        = $objp->total_ttc;
    -                $line->total_tva        = $objp->total_tva;
    -                $line->total_localtax1  = $objp->total_localtax1;
    -                $line->total_localtax2  = $objp->total_localtax2;
    -                $line->subprice         = $objp->subprice;
    -                $line->fk_remise_except = $objp->fk_remise_except;
    -                $line->remise_percent   = $objp->remise_percent;
    -                $line->price            = $objp->price;
    -                $line->fk_product       = $objp->fk_product;
    +				$line->vat_src_code     = $objp->vat_src_code;
    +				$line->tva_tx           = $objp->tva_tx;
    +				$line->localtax1_tx     = $objp->localtax1_tx;
    +				$line->localtax2_tx     = $objp->localtax2_tx;
    +				$line->localtax1_type	= $objp->localtax1_type;
    +				$line->localtax2_type	= $objp->localtax2_type;
    +				$line->total_ht         = $objp->total_ht;
    +				$line->total_ttc        = $objp->total_ttc;
    +				$line->total_tva        = $objp->total_tva;
    +				$line->total_localtax1  = $objp->total_localtax1;
    +				$line->total_localtax2  = $objp->total_localtax2;
    +				$line->subprice         = $objp->subprice;
    +				$line->fk_remise_except = $objp->fk_remise_except;
    +				$line->remise_percent   = $objp->remise_percent;
    +				$line->price            = $objp->price;
    +				$line->fk_product       = $objp->fk_product;
     				$line->fk_fournprice 	= $objp->fk_fournprice;
    -		      	$marginInfos			= getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
    -		   		$line->pa_ht 			= $marginInfos[0];
    -		    	$line->marge_tx			= $marginInfos[1];
    -		     	$line->marque_tx		= $marginInfos[2];
    -                $line->rang             = $objp->rang;
    -                $line->info_bits        = $objp->info_bits;
    -                $line->special_code		= $objp->special_code;
    -                $line->fk_parent_line	= $objp->fk_parent_line;
    +				$marginInfos			= getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
    +				$line->pa_ht 			= $marginInfos[0];
    +				$line->marge_tx			= $marginInfos[1];
    +				$line->marque_tx		= $marginInfos[2];
    +				$line->rang             = $objp->rang;
    +				$line->info_bits        = $objp->info_bits;
    +				$line->special_code		= $objp->special_code;
    +				$line->fk_parent_line	= $objp->fk_parent_line;
     
    -                $line->ref				= $objp->product_ref;
    -                $line->product_ref		= $objp->product_ref;
    -                $line->libelle			= $objp->product_label;
    -                $line->product_label	= $objp->product_label;
    -                $line->product_desc     = $objp->product_desc;
    -                $line->product_tobatch  = $objp->product_tobatch;
    -                $line->fk_product_type  = $objp->fk_product_type;	// Produit ou service
    -	            $line->fk_unit          = $objp->fk_unit;
    +				$line->ref				= $objp->product_ref;
    +				$line->product_ref		= $objp->product_ref;
    +				$line->libelle			= $objp->product_label;
    +				$line->product_label	= $objp->product_label;
    +				$line->product_desc     = $objp->product_desc;
    +				$line->product_tobatch  = $objp->product_tobatch;
    +				$line->fk_product_type  = $objp->fk_product_type;	// Produit ou service
    +				$line->fk_unit          = $objp->fk_unit;
     
    -	            $line->weight           = $objp->weight;
    -	            $line->weight_units     = $objp->weight_units;
    -	            $line->volume           = $objp->volume;
    -	            $line->volume_units     = $objp->volume_units;
    +				$line->weight           = $objp->weight;
    +				$line->weight_units     = $objp->weight_units;
    +				$line->volume           = $objp->volume;
    +				$line->volume_units     = $objp->volume_units;
     
    -                $line->date_start       = $this->db->jdate($objp->date_start);
    -                $line->date_end         = $this->db->jdate($objp->date_end);
    +				$line->date_start       = $this->db->jdate($objp->date_start);
    +				$line->date_end         = $this->db->jdate($objp->date_end);
     
     				// Multicurrency
     				$line->fk_multicurrency 		= $objp->fk_multicurrency;
    @@ -1877,813 +1932,830 @@ class Commande extends CommonOrder
     				$line->multicurrency_total_tva 	= $objp->multicurrency_total_tva;
     				$line->multicurrency_total_ttc 	= $objp->multicurrency_total_ttc;
     
    -           	$line->fetch_optionals();
    -
    +				$line->fetch_optionals();
     
                     $this->lines[$i] = $line;
     
    -                $i++;
    -            }
    +				$i++;
    +			}
     
    -            $this->db->free($result);
    +			$this->db->free($result);
     
    -            return 1;
    -        }
    -        else
    -        {
    -            $this->error=$this->db->error();
    -            return -3;
    -        }
    -    }
    +			return 1;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			return -3;
    +		}
    +	}
     
     
    -    /**
    -     *	Return number of line with type product.
    -     *
    -     *	@return		int		<0 if KO, Nbr of product lines if OK
    -     */
    -    function getNbOfProductsLines()
    -    {
    -        $nb=0;
    -        foreach($this->lines as $line)
    -        {
    -            if ($line->product_type == 0) $nb++;
    -        }
    -        return $nb;
    -    }
    +	/**
    +	 *	Return number of line with type product.
    +	 *
    +	 *	@return		int		<0 if KO, Nbr of product lines if OK
    +	 */
    +	function getNbOfProductsLines()
    +	{
    +		$nb=0;
    +		foreach($this->lines as $line)
    +		{
    +			if ($line->product_type == 0) $nb++;
    +		}
    +		return $nb;
    +	}
     
    -    /**
    -     *	Return number of line with type service.
    -     *
    -     *	@return		int		<0 if KO, Nbr of service lines if OK
    -     */
    -    function getNbOfServicesLines()
    -    {
    -        $nb=0;
    -        foreach($this->lines as $line)
    -        {
    -            if ($line->product_type == 1) $nb++;
    -        }
    -        return $nb;
    -    }
    +	/**
    +	 *	Return number of line with type service.
    +	 *
    +	 *	@return		int		<0 if KO, Nbr of service lines if OK
    +	 */
    +	function getNbOfServicesLines()
    +	{
    +		$nb=0;
    +		foreach($this->lines as $line)
    +		{
    +			if ($line->product_type == 1) $nb++;
    +		}
    +		return $nb;
    +	}
     
    -    /**
    -     *	Count numbe rof shipments for this order
    -     *
    -     * 	@return     int                			<0 if KO, Nb of shipment found if OK
    -     */
    -    function getNbOfShipments()
    -    {
    -    	$nb = 0;
    +	/**
    +	 *	Count numbe rof shipments for this order
    +	 *
    +	 * 	@return     int                			<0 if KO, Nb of shipment found if OK
    +	 */
    +	function getNbOfShipments()
    +	{
    +		$nb = 0;
     
    -    	$sql = 'SELECT COUNT(DISTINCT ed.fk_expedition) as nb';
    -    	$sql.= ' FROM '.MAIN_DB_PREFIX.'expeditiondet as ed,';
    -    	$sql.= ' '.MAIN_DB_PREFIX.'commandedet as cd';
    -    	$sql.= ' WHERE';
    -    	$sql.= ' ed.fk_origin_line = cd.rowid';
    -    	$sql.= ' AND cd.fk_commande =' .$this->id;
    -    	//print $sql;
    +		$sql = 'SELECT COUNT(DISTINCT ed.fk_expedition) as nb';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'expeditiondet as ed,';
    +		$sql.= ' '.MAIN_DB_PREFIX.'commandedet as cd';
    +		$sql.= ' WHERE';
    +		$sql.= ' ed.fk_origin_line = cd.rowid';
    +		$sql.= ' AND cd.fk_commande =' .$this->id;
    +		//print $sql;
     
    -    	dol_syslog(get_class($this)."::getNbOfShipments", LOG_DEBUG);
    -    	$resql = $this->db->query($sql);
    -    	if ($resql)
    -    	{
    -   			$obj = $this->db->fetch_object($resql);
    -   			if ($obj) $nb = $obj->nb;
    +		dol_syslog(get_class($this)."::getNbOfShipments", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if ($resql)
    +		{
    +			$obj = $this->db->fetch_object($resql);
    +			if ($obj) $nb = $obj->nb;
     
    -   			$this->db->free($resql);
    -    		return $nb;
    -    	}
    -    	else
    -    	{
    -    		$this->error=$this->db->lasterror();
    -    		return -1;
    -    	}
    -    }
    +			$this->db->free($resql);
    +			return $nb;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->lasterror();
    +			return -1;
    +		}
    +	}
     
    -    /**
    -     *	Load array this->expeditions of lines of shipments with nb of products sent for each order line
    -     *  Note: For a dedicated shipment, the fetch_lines can be used to load the qty_asked and qty_shipped. This function is use to return qty_shipped cumulated for the order
    -     *
    -     *	@param      int		$filtre_statut      Filter on shipment status
    -     * 	@return     int                			<0 if KO, Nb of lines found if OK
    -     */
    -    function loadExpeditions($filtre_statut=-1)
    -    {
    -        $this->expeditions = array();
    +	/**
    +	 *	Load array this->expeditions of lines of shipments with nb of products sent for each order line
    +	 *  Note: For a dedicated shipment, the fetch_lines can be used to load the qty_asked and qty_shipped. This function is use to return qty_shipped cumulated for the order
    +	 *
    +	 *	@param      int		$filtre_statut      Filter on shipment status
    +	 * 	@return     int                			<0 if KO, Nb of lines found if OK
    +	 */
    +	function loadExpeditions($filtre_statut=-1)
    +	{
    +		$this->expeditions = array();
     
    -        $sql = 'SELECT cd.rowid, cd.fk_product,';
    -        $sql.= ' sum(ed.qty) as qty';
    -        $sql.= ' FROM '.MAIN_DB_PREFIX.'expeditiondet as ed,';
    -        if ($filtre_statut >= 0) $sql.= ' '.MAIN_DB_PREFIX.'expedition as e,';
    -        $sql.= ' '.MAIN_DB_PREFIX.'commandedet as cd';
    -        $sql.= ' WHERE';
    -        if ($filtre_statut >= 0) $sql.= ' ed.fk_expedition = e.rowid AND';
    -        $sql.= ' ed.fk_origin_line = cd.rowid';
    -        $sql.= ' AND cd.fk_commande =' .$this->id;
    -        if ($this->fk_product > 0) $sql.= ' AND cd.fk_product = '.$this->fk_product;
    -        if ($filtre_statut >= 0) $sql.=' AND e.fk_statut >= '.$filtre_statut;
    -        $sql.= ' GROUP BY cd.rowid, cd.fk_product';
    -        //print $sql;
    +		$sql = 'SELECT cd.rowid, cd.fk_product,';
    +		$sql.= ' sum(ed.qty) as qty';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'expeditiondet as ed,';
    +		if ($filtre_statut >= 0) $sql.= ' '.MAIN_DB_PREFIX.'expedition as e,';
    +		$sql.= ' '.MAIN_DB_PREFIX.'commandedet as cd';
    +		$sql.= ' WHERE';
    +		if ($filtre_statut >= 0) $sql.= ' ed.fk_expedition = e.rowid AND';
    +		$sql.= ' ed.fk_origin_line = cd.rowid';
    +		$sql.= ' AND cd.fk_commande =' .$this->id;
    +		if ($this->fk_product > 0) $sql.= ' AND cd.fk_product = '.$this->fk_product;
    +		if ($filtre_statut >= 0) $sql.=' AND e.fk_statut >= '.$filtre_statut;
    +		$sql.= ' GROUP BY cd.rowid, cd.fk_product';
    +		//print $sql;
     
    -        dol_syslog(get_class($this)."::loadExpeditions", LOG_DEBUG);
    -        $resql = $this->db->query($sql);
    -        if ($resql)
    -        {
    -            $num = $this->db->num_rows($resql);
    -            $i = 0;
    -            while ($i < $num)
    -            {
    -                $obj = $this->db->fetch_object($resql);
    -                $this->expeditions[$obj->rowid] = $obj->qty;
    -                $i++;
    -            }
    -            $this->db->free($resql);
    -            return $num;
    -        }
    -        else
    -        {
    -            $this->error=$this->db->lasterror();
    -            return -1;
    -        }
    -    }
    +		dol_syslog(get_class($this)."::loadExpeditions", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if ($resql)
    +		{
    +			$num = $this->db->num_rows($resql);
    +			$i = 0;
    +			while ($i < $num)
    +			{
    +				$obj = $this->db->fetch_object($resql);
    +				$this->expeditions[$obj->rowid] = $obj->qty;
    +				$i++;
    +			}
    +			$this->db->free($resql);
    +			return $num;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->lasterror();
    +			return -1;
    +		}
    +	}
     
    -    /**
    -     * Returns a array with expeditions lines number
    -     *
    -     * @return	int		Nb of shipments
    -     *
    -     * TODO deprecate, move to Shipping class
    -     */
    -    function nb_expedition()
    -    {
    -        $sql = 'SELECT count(*)';
    -        $sql.= ' FROM '.MAIN_DB_PREFIX.'expedition as e';
    -        $sql.= ', '.MAIN_DB_PREFIX.'element_element as el';
    -        $sql.= ' WHERE el.fk_source = '.$this->id;
    -        $sql.= " AND el.fk_target = e.rowid";
    -        $sql.= " AND el.targettype = 'shipping'";
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 * Returns a array with expeditions lines number
    +	 *
    +	 * @return	int		Nb of shipments
    +	 *
    +	 * TODO deprecate, move to Shipping class
    +	 */
    +	function nb_expedition()
    +	{
    +        // phpcs:enable
    +		$sql = 'SELECT count(*)';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'expedition as e';
    +		$sql.= ', '.MAIN_DB_PREFIX.'element_element as el';
    +		$sql.= ' WHERE el.fk_source = '.$this->id;
    +		$sql.= " AND el.fk_target = e.rowid";
    +		$sql.= " AND el.targettype = 'shipping'";
     
    -        $resql = $this->db->query($sql);
    -        if ($resql)
    -        {
    -            $row = $this->db->fetch_row($resql);
    -            return $row[0];
    -        }
    -        else dol_print_error($this->db);
    -    }
    +		$resql = $this->db->query($sql);
    +		if ($resql)
    +		{
    +			$row = $this->db->fetch_row($resql);
    +			return $row[0];
    +		}
    +		else dol_print_error($this->db);
    +	}
     
    -    /**
    -     *	Return a array with the pending stock by product
    -     *
    -     *	@param      int		$filtre_statut      Filtre sur statut
    -     *	@return     int                 		0 si OK, <0 si KO
    -     *
    -     *	TODO		FONCTION NON FINIE A FINIR
    -     */
    -    function stock_array($filtre_statut=self::STATUS_CANCELED)
    -    {
    -        $this->stocks = array();
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Return a array with the pending stock by product
    +	 *
    +	 *	@param      int		$filtre_statut      Filtre sur statut
    +	 *	@return     int                 		0 si OK, <0 si KO
    +	 *
    +	 *	TODO		FONCTION NON FINIE A FINIR
    +	 */
    +	function stock_array($filtre_statut=self::STATUS_CANCELED)
    +	{
    +        // phpcs:enable
    +		$this->stocks = array();
     
    -        // Tableau des id de produit de la commande
    +		// Tableau des id de produit de la commande
     		$array_of_product=array();
     
    -        // Recherche total en stock pour chaque produit
    -        // TODO $array_of_product est défini vide juste au dessus !!
    -        if (count($array_of_product))
    -        {
    -            $sql = "SELECT fk_product, sum(ps.reel) as total";
    -            $sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps";
    -            $sql.= " WHERE ps.fk_product IN (".join(',',$array_of_product).")";
    -            $sql.= ' GROUP BY fk_product ';
    -            $resql = $this->db->query($sql);
    -            if ($resql)
    -            {
    -                $num = $this->db->num_rows($resql);
    -                $i = 0;
    -                while ($i < $num)
    -                {
    -                    $obj = $this->db->fetch_object($resql);
    -                    $this->stocks[$obj->fk_product] = $obj->total;
    -                    $i++;
    -                }
    -                $this->db->free($resql);
    -            }
    -        }
    -        return 0;
    -    }
    +		// Recherche total en stock pour chaque produit
    +		// TODO $array_of_product est défini vide juste au dessus !!
    +		if (count($array_of_product))
    +		{
    +			$sql = "SELECT fk_product, sum(ps.reel) as total";
    +			$sql.= " FROM ".MAIN_DB_PREFIX."product_stock as ps";
    +			$sql.= " WHERE ps.fk_product IN (".join(',',$array_of_product).")";
    +			$sql.= ' GROUP BY fk_product ';
    +			$resql = $this->db->query($sql);
    +			if ($resql)
    +			{
    +				$num = $this->db->num_rows($resql);
    +				$i = 0;
    +				while ($i < $num)
    +				{
    +					$obj = $this->db->fetch_object($resql);
    +					$this->stocks[$obj->fk_product] = $obj->total;
    +					$i++;
    +				}
    +				$this->db->free($resql);
    +			}
    +		}
    +		return 0;
    +	}
     
    -    /**
    -     *  Delete an order line
    -     *
    -     *	@param      User	$user		User object
    -     *  @param      int		$lineid		Id of line to delete
    -     *  @return     int        		 	>0 if OK, 0 if nothing to do, <0 if KO
    -     */
    -    function deleteline($user=null, $lineid=0)
    -    {
    -        if ($this->statut == self::STATUS_DRAFT)
    -        {
    -            $this->db->begin();
    +	/**
    +	 *  Delete an order line
    +	 *
    +	 *	@param      User	$user		User object
    +	 *  @param      int		$lineid		Id of line to delete
    +	 *  @return     int        		 	>0 if OK, 0 if nothing to do, <0 if KO
    +	 */
    +	function deleteline($user=null, $lineid=0)
    +	{
    +		if ($this->statut == self::STATUS_DRAFT)
    +		{
    +			$this->db->begin();
     
    -            $sql = "SELECT fk_product, qty";
    -            $sql.= " FROM ".MAIN_DB_PREFIX."commandedet";
    -            $sql.= " WHERE rowid = ".$lineid;
    +			$sql = "SELECT fk_product, qty";
    +			$sql.= " FROM ".MAIN_DB_PREFIX."commandedet";
    +			$sql.= " WHERE rowid = ".$lineid;
     
    -            $result = $this->db->query($sql);
    -            if ($result)
    -            {
    -                $obj = $this->db->fetch_object($result);
    +			$result = $this->db->query($sql);
    +			if ($result)
    +			{
    +				$obj = $this->db->fetch_object($result);
     
    -                if ($obj)
    -                {
    -                    $product = new Product($this->db);
    -                    $product->id = $obj->fk_product;
    +				if ($obj)
    +				{
    +					$product = new Product($this->db);
    +					$product->id = $obj->fk_product;
     
    -                    // Delete line
    -                    $line = new OrderLine($this->db);
    +					// Delete line
    +					$line = new OrderLine($this->db);
     
    -                    // For triggers
    -                    $line->fetch($lineid);
    +					// For triggers
    +					$line->fetch($lineid);
     
    -                    if ($line->delete($user) > 0)
    -                    {
    -                        $result=$this->update_price(1);
    -
    -                        if ($result > 0)
    -                        {
    -                            $this->db->commit();
    -                            return 1;
    -                        }
    -                        else
    -                        {
    -                            $this->db->rollback();
    -                            $this->error=$this->db->lasterror();
    -                            return -1;
    -                        }
    -                    }
    -                    else
    -                    {
    -                        $this->db->rollback();
    -                        $this->error=$line->error;
    -                        return -1;
    -                    }
    -                }
    -                else
    -                {
    -                    $this->db->rollback();
    -                    return 0;
    -                }
    -            }
    -            else
    -            {
    -                $this->db->rollback();
    -                $this->error=$this->db->lasterror();
    -                return -1;
    -            }
    -        }
    -        else
    -        {
    -        	$this->error='ErrorDeleteLineNotAllowedByObjectStatus';
    -        	return -1;
    -        }
    -    }
    -
    -    /**
    -     * 	Applique une remise relative
    -     *
    -     * 	@param     	User		$user		User qui positionne la remise
    -     * 	@param     	float		$remise		Discount (percent)
    -     * 	@param     	int			$notrigger	1=Does not execute triggers, 0= execute triggers
    -     *	@return		int 					<0 if KO, >0 if OK
    -     */
    -    function set_remise($user, $remise, $notrigger=0)
    -    {
    -        $remise=trim($remise)?trim($remise):0;
    -
    -        if ($user->rights->commande->creer)
    -        {
    -        	$error=0;
    -
    -        	$this->db->begin();
    -
    -            $remise=price2num($remise);
    -
    -            $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    -            $sql.= ' SET remise_percent = '.$remise;
    -            $sql.= ' WHERE rowid = '.$this->id.' AND fk_statut = '.self::STATUS_DRAFT.' ;';
    -
    -            dol_syslog(__METHOD__, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->remise_percent = $remise;
    -            	$this->update_price(1);
    -            }
    -
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -    }
    -
    -
    -    /**
    -     * 		Applique une remise absolue
    -     *
    -     * 		@param     	User		$user 		User qui positionne la remise
    -     * 		@param     	float		$remise		Discount
    -     * 		@param     	int			$notrigger	1=Does not execute triggers, 0= execute triggers
    -     *		@return		int 					<0 if KO, >0 if OK
    -     */
    -    function set_remise_absolue($user, $remise, $notrigger=0)
    -    {
    -        $remise=trim($remise)?trim($remise):0;
    -
    -        if ($user->rights->commande->creer)
    -        {
    -        	$error=0;
    -
    -        	$this->db->begin();
    -
    -            $remise=price2num($remise);
    -
    -            $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    -            $sql.= ' SET remise_absolue = '.$remise;
    -            $sql.= ' WHERE rowid = '.$this->id.' AND fk_statut = '.self::STATUS_DRAFT.' ;';
    -
    -            dol_syslog(__METHOD__, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->remise_absolue = $remise;
    -            	$this->update_price(1);
    -            }
    -
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -    }
    -
    -
    -    /**
    -     *	Set the order date
    -     *
    -     *	@param      User	$user       Object user making change
    -     *	@param      int		$date		Date
    -     * 	@param     	int		$notrigger	1=Does not execute triggers, 0= execute triggers
    -     *	@return     int         		<0 if KO, >0 if OK
    -     */
    -    function set_date($user, $date, $notrigger=0)
    -    {
    -        if ($user->rights->commande->creer)
    -        {
    -        	$error=0;
    -
    -        	$this->db->begin();
    -
    -            $sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    -            $sql.= " SET date_commande = ".($date ? "'".$this->db->idate($date)."'" : 'null');
    -            $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT;
    -
    -            dol_syslog(__METHOD__, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->date = $date;
    -            }
    -
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -        else
    -        {
    -            return -2;
    -        }
    -    }
    -
    -    /**
    -     *	Set the planned delivery date
    -     *
    -     *	@param      User	$user        		Objet utilisateur qui modifie
    -     *	@param      int		$date_livraison     Date de livraison
    -     *  @param     	int		$notrigger			1=Does not execute triggers, 0= execute triggers
    -     *	@return     int         				<0 si ko, >0 si ok
    -     */
    -    function set_date_livraison($user, $date_livraison, $notrigger=0)
    -    {
    -        if ($user->rights->commande->creer)
    -        {
    -        	$error=0;
    -
    -        	$this->db->begin();
    -
    -            $sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    -            $sql.= " SET date_livraison = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null');
    -            $sql.= " WHERE rowid = ".$this->id;
    -
    -            dol_syslog(__METHOD__, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->date_livraison = $date_livraison;
    -            }
    -
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    -
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -        else
    -        {
    -            return -2;
    -        }
    -    }
    -
    -    /**
    -     *  Return list of orders (eventuelly filtered on a user) into an array
    -     *
    -     *  @param		int		$shortlist		0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name)
    -     *  @param      int		$draft      	0=not draft, 1=draft
    -     *  @param      User	$excluser      	Objet user to exclude
    -     *  @param    	int		$socid			Id third pary
    -     *  @param    	int		$limit			For pagination
    -     *  @param    	int		$offset			For pagination
    -     *  @param    	string	$sortfield		Sort criteria
    -     *  @param    	string	$sortorder		Sort order
    -     *  @return     int             		-1 if KO, array with result if OK
    -     */
    -    function liste_array($shortlist=0, $draft=0, $excluser='', $socid=0, $limit=0, $offset=0, $sortfield='c.date_commande', $sortorder='DESC')
    -    {
    -        global $user;
    -
    -        $ga = array();
    -
    -        $sql = "SELECT s.rowid, s.nom as name, s.client,";
    -        $sql.= " c.rowid as cid, c.ref";
    -        if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user";
    -        $sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c";
    -		if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    -        $sql.= " WHERE c.entity IN (".getEntity('commande').")";
    -        $sql.= " AND c.fk_soc = s.rowid";
    -        if (! $user->rights->societe->client->voir && ! $socid) //restriction
    -        {
    -        	$sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
    -        }
    -        if ($socid) $sql.= " AND s.rowid = ".$socid;
    -        if ($draft) $sql.= " AND c.fk_statut = ".self::STATUS_DRAFT;
    -        if (is_object($excluser)) $sql.= " AND c.fk_user_author <> ".$excluser->id;
    -        $sql.= $this->db->order($sortfield,$sortorder);
    -        $sql.= $this->db->plimit($limit,$offset);
    -
    -        $result=$this->db->query($sql);
    -        if ($result)
    -        {
    -            $numc = $this->db->num_rows($result);
    -            if ($numc)
    -            {
    -                $i = 0;
    -                while ($i < $numc)
    -                {
    -                    $obj = $this->db->fetch_object($result);
    -
    -                    if ($shortlist == 1)
    -                    {
    -                    	$ga[$obj->cid] = $obj->ref;
    -                    }
    -                    else if ($shortlist == 2)
    -                    {
    -                    	$ga[$obj->cid] = $obj->ref.' ('.$obj->name.')';
    -                    }
    -                    else
    +					if ($line->delete($user) > 0)
     					{
    -                    	$ga[$i]['id']	= $obj->cid;
    -                    	$ga[$i]['ref'] 	= $obj->ref;
    -                    	$ga[$i]['name'] = $obj->name;
    -                    }
    -                    $i++;
    -                }
    -            }
    -            return $ga;
    -        }
    -        else
    -        {
    -            dol_print_error($this->db);
    -            return -1;
    -        }
    -    }
    +						$result=$this->update_price(1);
     
    -    /**
    -     *	Update delivery delay
    -     *
    -     *	@param      int		$availability_id	Id du nouveau mode
    -     *  @param     	int		$notrigger			1=Does not execute triggers, 0= execute triggers
    -     *	@return     int         				>0 if OK, <0 if KO
    -     */
    -    function availability($availability_id, $notrigger=0)
    -    {
    -        global $user;
    +						if ($result > 0)
    +						{
    +							$this->db->commit();
    +							return 1;
    +						}
    +						else
    +						{
    +							$this->db->rollback();
    +							$this->error=$this->db->lasterror();
    +							return -1;
    +						}
    +					}
    +					else
    +					{
    +						$this->db->rollback();
    +						$this->error=$line->error;
    +						return -1;
    +					}
    +				}
    +				else
    +				{
    +					$this->db->rollback();
    +					return 0;
    +				}
    +			}
    +			else
    +			{
    +				$this->db->rollback();
    +				$this->error=$this->db->lasterror();
    +				return -1;
    +			}
    +		}
    +		else
    +		{
    +			$this->error='ErrorDeleteLineNotAllowedByObjectStatus';
    +			return -1;
    +		}
    +	}
     
    -        dol_syslog('Commande::availability('.$availability_id.')');
    -        if ($this->statut >= self::STATUS_DRAFT)
    -        {
    -        	$error=0;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 * 	Applique une remise relative
    +	 *
    +	 * 	@param     	User		$user		User qui positionne la remise
    +	 * 	@param     	float		$remise		Discount (percent)
    +	 * 	@param     	int			$notrigger	1=Does not execute triggers, 0= execute triggers
    +	 *	@return		int 					<0 if KO, >0 if OK
    +	 */
    +	function set_remise($user, $remise, $notrigger=0)
    +	{
    +        // phpcs:enable
    +		$remise=trim($remise)?trim($remise):0;
     
    -        	$this->db->begin();
    +		if ($user->rights->commande->creer)
    +		{
    +			$error=0;
     
    -            $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    -            $sql .= ' SET fk_availability = '.$availability_id;
    -            $sql .= ' WHERE rowid='.$this->id;
    +			$this->db->begin();
     
    -            dol_syslog(__METHOD__, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    +			$remise=price2num($remise);
     
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->availability_id = $availability_id;
    -            }
    +			$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    +			$sql.= ' SET remise_percent = '.$remise;
    +			$sql.= ' WHERE rowid = '.$this->id.' AND fk_statut = '.self::STATUS_DRAFT.' ;';
     
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    +			dol_syslog(__METHOD__, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
     
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -        else
    -        {
    -        	$error_str='Command status do not meet requirement '.$this->statut;
    -            dol_syslog(__METHOD__.$error_str, LOG_ERR);
    -            $this->error=$error_str;
    -            $this->errors[]= $this->error;
    -            return -2;
    -        }
    -    }
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->remise_percent = $remise;
    +				$this->update_price(1);
    +			}
     
    -    /**
    -     *	Update order demand_reason
    -     *
    -     *  @param      int		$demand_reason_id	Id of new demand
    -     *  @param     	int		$notrigger			1=Does not execute triggers, 0= execute triggers
    -     *  @return     int        			 		>0 if ok, <0 if ko
    -     */
    -    function demand_reason($demand_reason_id, $notrigger=0)
    -    {
    -        global $user;
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
     
    -        dol_syslog('Commande::demand_reason('.$demand_reason_id.')');
    -        if ($this->statut >= self::STATUS_DRAFT)
    -        {
    -        	$error=0;
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +	}
     
    -        	$this->db->begin();
     
    -            $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    -            $sql .= ' SET fk_input_reason = '.$demand_reason_id;
    -            $sql .= ' WHERE rowid='.$this->id;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 * 		Applique une remise absolue
    +	 *
    +	 * 		@param     	User		$user 		User qui positionne la remise
    +	 * 		@param     	float		$remise		Discount
    +	 * 		@param     	int			$notrigger	1=Does not execute triggers, 0= execute triggers
    +	 *		@return		int 					<0 if KO, >0 if OK
    +	 */
    +	function set_remise_absolue($user, $remise, $notrigger=0)
    +	{
    +        // phpcs:enable
    +		$remise=trim($remise)?trim($remise):0;
     
    -            dol_syslog(__METHOD__, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    +		if ($user->rights->commande->creer)
    +		{
    +			$error=0;
     
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->demand_reason_id = $demand_reason_id;
    -            }
    +			$this->db->begin();
     
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    +			$remise=price2num($remise);
     
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -        else
    -        {
    -        	$error_str='order status do not meet requirement '.$this->statut;
    -        	dol_syslog(__METHOD__.$error_str, LOG_ERR);
    -        	$this->error=$error_str;
    -        	$this->errors[]= $this->error;
    -            return -2;
    -        }
    -    }
    +			$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    +			$sql.= ' SET remise_absolue = '.$remise;
    +			$sql.= ' WHERE rowid = '.$this->id.' AND fk_statut = '.self::STATUS_DRAFT.' ;';
     
    -    /**
    -     *	Set customer ref
    -     *
    -     *	@param      User	$user           User that make change
    -     *	@param      string	$ref_client     Customer ref
    -     *  @param     	int		$notrigger		1=Does not execute triggers, 0= execute triggers
    -     *	@return     int             		<0 if KO, >0 if OK
    -     */
    -    function set_ref_client($user, $ref_client, $notrigger=0)
    -    {
    -        if ($user->rights->commande->creer)
    -        {
    -        	$error=0;
    +			dol_syslog(__METHOD__, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
     
    -        	$this->db->begin();
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->remise_absolue = $remise;
    +				$this->update_price(1);
    +			}
     
    -            $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande SET';
    -            $sql.= ' ref_client = '.(empty($ref_client) ? 'NULL' : '\''.$this->db->escape($ref_client).'\'');
    -            $sql.= ' WHERE rowid = '.$this->id;
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
     
    -            dol_syslog(__METHOD__.' this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
    -            $resql=$this->db->query($sql);
    -            if (!$resql)
    -            {
    -            	$this->errors[]=$this->db->error();
    -            	$error++;
    -            }
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +	}
     
    -            if (! $error)
    -            {
    -            	$this->oldcopy= clone $this;
    -            	$this->ref_client = $ref_client;
    -            }
     
    -            if (! $notrigger && empty($error))
    -            {
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_MODIFY',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    -            }
    -            if (! $error)
    -            {
    -            	$this->db->commit();
    -            	return 1;
    -            }
    -            else
    -            {
    -            	foreach($this->errors as $errmsg)
    -            	{
    -            		dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    -            		$this->error.=($this->error?', '.$errmsg:$errmsg);
    -            	}
    -            	$this->db->rollback();
    -            	return -1*$error;
    -            }
    -        }
    -        else
    -        {
    -            return -1;
    -        }
    -    }
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Set the order date
    +	 *
    +	 *	@param      User	$user       Object user making change
    +	 *	@param      int		$date		Date
    +	 * 	@param     	int		$notrigger	1=Does not execute triggers, 0= execute triggers
    +	 *	@return     int         		<0 if KO, >0 if OK
    +	 */
    +	function set_date($user, $date, $notrigger=0)
    +	{
    +        // phpcs:enable
    +		if ($user->rights->commande->creer)
    +		{
    +			$error=0;
    +
    +			$this->db->begin();
    +
    +			$sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    +			$sql.= " SET date_commande = ".($date ? "'".$this->db->idate($date)."'" : 'null');
    +			$sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT;
    +
    +			dol_syslog(__METHOD__, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->date = $date;
    +			}
    +
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +		else
    +		{
    +			return -2;
    +		}
    +	}
    +
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Set the planned delivery date
    +	 *
    +	 *	@param      User	$user        		Objet utilisateur qui modifie
    +	 *	@param      int		$date_livraison     Date de livraison
    +	 *  @param     	int		$notrigger			1=Does not execute triggers, 0= execute triggers
    +	 *	@return     int         				<0 si ko, >0 si ok
    +	 */
    +	function set_date_livraison($user, $date_livraison, $notrigger=0)
    +	{
    +        // phpcs:enable
    +		if ($user->rights->commande->creer)
    +		{
    +			$error=0;
    +
    +			$this->db->begin();
    +
    +			$sql = "UPDATE ".MAIN_DB_PREFIX."commande";
    +			$sql.= " SET date_livraison = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null');
    +			$sql.= " WHERE rowid = ".$this->id;
    +
    +			dol_syslog(__METHOD__, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->date_livraison = $date_livraison;
    +			}
    +
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +		else
    +		{
    +			return -2;
    +		}
    +	}
    +
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *  Return list of orders (eventuelly filtered on a user) into an array
    +	 *
    +	 *  @param		int		$shortlist		0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name)
    +	 *  @param      int		$draft      	0=not draft, 1=draft
    +	 *  @param      User	$excluser      	Objet user to exclude
    +	 *  @param    	int		$socid			Id third pary
    +	 *  @param    	int		$limit			For pagination
    +	 *  @param    	int		$offset			For pagination
    +	 *  @param    	string	$sortfield		Sort criteria
    +	 *  @param    	string	$sortorder		Sort order
    +	 *  @return     int             		-1 if KO, array with result if OK
    +	 */
    +	function liste_array($shortlist=0, $draft=0, $excluser='', $socid=0, $limit=0, $offset=0, $sortfield='c.date_commande', $sortorder='DESC')
    +	{
    +        // phpcs:enable
    +		global $user;
    +
    +		$ga = array();
    +
    +		$sql = "SELECT s.rowid, s.nom as name, s.client,";
    +		$sql.= " c.rowid as cid, c.ref";
    +		if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c";
    +		if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    +		$sql.= " WHERE c.entity IN (".getEntity('commande').")";
    +		$sql.= " AND c.fk_soc = s.rowid";
    +		if (! $user->rights->societe->client->voir && ! $socid) //restriction
    +		{
    +			$sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
    +		}
    +		if ($socid) $sql.= " AND s.rowid = ".$socid;
    +		if ($draft) $sql.= " AND c.fk_statut = ".self::STATUS_DRAFT;
    +		if (is_object($excluser)) $sql.= " AND c.fk_user_author <> ".$excluser->id;
    +		$sql.= $this->db->order($sortfield,$sortorder);
    +		$sql.= $this->db->plimit($limit,$offset);
    +
    +		$result=$this->db->query($sql);
    +		if ($result)
    +		{
    +			$numc = $this->db->num_rows($result);
    +			if ($numc)
    +			{
    +				$i = 0;
    +				while ($i < $numc)
    +				{
    +					$obj = $this->db->fetch_object($result);
    +
    +					if ($shortlist == 1)
    +					{
    +						$ga[$obj->cid] = $obj->ref;
    +					}
    +					else if ($shortlist == 2)
    +					{
    +						$ga[$obj->cid] = $obj->ref.' ('.$obj->name.')';
    +					}
    +					else
    +					{
    +						$ga[$i]['id']	= $obj->cid;
    +						$ga[$i]['ref'] 	= $obj->ref;
    +						$ga[$i]['name'] = $obj->name;
    +					}
    +					$i++;
    +				}
    +			}
    +			return $ga;
    +		}
    +		else
    +		{
    +			dol_print_error($this->db);
    +			return -1;
    +		}
    +	}
    +
    +	/**
    +	 *	Update delivery delay
    +	 *
    +	 *	@param      int		$availability_id	Id du nouveau mode
    +	 *  @param     	int		$notrigger			1=Does not execute triggers, 0= execute triggers
    +	 *	@return     int         				>0 if OK, <0 if KO
    +	 */
    +	function availability($availability_id, $notrigger=0)
    +	{
    +		global $user;
    +
    +		dol_syslog('Commande::availability('.$availability_id.')');
    +		if ($this->statut >= self::STATUS_DRAFT)
    +		{
    +			$error=0;
    +
    +			$this->db->begin();
    +
    +			$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    +			$sql .= ' SET fk_availability = '.$availability_id;
    +			$sql .= ' WHERE rowid='.$this->id;
    +
    +			dol_syslog(__METHOD__, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->availability_id = $availability_id;
    +			}
    +
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +		else
    +		{
    +			$error_str='Command status do not meet requirement '.$this->statut;
    +			dol_syslog(__METHOD__.$error_str, LOG_ERR);
    +			$this->error=$error_str;
    +			$this->errors[]= $this->error;
    +			return -2;
    +		}
    +	}
    +
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Update order demand_reason
    +	 *
    +	 *  @param      int		$demand_reason_id	Id of new demand
    +	 *  @param     	int		$notrigger			1=Does not execute triggers, 0= execute triggers
    +	 *  @return     int        			 		>0 if ok, <0 if ko
    +	 */
    +	function demand_reason($demand_reason_id, $notrigger=0)
    +	{
    +        // phpcs:enable
    +		global $user;
    +
    +		dol_syslog('Commande::demand_reason('.$demand_reason_id.')');
    +		if ($this->statut >= self::STATUS_DRAFT)
    +		{
    +			$error=0;
    +
    +			$this->db->begin();
    +
    +			$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande';
    +			$sql .= ' SET fk_input_reason = '.$demand_reason_id;
    +			$sql .= ' WHERE rowid='.$this->id;
    +
    +			dol_syslog(__METHOD__, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->demand_reason_id = $demand_reason_id;
    +			}
    +
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +		else
    +		{
    +			$error_str='order status do not meet requirement '.$this->statut;
    +			dol_syslog(__METHOD__.$error_str, LOG_ERR);
    +			$this->error=$error_str;
    +			$this->errors[]= $this->error;
    +			return -2;
    +		}
    +	}
    +
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Set customer ref
    +	 *
    +	 *	@param      User	$user           User that make change
    +	 *	@param      string	$ref_client     Customer ref
    +	 *  @param     	int		$notrigger		1=Does not execute triggers, 0= execute triggers
    +	 *	@return     int             		<0 if KO, >0 if OK
    +	 */
    +	function set_ref_client($user, $ref_client, $notrigger=0)
    +	{
    +        // phpcs:enable
    +		if ($user->rights->commande->creer)
    +		{
    +			$error=0;
    +
    +			$this->db->begin();
    +
    +			$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande SET';
    +			$sql.= ' ref_client = '.(empty($ref_client) ? 'NULL' : '\''.$this->db->escape($ref_client).'\'');
    +			$sql.= ' WHERE rowid = '.$this->id;
    +
    +			dol_syslog(__METHOD__.' this->id='.$this->id.', ref_client='.$ref_client, LOG_DEBUG);
    +			$resql=$this->db->query($sql);
    +			if (!$resql)
    +			{
    +				$this->errors[]=$this->db->error();
    +				$error++;
    +			}
    +
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->ref_client = $ref_client;
    +			}
    +
    +			if (! $notrigger && empty($error))
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_MODIFY',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
    +			if (! $error)
    +			{
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(__METHOD__.' Error: '.$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +		else
    +		{
    +			return -1;
    +		}
    +	}
     
     	/**
     	 * Classify the order as invoiced
    @@ -2694,7 +2766,7 @@ class Commande extends CommonOrder
     	 */
     	function classifyBilled(User $user, $notrigger=0)
     	{
    -        $error = 0;
    +		$error = 0;
     
     		$this->db->begin();
     
    @@ -2713,10 +2785,10 @@ class Commande extends CommonOrder
     
     			if (! $notrigger && empty($error))
     			{
    -            	// Call trigger
    -            	$result=$this->call_trigger('ORDER_CLASSIFY_BILLED',$user);
    -            	if ($result < 0) $error++;
    -            	// End call triggers
    +				// Call trigger
    +				$result=$this->call_trigger('ORDER_CLASSIFY_BILLED',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
     			}
     
     			if (! $error)
    @@ -2738,7 +2810,7 @@ class Commande extends CommonOrder
     		else
     		{
     			$this->error=$this->db->error();
    -            $this->db->rollback();
    +			$this->db->rollback();
     			return -1;
     		}
     	}
    @@ -2750,146 +2822,146 @@ class Commande extends CommonOrder
     	 */
     	function classifyUnBilled()
     	{
    -	    global $conf, $user, $langs;
    -	    $error = 0;
    +		global $conf, $user, $langs;
    +		$error = 0;
     
    -	    $this->db->begin();
    +		$this->db->begin();
     
    -	    $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande SET facture = 0';
    -	    $sql.= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT;
    +		$sql = 'UPDATE '.MAIN_DB_PREFIX.'commande SET facture = 0';
    +		$sql.= ' WHERE rowid = '.$this->id.' AND fk_statut > '.self::STATUS_DRAFT;
     
    -	    dol_syslog(get_class($this)."::classifyUnBilled", LOG_DEBUG);
    -	    if ($this->db->query($sql))
    -	    {
    -	    	if (! $error)
    -	    	{
    -	    		$this->oldcopy= clone $this;
    -	    		$this->billed=1;
    -	    	}
    +		dol_syslog(get_class($this)."::classifyUnBilled", LOG_DEBUG);
    +		if ($this->db->query($sql))
    +		{
    +			if (! $error)
    +			{
    +				$this->oldcopy= clone $this;
    +				$this->billed=1;
    +			}
     
    -	        // Call trigger
    -	        $result=$this->call_trigger('ORDER_CLASSIFY_UNBILLED',$user);
    -	        if ($result < 0) $error++;
    -	        // End call triggers
    +			// Call trigger
    +			$result=$this->call_trigger('ORDER_CLASSIFY_UNBILLED',$user);
    +			if ($result < 0) $error++;
    +			// End call triggers
     
    -	        if (! $error)
    -	        {
    -	            $this->billed=0;
    +			if (! $error)
    +			{
    +				$this->billed=0;
     
    -	            $this->db->commit();
    -	            return 1;
    -	        }
    -	        else
    -	        {
    -	            foreach($this->errors as $errmsg)
    -	            {
    -	                dol_syslog(get_class($this)."::classifyUnBilled ".$errmsg, LOG_ERR);
    -	                $this->error.=($this->error?', '.$errmsg:$errmsg);
    -	            }
    -	            $this->db->rollback();
    -	            return -1*$error;
    -	        }
    -	    }
    -	    else
    -	    {
    -	        $this->error=$this->db->error();
    -	        $this->db->rollback();
    -	        return -1;
    -	    }
    +				$this->db->commit();
    +				return 1;
    +			}
    +			else
    +			{
    +				foreach($this->errors as $errmsg)
    +				{
    +					dol_syslog(get_class($this)."::classifyUnBilled ".$errmsg, LOG_ERR);
    +					$this->error.=($this->error?', '.$errmsg:$errmsg);
    +				}
    +				$this->db->rollback();
    +				return -1*$error;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			$this->db->rollback();
    +			return -1;
    +		}
     	}
     
     
    -    /**
    -     *  Update a line in database
    -     *
    -     *  @param    	int				$rowid            	Id of line to update
    -     *  @param    	string			$desc             	Description of line
    -     *  @param    	float			$pu               	Unit price
    -     *  @param    	float			$qty              	Quantity
    -     *  @param    	float			$remise_percent   	Percent of discount
    -     *  @param    	float			$txtva           	Taux TVA
    -     * 	@param		float			$txlocaltax1		Local tax 1 rate
    -     *  @param		float			$txlocaltax2		Local tax 2 rate
    -     *  @param    	string			$price_base_type	HT or TTC
    -     *  @param    	int				$info_bits        	Miscellaneous informations on line
    -     *  @param    	int				$date_start        	Start date of the line
    -     *  @param    	int				$date_end          	End date of the line
    -     * 	@param		int				$type				Type of line (0=product, 1=service)
    -     * 	@param		int				$fk_parent_line		Id of parent line (0 in most cases, used by modules adding sublevels into lines).
    -     * 	@param		int				$skip_update_total	Keep fields total_xxx to 0 (used for special lines by some modules)
    -     *  @param		int				$fk_fournprice		Id of origin supplier price
    -     *  @param		int				$pa_ht				Price (without tax) of product when it was bought
    -     *  @param		string			$label				Label
    -     *  @param		int				$special_code		Special code (also used by externals modules!)
    +	/**
    +	 *  Update a line in database
    +	 *
    +	 *  @param    	int				$rowid            	Id of line to update
    +	 *  @param    	string			$desc             	Description of line
    +	 *  @param    	float			$pu               	Unit price
    +	 *  @param    	float			$qty              	Quantity
    +	 *  @param    	float			$remise_percent   	Percent of discount
    +	 *  @param    	float			$txtva           	Taux TVA
    +	 * 	@param		float			$txlocaltax1		Local tax 1 rate
    +	 *  @param		float			$txlocaltax2		Local tax 2 rate
    +	 *  @param    	string			$price_base_type	HT or TTC
    +	 *  @param    	int				$info_bits        	Miscellaneous informations on line
    +	 *  @param    	int				$date_start        	Start date of the line
    +	 *  @param    	int				$date_end          	End date of the line
    +	 * 	@param		int				$type				Type of line (0=product, 1=service)
    +	 * 	@param		int				$fk_parent_line		Id of parent line (0 in most cases, used by modules adding sublevels into lines).
    +	 * 	@param		int				$skip_update_total	Keep fields total_xxx to 0 (used for special lines by some modules)
    +	 *  @param		int				$fk_fournprice		Id of origin supplier price
    +	 *  @param		int				$pa_ht				Price (without tax) of product when it was bought
    +	 *  @param		string			$label				Label
    +	 *  @param		int				$special_code		Special code (also used by externals modules!)
     	 *  @param		array			$array_options		extrafields array
    -     * 	@param 		string			$fk_unit 			Code of the unit to use. Null to use the default one
    +	 * 	@param 		string			$fk_unit 			Code of the unit to use. Null to use the default one
     	 *  @param		double			$pu_ht_devise		Amount in currency
    -     * 	@param		int				$notrigger			disable line update trigger
    -     *  @return   	int              					< 0 if KO, > 0 if OK
    -     */
    +	 * 	@param		int				$notrigger			disable line update trigger
    +	 *  @return   	int              					< 0 if KO, > 0 if OK
    +	 */
     	function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0,$txlocaltax2=0.0, $price_base_type='HT', $info_bits=0, $date_start='', $date_end='', $type=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0, $label='', $special_code=0, $array_options=0, $fk_unit=null, $pu_ht_devise = 0, $notrigger=0)
    -    {
    -        global $conf, $mysoc, $langs, $user;
    +	{
    +		global $conf, $mysoc, $langs, $user;
     
    -        dol_syslog(get_class($this)."::updateline id=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, date_start=$date_start, date_end=$date_end, type=$type, fk_parent_line=$fk_parent_line, pa_ht=$pa_ht, special_code=$special_code");
    -        include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    +		dol_syslog(get_class($this)."::updateline id=$rowid, desc=$desc, pu=$pu, qty=$qty, remise_percent=$remise_percent, txtva=$txtva, txlocaltax1=$txlocaltax1, txlocaltax2=$txlocaltax2, price_base_type=$price_base_type, info_bits=$info_bits, date_start=$date_start, date_end=$date_end, type=$type, fk_parent_line=$fk_parent_line, pa_ht=$pa_ht, special_code=$special_code");
    +		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
     
    -        if (! empty($this->brouillon))
    -        {
    -            $this->db->begin();
    +		if (! empty($this->brouillon))
    +		{
    +			$this->db->begin();
     
    -            // Clean parameters
    -            if (empty($qty)) $qty=0;
    -            if (empty($info_bits)) $info_bits=0;
    -            if (empty($txtva)) $txtva=0;
    -            if (empty($txlocaltax1)) $txlocaltax1=0;
    -            if (empty($txlocaltax2)) $txlocaltax2=0;
    -            if (empty($remise_percent)) $remise_percent=0;
    -            if (empty($special_code) || $special_code == 3) $special_code=0;
    +			// Clean parameters
    +			if (empty($qty)) $qty=0;
    +			if (empty($info_bits)) $info_bits=0;
    +			if (empty($txtva)) $txtva=0;
    +			if (empty($txlocaltax1)) $txlocaltax1=0;
    +			if (empty($txlocaltax2)) $txlocaltax2=0;
    +			if (empty($remise_percent)) $remise_percent=0;
    +			if (empty($special_code) || $special_code == 3) $special_code=0;
     
    -            $remise_percent=price2num($remise_percent);
    -            $qty=price2num($qty);
    -            $pu = price2num($pu);
    -      		$pa_ht=price2num($pa_ht);
    -        	$pu_ht_devise=price2num($pu_ht_devise);
    -            $txtva=price2num($txtva);
    -            $txlocaltax1=price2num($txlocaltax1);
    -            $txlocaltax2=price2num($txlocaltax2);
    +			$remise_percent=price2num($remise_percent);
    +			$qty=price2num($qty);
    +			$pu = price2num($pu);
    +			$pa_ht=price2num($pa_ht);
    +			$pu_ht_devise=price2num($pu_ht_devise);
    +			$txtva=price2num($txtva);
    +			$txlocaltax1=price2num($txlocaltax1);
    +			$txlocaltax2=price2num($txlocaltax2);
     
    -            // Calcul du total TTC et de la TVA pour la ligne a partir de
    -            // qty, pu, remise_percent et txtva
    -            // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
    -            // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
    +			// Calcul du total TTC et de la TVA pour la ligne a partir de
    +			// qty, pu, remise_percent et txtva
    +			// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
    +			// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
     
    -            $localtaxes_type=getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
    +			$localtaxes_type=getLocalTaxesFromRate($txtva, 0, $this->thirdparty, $mysoc);
     
    -       		// Clean vat code
    -    		$vat_src_code='';
    -    		if (preg_match('/\((.*)\)/', $txtva, $reg))
    -    		{
    -    		    $vat_src_code = $reg[1];
    -    		    $txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
    -    		}
    +			// Clean vat code
    +			$vat_src_code='';
    +			if (preg_match('/\((.*)\)/', $txtva, $reg))
    +			{
    +				$vat_src_code = $reg[1];
    +				$txtva = preg_replace('/\s*\(.*\)/', '', $txtva);    // Remove code into vatrate.
    +			}
     
    -            $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
    +			$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
     
    -            $total_ht  = $tabprice[0];
    -            $total_tva = $tabprice[1];
    -            $total_ttc = $tabprice[2];
    -            $total_localtax1 = $tabprice[9];
    -            $total_localtax2 = $tabprice[10];
    +			$total_ht  = $tabprice[0];
    +			$total_tva = $tabprice[1];
    +			$total_ttc = $tabprice[2];
    +			$total_localtax1 = $tabprice[9];
    +			$total_localtax2 = $tabprice[10];
     			$pu_ht  = $tabprice[3];
     			$pu_tva = $tabprice[4];
     			$pu_ttc = $tabprice[5];
     
     			// MultiCurrency
     			$multicurrency_total_ht  = $tabprice[16];
    -            $multicurrency_total_tva = $tabprice[17];
    -            $multicurrency_total_ttc = $tabprice[18];
    +			$multicurrency_total_tva = $tabprice[17];
    +			$multicurrency_total_ttc = $tabprice[18];
     			$pu_ht_devise = $tabprice[19];
     
    -            // Anciens indicateurs: $price, $subprice (a ne plus utiliser)
    -            $price = $pu_ht;
    +			// Anciens indicateurs: $price, $subprice (a ne plus utiliser)
    +			$price = $pu_ht;
     			if ($price_base_type == 'TTC')
     			{
     				$subprice = $pu_ttc;
    @@ -2898,72 +2970,72 @@ class Commande extends CommonOrder
     			{
     				$subprice = $pu_ht;
     			}
    -            $remise = 0;
    -            if ($remise_percent > 0)
    -            {
    -                $remise = round(($pu * $remise_percent / 100),2);
    -                $price = ($pu - $remise);
    -            }
    +			$remise = 0;
    +			if ($remise_percent > 0)
    +			{
    +				$remise = round(($pu * $remise_percent / 100),2);
    +				$price = ($pu - $remise);
    +			}
     
    -            //Fetch current line from the database and then clone the object and set it in $oldline property
    -            $line = new OrderLine($this->db);
    -            $line->fetch($rowid);
    +			//Fetch current line from the database and then clone the object and set it in $oldline property
    +			$line = new OrderLine($this->db);
    +			$line->fetch($rowid);
     
    -            if (!empty($line->fk_product))
    -            {
    -                $product=new Product($this->db);
    -                $result=$product->fetch($line->fk_product);
    -                $product_type=$product->type;
    +			if (!empty($line->fk_product))
    +			{
    +				$product=new Product($this->db);
    +				$result=$product->fetch($line->fk_product);
    +				$product_type=$product->type;
     
    -                if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER) && $product_type == 0 && $product->stock_reel < $qty)
    -                {
    -                    $langs->load("errors");
    -                    $this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnOrder', $product->ref);
    -                    dol_syslog(get_class($this)."::addline error=Product ".$product->ref.": ".$this->error, LOG_ERR);
    -                    $this->db->rollback();
    -                    return self::STOCK_NOT_ENOUGH_FOR_ORDER;
    -                }
    -            }
    +				if (! empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_ORDER) && $product_type == 0 && $product->stock_reel < $qty)
    +				{
    +					$langs->load("errors");
    +					$this->error=$langs->trans('ErrorStockIsNotEnoughToAddProductOnOrder', $product->ref);
    +					dol_syslog(get_class($this)."::addline error=Product ".$product->ref.": ".$this->error, LOG_ERR);
    +					$this->db->rollback();
    +					return self::STOCK_NOT_ENOUGH_FOR_ORDER;
    +				}
    +			}
     
    -            $staticline = clone $line;
    +			$staticline = clone $line;
     
    -            $line->oldline = $staticline;
    -            $this->line = $line;
    -            $this->line->context = $this->context;
    +			$line->oldline = $staticline;
    +			$this->line = $line;
    +			$this->line->context = $this->context;
     
    -            // Reorder if fk_parent_line change
    -            if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line)
    -            {
    -            	$rangmax = $this->line_max($fk_parent_line);
    -            	$this->line->rang = $rangmax + 1;
    -            }
    +			// Reorder if fk_parent_line change
    +			if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line)
    +			{
    +				$rangmax = $this->line_max($fk_parent_line);
    +				$this->line->rang = $rangmax + 1;
    +			}
     
    -            $this->line->rowid=$rowid;
    -            $this->line->label=$label;
    -            $this->line->desc=$desc;
    -            $this->line->qty=$qty;
    +			$this->line->rowid=$rowid;
    +			$this->line->label=$label;
    +			$this->line->desc=$desc;
    +			$this->line->qty=$qty;
     
    -            $this->line->vat_src_code	= $vat_src_code;
    -            $this->line->tva_tx         = $txtva;
    -            $this->line->localtax1_tx   = $txlocaltax1;
    -            $this->line->localtax2_tx   = $txlocaltax2;
    +			$this->line->vat_src_code	= $vat_src_code;
    +			$this->line->tva_tx         = $txtva;
    +			$this->line->localtax1_tx   = $txlocaltax1;
    +			$this->line->localtax2_tx   = $txlocaltax2;
     			$this->line->localtax1_type = $localtaxes_type[0];
     			$this->line->localtax2_type = $localtaxes_type[2];
    -            $this->line->remise_percent = $remise_percent;
    -            $this->line->subprice       = $subprice;
    -            $this->line->info_bits      = $info_bits;
    -            $this->line->special_code   = $special_code;
    -            $this->line->total_ht       = $total_ht;
    -            $this->line->total_tva      = $total_tva;
    -            $this->line->total_localtax1= $total_localtax1;
    -            $this->line->total_localtax2= $total_localtax2;
    -            $this->line->total_ttc      = $total_ttc;
    -            $this->line->date_start     = $date_start;
    -            $this->line->date_end       = $date_end;
    -            $this->line->product_type   = $type;
    -            $this->line->fk_parent_line = $fk_parent_line;
    -            $this->line->skip_update_total=$skip_update_total;
    -	        $this->line->fk_unit        = $fk_unit;
    +			$this->line->remise_percent = $remise_percent;
    +			$this->line->subprice       = $subprice;
    +			$this->line->info_bits      = $info_bits;
    +			$this->line->special_code   = $special_code;
    +			$this->line->total_ht       = $total_ht;
    +			$this->line->total_tva      = $total_tva;
    +			$this->line->total_localtax1= $total_localtax1;
    +			$this->line->total_localtax2= $total_localtax2;
    +			$this->line->total_ttc      = $total_ttc;
    +			$this->line->date_start     = $date_start;
    +			$this->line->date_end       = $date_end;
    +			$this->line->product_type   = $type;
    +			$this->line->fk_parent_line = $fk_parent_line;
    +			$this->line->skip_update_total=$skip_update_total;
    +			$this->line->fk_unit        = $fk_unit;
     
     			$this->line->fk_fournprice = $fk_fournprice;
     			$this->line->pa_ht = $pa_ht;
    @@ -2971,44 +3043,44 @@ class Commande extends CommonOrder
     			// Multicurrency
     			$this->line->multicurrency_subprice		= $pu_ht_devise;
     			$this->line->multicurrency_total_ht 	= $multicurrency_total_ht;
    -            $this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
    -            $this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
    +			$this->line->multicurrency_total_tva 	= $multicurrency_total_tva;
    +			$this->line->multicurrency_total_ttc 	= $multicurrency_total_ttc;
     
    -            // TODO deprecated
    -            $this->line->price=$price;
    -            $this->line->remise=$remise;
    +			// TODO deprecated
    +			$this->line->price=$price;
    +			$this->line->remise=$remise;
     
     			if (is_array($array_options) && count($array_options)>0) {
     				$this->line->array_options=$array_options;
     			}
     
    -            $result=$this->line->update($user, $notrigger);
    -            if ($result > 0)
    -            {
    -            	// Reorder if child line
    -            	if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
    +			$result=$this->line->update($user, $notrigger);
    +			if ($result > 0)
    +			{
    +				// Reorder if child line
    +				if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
     
    -                // Mise a jour info denormalisees
    -                $this->update_price(1);
    +				// Mise a jour info denormalisees
    +				$this->update_price(1);
     
    -                $this->db->commit();
    -                return $result;
    -            }
    -            else
    -            {
    -	            $this->error=$this->line->error;
    +				$this->db->commit();
    +				return $result;
    +			}
    +			else
    +			{
    +				$this->error=$this->line->error;
     
    -	            $this->db->rollback();
    -	            return -1;
    -            }
    -        }
    -        else
    -        {
    -            $this->error=get_class($this)."::updateline Order status makes operation forbidden";
    -        	$this->errors=array('OrderStatusMakeOperationForbidden');
    -            return -2;
    -        }
    -    }
    +				$this->db->rollback();
    +				return -1;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=get_class($this)."::updateline Order status makes operation forbidden";
    +			$this->errors=array('OrderStatusMakeOperationForbidden');
    +			return -2;
    +		}
    +	}
     
     	/**
     	 *      Update database
    @@ -3105,31 +3177,31 @@ class Commande extends CommonOrder
     		}
     	}
     
    -    /**
    -     *	Delete the customer order
    -     *
    -     *	@param	User	$user		User object
    -     *	@param	int		$notrigger	1=Does not execute triggers, 0= execute triggers
    -     * 	@return	int					<=0 if KO, >0 if OK
    -     */
    -    function delete($user, $notrigger=0)
    -    {
    -        global $conf, $langs;
    -        require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    +	/**
    +	 *	Delete the customer order
    +	 *
    +	 *	@param	User	$user		User object
    +	 *	@param	int		$notrigger	1=Does not execute triggers, 0= execute triggers
    +	 * 	@return	int					<=0 if KO, >0 if OK
    +	 */
    +	function delete($user, $notrigger=0)
    +	{
    +		global $conf, $langs;
    +		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    -        $error = 0;
    +		$error = 0;
     
    -        dol_syslog(get_class($this) . "::delete ".$this->id, LOG_DEBUG);
    +		dol_syslog(get_class($this) . "::delete ".$this->id, LOG_DEBUG);
     
    -        $this->db->begin();
    +		$this->db->begin();
     
    -        if (! $error && ! $notrigger)
    -        {
    -            // Call trigger
    -            $result=$this->call_trigger('ORDER_DELETE',$user);
    -            if ($result < 0) $error++;
    -            // End call triggers
    -        }
    +		if (! $error && ! $notrigger)
    +		{
    +			// Call trigger
    +			$result=$this->call_trigger('ORDER_DELETE',$user);
    +			if ($result < 0) $error++;
    +			// End call triggers
    +		}
     
     		if ($this->nb_expedition() != 0)
     		{
    @@ -3137,311 +3209,318 @@ class Commande extends CommonOrder
     			$error++;
     		}
     
    -        if (! $error)
    -        {
    -        	// Delete order details
    -        	$sql = 'DELETE FROM '.MAIN_DB_PREFIX."commandedet WHERE fk_commande = ".$this->id;
    -        	if (! $this->db->query($sql) )
    -        	{
    -        		$error++;
    -        		$this->errors[]=$this->db->lasterror();
    -        	}
    -        }
    +		if (! $error)
    +		{
    +			// Delete order details
    +			$sql = 'DELETE FROM '.MAIN_DB_PREFIX."commandedet WHERE fk_commande = ".$this->id;
    +			if (! $this->db->query($sql) )
    +			{
    +				$error++;
    +				$this->errors[]=$this->db->lasterror();
    +			}
    +		}
     
    -        if (! $error)
    -        {
    -        	// Delete linked object
    -        	$res = $this->deleteObjectLinked();
    -        	if ($res < 0) $error++;
    -        }
    +		if (! $error)
    +		{
    +			// Delete linked object
    +			$res = $this->deleteObjectLinked();
    +			if ($res < 0) $error++;
    +		}
     
    -        if (! $error)
    -        {
    -        	// Delete linked contacts
    -        	$res = $this->delete_linked_contact();
    -        	if ($res < 0) $error++;
    -        }
    +		if (! $error)
    +		{
    +			// Delete linked contacts
    +			$res = $this->delete_linked_contact();
    +			if ($res < 0) $error++;
    +		}
     
    -        if (! $error)
    -        {
    -        	// Remove extrafields
    -        	if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
    -        	{
    -        		$result=$this->deleteExtraFields();
    -        		if ($result < 0)
    -        		{
    -        			$error++;
    -        			dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
    -        		}
    -        	}
    -        }
    +		if (! $error)
    +		{
    +			// Remove extrafields
    +			if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
    +			{
    +				$result=$this->deleteExtraFields();
    +				if ($result < 0)
    +				{
    +					$error++;
    +					dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
    +				}
    +			}
    +		}
     
    -        if (! $error)
    -        {
    -        	// Delete object
    -        	$sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande WHERE rowid = ".$this->id;
    -        	if (! $this->db->query($sql) )
    -        	{
    -        		$error++;
    -        		$this->errors[]=$this->db->lasterror();
    -        	}
    -        }
    +		if (! $error)
    +		{
    +			// Delete object
    +			$sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande WHERE rowid = ".$this->id;
    +			if (! $this->db->query($sql) )
    +			{
    +				$error++;
    +				$this->errors[]=$this->db->lasterror();
    +			}
    +		}
     
    -        if (! $error)
    -        {
    -        	// Remove directory with files
    -        	$comref = dol_sanitizeFileName($this->ref);
    -        	if ($conf->commande->dir_output && !empty($this->ref))
    -        	{
    -        		$dir = $conf->commande->dir_output . "/" . $comref ;
    -        		$file = $conf->commande->dir_output . "/" . $comref . "/" . $comref . ".pdf";
    -        		if (file_exists($file))	// We must delete all files before deleting directory
    -        		{
    -        			dol_delete_preview($this);
    +		if (! $error)
    +		{
    +			// Remove directory with files
    +			$comref = dol_sanitizeFileName($this->ref);
    +			if ($conf->commande->dir_output && !empty($this->ref))
    +			{
    +				$dir = $conf->commande->dir_output . "/" . $comref ;
    +				$file = $conf->commande->dir_output . "/" . $comref . "/" . $comref . ".pdf";
    +				if (file_exists($file))	// We must delete all files before deleting directory
    +				{
    +					dol_delete_preview($this);
     
    -        			if (! dol_delete_file($file,0,0,0,$this)) // For triggers
    -        			{
    -        				$this->db->rollback();
    -        				return 0;
    -        			}
    -        		}
    -        		if (file_exists($dir))
    -        		{
    -        			if (! dol_delete_dir_recursive($dir))
    -        			{
    -        				$this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
    -        				$this->db->rollback();
    -        				return 0;
    -        			}
    -        		}
    -        	}
    -        }
    +					if (! dol_delete_file($file,0,0,0,$this)) // For triggers
    +					{
    +						$this->db->rollback();
    +						return 0;
    +					}
    +				}
    +				if (file_exists($dir))
    +				{
    +					if (! dol_delete_dir_recursive($dir))
    +					{
    +						$this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
    +						$this->db->rollback();
    +						return 0;
    +					}
    +				}
    +			}
    +		}
     
    -        if (! $error)
    -        {
    -        	$this->db->commit();
    -        	return 1;
    -        }
    -        else
    -        {
    -	        foreach($this->errors as $errmsg)
    -	        {
    -		        $this->error.=($this->error?', '.$errmsg:$errmsg);
    -	        }
    -	        $this->db->rollback();
    -	        return -1*$error;
    -        }
    -    }
    +		if (! $error)
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +		else
    +		{
    +			foreach($this->errors as $errmsg)
    +			{
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +	}
     
     
    -    /**
    -     *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
    -     *
    -     *	@param		User	$user   Object user
    -     *	@return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
    -     */
    -    function load_board($user)
    -    {
    -        global $conf, $langs;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
    +	 *
    +	 *	@param		User	$user   Object user
    +	 *	@return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
    +	 */
    +	function load_board($user)
    +	{
    +        // phpcs:enable
    +		global $conf, $langs;
     
    -        $clause = " WHERE";
    +		$clause = " WHERE";
     
    -        $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.date_livraison as delivery_date, c.fk_statut";
    -        $sql.= " FROM ".MAIN_DB_PREFIX."commande as c";
    -        if (!$user->rights->societe->client->voir && !$user->societe_id)
    -        {
    -            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc";
    -            $sql.= " WHERE sc.fk_user = " .$user->id;
    -            $clause = " AND";
    -        }
    -        $sql.= $clause." c.entity IN (".getEntity('commande').")";
    -        //$sql.= " AND c.fk_statut IN (1,2,3) AND c.facture = 0";
    -        $sql.= " AND ((c.fk_statut IN (".self::STATUS_VALIDATED.",".self::STATUS_SHIPMENTONPROCESS.")) OR (c.fk_statut = ".self::STATUS_CLOSED." AND c.facture = 0))";    // If status is 2 and facture=1, it must be selected
    -        if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id;
    +		$sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.date_livraison as delivery_date, c.fk_statut, c.total_ht";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."commande as c";
    +		if (!$user->rights->societe->client->voir && !$user->societe_id)
    +		{
    +			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc";
    +			$sql.= " WHERE sc.fk_user = " .$user->id;
    +			$clause = " AND";
    +		}
    +		$sql.= $clause." c.entity IN (".getEntity('commande').")";
    +		//$sql.= " AND c.fk_statut IN (1,2,3) AND c.facture = 0";
    +		$sql.= " AND ((c.fk_statut IN (".self::STATUS_VALIDATED.",".self::STATUS_SHIPMENTONPROCESS.")) OR (c.fk_statut = ".self::STATUS_CLOSED." AND c.facture = 0))";    // If status is 2 and facture=1, it must be selected
    +		if ($user->societe_id) $sql.=" AND c.fk_soc = ".$user->societe_id;
     
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    -	        $response = new WorkboardResponse();
    -	        $response->warning_delay=$conf->commande->client->warning_delay/60/60/24;
    -	        $response->label=$langs->trans("OrdersToProcess");
    -	        $response->url=DOL_URL_ROOT.'/commande/list.php?viewstatut=-3&mainmenu=commercial&leftmenu=orders';
    -	        $response->img=img_object('',"order");
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			$response = new WorkboardResponse();
    +			$response->warning_delay=$conf->commande->client->warning_delay/60/60/24;
    +			$response->label=$langs->trans("OrdersToProcess");
    +			$response->url=DOL_URL_ROOT.'/commande/list.php?viewstatut=-3&mainmenu=commercial&leftmenu=orders';
    +			$response->img=img_object('',"order");
     
    -            $generic_commande = new Commande($this->db);
    +			$generic_commande = new Commande($this->db);
     
    -            while ($obj=$this->db->fetch_object($resql))
    -            {
    -                $response->nbtodo++;
    +			while ($obj=$this->db->fetch_object($resql))
    +			{
    +				$response->nbtodo++;
    +				$response->total+= $obj->total_ht;
     
    -                $generic_commande->statut = $obj->fk_statut;
    -                $generic_commande->date_commande = $this->db->jdate($obj->date_commande);
    -                $generic_commande->date_livraison = $this->db->jdate($obj->delivery_date);
    +				$generic_commande->statut = $obj->fk_statut;
    +				$generic_commande->date_commande = $this->db->jdate($obj->date_commande);
    +				$generic_commande->date_livraison = $this->db->jdate($obj->delivery_date);
     
    -                if ($generic_commande->hasDelay()) {
    -		            $response->nbtodolate++;
    -	            }
    -            }
    +				if ($generic_commande->hasDelay()) {
    +					$response->nbtodolate++;
    +				}
    +			}
     
    -            return $response;
    -        }
    -        else
    -        {
    -            $this->error=$this->db->error();
    -            return -1;
    -        }
    -    }
    +			return $response;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			return -1;
    +		}
    +	}
     
    -    /**
    -     *	Return source label of order
    -     *
    -     *	@return     string      Label
    -     */
    -    function getLabelSource()
    -    {
    -        global $langs;
    +	/**
    +	 *	Return source label of order
    +	 *
    +	 *	@return     string      Label
    +	 */
    +	function getLabelSource()
    +	{
    +		global $langs;
     
    -        $label=$langs->trans('OrderSource'.$this->source);
    +		$label=$langs->trans('OrderSource'.$this->source);
     
    -        if ($label == 'OrderSource') return '';
    -        return $label;
    -    }
    +		if ($label == 'OrderSource') return '';
    +		return $label;
    +	}
     
    -    /**
    -     *	Return status label of Order
    -     *
    -     *	@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
    -     */
    -    function getLibStatut($mode)
    -    {
    -        return $this->LibStatut($this->statut, $this->billed, $mode);
    -    }
    +	/**
    +	 *	Return status label of Order
    +	 *
    +	 *	@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
    +	 */
    +	function getLibStatut($mode)
    +	{
    +		return $this->LibStatut($this->statut, $this->billed, $mode);
    +	}
     
    -    /**
    -     *	Return label of status
    -     *
    -     *	@param		int		$statut      	  Id statut
    -     *  @param      int		$billed    		  If invoiced
    -     *	@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
    -     *  @param      int     $donotshowbilled  Do not show billed status after order status
    -     *  @return     string					  Label of status
    -     */
    -    function LibStatut($statut,$billed,$mode,$donotshowbilled=0)
    -    {
    -        global $langs, $conf;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Return label of status
    +	 *
    +	 *	@param		int		$statut      	  Id statut
    +	 *  @param      int		$billed    		  If invoiced
    +	 *	@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
    +	 *  @param      int     $donotshowbilled  Do not show billed status after order status
    +	 *  @return     string					  Label of status
    +	 */
    +	function LibStatut($statut,$billed,$mode,$donotshowbilled=0)
    +	{
    +        // phpcs:enable
    +		global $langs, $conf;
     
    -        $billedtext = '';
    -        if (empty($donotshowbilled)) $billedtext .= ($billed?' - '.$langs->trans("Billed"):'');
    +		$billedtext = '';
    +		if (empty($donotshowbilled)) $billedtext .= ($billed?' - '.$langs->trans("Billed"):'');
     
    -        //print 'x'.$statut.'-'.$billed;
    -        if ($mode == 0)
    -        {
    -            if ($statut==self::STATUS_CANCELED) return $langs->trans('StatusOrderCanceled');
    -            if ($statut==self::STATUS_DRAFT) return $langs->trans('StatusOrderDraft');
    -            if ($statut==self::STATUS_VALIDATED) return $langs->trans('StatusOrderValidated').$billedtext;
    -            if ($statut==self::STATUS_SHIPMENTONPROCESS) return $langs->trans('StatusOrderSentShort').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderToBill');
    -            if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderProcessed').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderDelivered');
    -        }
    -        elseif ($mode == 1)
    -        {
    -            if ($statut==self::STATUS_CANCELED) return $langs->trans('StatusOrderCanceledShort');
    -            if ($statut==self::STATUS_DRAFT) return $langs->trans('StatusOrderDraftShort');
    -            if ($statut==self::STATUS_VALIDATED) return $langs->trans('StatusOrderValidatedShort').$billedtext;
    -            if ($statut==self::STATUS_SHIPMENTONPROCESS) return $langs->trans('StatusOrderSentShort').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderToBillShort');
    -            if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderProcessed').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderDelivered');
    -        }
    -        elseif ($mode == 2)
    -        {
    -            if ($statut==self::STATUS_CANCELED) return img_picto($langs->trans('StatusOrderCanceled'),'statut5').' '.$langs->trans('StatusOrderCanceledShort');
    -            if ($statut==self::STATUS_DRAFT) return img_picto($langs->trans('StatusOrderDraft'),'statut0').' '.$langs->trans('StatusOrderDraftShort');
    -            if ($statut==self::STATUS_VALIDATED) return img_picto($langs->trans('StatusOrderValidated'),'statut1').' '.$langs->trans('StatusOrderValidatedShort').$billedtext;
    -            if ($statut==self::STATUS_SHIPMENTONPROCESS) return img_picto($langs->trans('StatusOrderSent'),'statut3').' '.$langs->trans('StatusOrderSentShort').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderToBill'),'statut4').' '.$langs->trans('StatusOrderToBillShort');
    -            if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6').' '.$langs->trans('StatusOrderProcessed').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderDelivered'),'statut6').' '.$langs->trans('StatusOrderDeliveredShort');
    -        }
    -        elseif ($mode == 3)
    -        {
    -            if ($statut==self::STATUS_CANCELED) return img_picto($langs->trans('StatusOrderCanceled'),'statut5');
    -            if ($statut==self::STATUS_DRAFT) return img_picto($langs->trans('StatusOrderDraft'),'statut0');
    -            if ($statut==self::STATUS_VALIDATED) return img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1');
    -            if ($statut==self::STATUS_SHIPMENTONPROCESS) return img_picto($langs->trans('StatusOrderSentShort').$billedtext,'statut3');
    -            if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderToBill'),'statut4');
    -            if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6');
    -            if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderDelivered'),'statut6');
    -        }
    -        elseif ($mode == 4)
    -        {
    -            if ($statut==self::STATUS_CANCELED) return img_picto($langs->trans('StatusOrderCanceled'),'statut5').' '.$langs->trans('StatusOrderCanceled');
    -            if ($statut==self::STATUS_DRAFT) return img_picto($langs->trans('StatusOrderDraft'),'statut0').' '.$langs->trans('StatusOrderDraft');
    -            if ($statut==self::STATUS_VALIDATED) return img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1').' '.$langs->trans('StatusOrderValidated').$billedtext;
    -            if ($statut==self::STATUS_SHIPMENTONPROCESS) return img_picto($langs->trans('StatusOrderSentShort').$billedtext,'statut3').' '.$langs->trans('StatusOrderSent').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderToBill'),'statut4').' '.$langs->trans('StatusOrderToBill');
    -            if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderProcessedShort').$billedtext,'statut6').' '.$langs->trans('StatusOrderProcessed').$billedtext;
    -            if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderDelivered'),'statut6').' '.$langs->trans('StatusOrderDelivered');
    -        }
    -        elseif ($mode == 5)
    -        {
    -            if ($statut==self::STATUS_CANCELED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderCanceledShort').' </span>'.img_picto($langs->trans('StatusOrderCanceled'),'statut5');
    -            if ($statut==self::STATUS_DRAFT) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDraftShort').' </span>'.img_picto($langs->trans('StatusOrderDraft'),'statut0');
    -            if ($statut==self::STATUS_VALIDATED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderValidatedShort').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1');
    -            if ($statut==self::STATUS_SHIPMENTONPROCESS) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderSentShort').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderSent').$billedtext,'statut3');
    -            if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderToBillShort').' </span>'.img_picto($langs->trans('StatusOrderToBill'),'statut4');
    -            if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderProcessedShort').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6');
    -            if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDeliveredShort').' </span>'.img_picto($langs->trans('StatusOrderDelivered'),'statut6');
    -        }
    -        elseif ($mode == 6)
    -        {
    -        	if ($statut==self::STATUS_CANCELED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderCanceled').' </span>'.img_picto($langs->trans('StatusOrderCanceled'),'statut5');
    -        	if ($statut==self::STATUS_DRAFT) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDraft').' </span>'.img_picto($langs->trans('StatusOrderDraft'),'statut0');
    -        	if ($statut==self::STATUS_VALIDATED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderValidated').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1');
    -        	if ($statut==self::STATUS_SHIPMENTONPROCESS) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderSent').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderSent').$billedtext,'statut3');
    -        	if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderToBill').' </span>'.img_picto($langs->trans('StatusOrderToBill'),'statut4');
    -        	if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderProcessed').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6');
    -        	if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDelivered').' </span>'.img_picto($langs->trans('StatusOrderDelivered'),'statut6');
    -        }
    -
    -    }
    +		//print 'x'.$statut.'-'.$billed;
    +		if ($mode == 0)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return $langs->trans('StatusOrderCanceled');
    +			if ($statut==self::STATUS_DRAFT) return $langs->trans('StatusOrderDraft');
    +			if ($statut==self::STATUS_VALIDATED) return $langs->trans('StatusOrderValidated').$billedtext;
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return $langs->trans('StatusOrderSentShort').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderToBill');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderProcessed').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderDelivered');
    +		}
    +		elseif ($mode == 1)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return $langs->trans('StatusOrderCanceledShort');
    +			if ($statut==self::STATUS_DRAFT) return $langs->trans('StatusOrderDraftShort');
    +			if ($statut==self::STATUS_VALIDATED) return $langs->trans('StatusOrderValidatedShort').$billedtext;
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return $langs->trans('StatusOrderSentShort').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderToBillShort');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderProcessed').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return $langs->trans('StatusOrderDelivered');
    +		}
    +		elseif ($mode == 2)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return img_picto($langs->trans('StatusOrderCanceled'),'statut5').' '.$langs->trans('StatusOrderCanceledShort');
    +			if ($statut==self::STATUS_DRAFT) return img_picto($langs->trans('StatusOrderDraft'),'statut0').' '.$langs->trans('StatusOrderDraftShort');
    +			if ($statut==self::STATUS_VALIDATED) return img_picto($langs->trans('StatusOrderValidated'),'statut1').' '.$langs->trans('StatusOrderValidatedShort').$billedtext;
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return img_picto($langs->trans('StatusOrderSent'),'statut3').' '.$langs->trans('StatusOrderSentShort').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderToBill'),'statut4').' '.$langs->trans('StatusOrderToBillShort');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6').' '.$langs->trans('StatusOrderProcessed').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderDelivered'),'statut6').' '.$langs->trans('StatusOrderDeliveredShort');
    +		}
    +		elseif ($mode == 3)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return img_picto($langs->trans('StatusOrderCanceled'),'statut5');
    +			if ($statut==self::STATUS_DRAFT) return img_picto($langs->trans('StatusOrderDraft'),'statut0');
    +			if ($statut==self::STATUS_VALIDATED) return img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1');
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return img_picto($langs->trans('StatusOrderSentShort').$billedtext,'statut3');
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderToBill'),'statut4');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6');
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderDelivered'),'statut6');
    +		}
    +		elseif ($mode == 4)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return img_picto($langs->trans('StatusOrderCanceled'),'statut5').' '.$langs->trans('StatusOrderCanceled');
    +			if ($statut==self::STATUS_DRAFT) return img_picto($langs->trans('StatusOrderDraft'),'statut0').' '.$langs->trans('StatusOrderDraft');
    +			if ($statut==self::STATUS_VALIDATED) return img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1').' '.$langs->trans('StatusOrderValidated').$billedtext;
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return img_picto($langs->trans('StatusOrderSentShort').$billedtext,'statut3').' '.$langs->trans('StatusOrderSent').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderToBill'),'statut4').' '.$langs->trans('StatusOrderToBill');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderProcessedShort').$billedtext,'statut6').' '.$langs->trans('StatusOrderProcessed').$billedtext;
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return img_picto($langs->trans('StatusOrderDelivered'),'statut6').' '.$langs->trans('StatusOrderDelivered');
    +		}
    +		elseif ($mode == 5)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderCanceledShort').' </span>'.img_picto($langs->trans('StatusOrderCanceled'),'statut5');
    +			if ($statut==self::STATUS_DRAFT) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDraftShort').' </span>'.img_picto($langs->trans('StatusOrderDraft'),'statut0');
    +			if ($statut==self::STATUS_VALIDATED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderValidatedShort').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1');
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderSentShort').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderSent').$billedtext,'statut3');
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderToBillShort').' </span>'.img_picto($langs->trans('StatusOrderToBill'),'statut4');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderProcessedShort').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6');
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDeliveredShort').' </span>'.img_picto($langs->trans('StatusOrderDelivered'),'statut6');
    +		}
    +		elseif ($mode == 6)
    +		{
    +			if ($statut==self::STATUS_CANCELED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderCanceled').' </span>'.img_picto($langs->trans('StatusOrderCanceled'),'statut5');
    +			if ($statut==self::STATUS_DRAFT) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDraft').' </span>'.img_picto($langs->trans('StatusOrderDraft'),'statut0');
    +			if ($statut==self::STATUS_VALIDATED) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderValidated').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderValidated').$billedtext,'statut1');
    +			if ($statut==self::STATUS_SHIPMENTONPROCESS) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderSent').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderSent').$billedtext,'statut3');
    +			if ($statut==self::STATUS_CLOSED && (! $billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderToBill').' </span>'.img_picto($langs->trans('StatusOrderToBill'),'statut4');
    +			if ($statut==self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderProcessed').$billedtext.' </span>'.img_picto($langs->trans('StatusOrderProcessed').$billedtext,'statut6');
    +			if ($statut==self::STATUS_CLOSED && (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) return '<span class="hideonsmartphone">'.$langs->trans('StatusOrderDelivered').' </span>'.img_picto($langs->trans('StatusOrderDelivered'),'statut6');
    +		}
    +	}
     
     
    -    /**
    -     *	Return clicable link of object (with eventually picto)
    -     *
    -     *	@param      int			$withpicto                Add picto into link
    -     *	@param      string	    $option                   Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
    -     *	@param      int			$max          	          Max length to show
    -     *	@param      int			$short			          ???
    -     *  @param	    int   	    $notooltip		          1=Disable tooltip
    -     *  @param      int         $save_lastsearch_value    -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
    -     *	@return     string          			          String with URL
    -     */
    -    function getNomUrl($withpicto=0, $option='', $max=0, $short=0, $notooltip=0, $save_lastsearch_value=-1)
    -    {
    -        global $conf, $langs, $user;
    +	/**
    +	 *	Return clicable link of object (with eventually picto)
    +	 *
    +	 *	@param      int			$withpicto                Add picto into link
    +	 *	@param      string	    $option                   Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
    +	 *	@param      int			$max          	          Max length to show
    +	 *	@param      int			$short			          ???
    +	 *  @param	    int   	    $notooltip		          1=Disable tooltip
    +	 *  @param      int         $save_lastsearch_value    -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
    +	 *	@return     string          			          String with URL
    +	 */
    +	function getNomUrl($withpicto=0, $option='', $max=0, $short=0, $notooltip=0, $save_lastsearch_value=-1)
    +	{
    +		global $conf, $langs, $user;
     
    -        if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
    +		if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
     
    -        $result='';
    +		$result='';
     
    -        if (! empty($conf->expedition->enabled) && ($option == '1' || $option == '2')) $url = DOL_URL_ROOT.'/expedition/shipment.php?id='.$this->id;
    -        else $url = DOL_URL_ROOT.'/commande/card.php?id='.$this->id;
    +		if (! empty($conf->expedition->enabled) && ($option == '1' || $option == '2')) $url = DOL_URL_ROOT.'/expedition/shipment.php?id='.$this->id;
    +		else $url = DOL_URL_ROOT.'/commande/card.php?id='.$this->id;
     
    -        if ($option !== 'nolink')
    -        {
    -            // Add param to save lastsearch_values or not
    -            $add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
    -            if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
    -            if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
    -        }
    +		if (!$user->rights->commande->lire)
    +			$option = 'nolink';
     
    -        if ($short) return $url;
    +		if ($option !== 'nolink')
    +		{
    +			// Add param to save lastsearch_values or not
    +			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
    +			if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
    +			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
    +		}
     
    -        $label = '';
    +		if ($short) return $url;
    +
    +		$label = '';
     
     		if ($user->rights->commande->lire) {
     			$label = '<u>'.$langs->trans("ShowOrder").'</u>';
    @@ -3461,225 +3540,231 @@ class Commande extends CommonOrder
     		$linkclose='';
     		if (empty($notooltip) && $user->rights->commande->lire)
     		{
    -		    if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
    -		    {
    -		        $label=$langs->trans("ShowOrder");
    -		        $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
    -		    }
    -		    $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
    -		    $linkclose.=' class="classfortooltip"';
    +			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
    +			{
    +				$label=$langs->trans("ShowOrder");
    +				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
    +			}
    +			$linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
    +			$linkclose.=' class="classfortooltip"';
     		}
     
    -        $linkstart = '<a href="'.$url.'"';
    -        $linkstart.=$linkclose.'>';
    -        $linkend='</a>';
    +		$linkstart = '<a href="'.$url.'"';
    +		$linkstart.=$linkclose.'>';
    +		$linkend='</a>';
     
    -        $result .= $linkstart;
    -        if ($withpicto) $result.=img_object(($notooltip?'':$label), $this->picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
    -        if ($withpicto != 2) $result.= $this->ref;
    -        $result .= $linkend;
    +		if ($option === 'nolink') {
    +			$linkstart = '';
    +			$linkend = '';
    +		}
     
    -        return $result;
    -    }
    +		$result .= $linkstart;
    +		if ($withpicto) $result.=img_object(($notooltip?'':$label), $this->picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
    +		if ($withpicto != 2) $result.= $this->ref;
    +		$result .= $linkend;
    +
    +		return $result;
    +	}
     
     
    -    /**
    -     *	Charge les informations d'ordre info dans l'objet commande
    -     *
    -     *	@param  int		$id       Id of order
    -     *	@return	void
    -     */
    -    function info($id)
    -    {
    -        $sql = 'SELECT c.rowid, date_creation as datec, tms as datem,';
    -        $sql.= ' date_valid as datev,';
    -        $sql.= ' date_cloture as datecloture,';
    -        $sql.= ' fk_user_author, fk_user_valid, fk_user_cloture';
    -        $sql.= ' FROM '.MAIN_DB_PREFIX.'commande as c';
    -        $sql.= ' WHERE c.rowid = '.$id;
    -        $result=$this->db->query($sql);
    -        if ($result)
    -        {
    -            if ($this->db->num_rows($result))
    -            {
    -                $obj = $this->db->fetch_object($result);
    -                $this->id = $obj->rowid;
    -                if ($obj->fk_user_author)
    -                {
    -                    $cuser = new User($this->db);
    -                    $cuser->fetch($obj->fk_user_author);
    -                    $this->user_creation   = $cuser;
    -                }
    +	/**
    +	 *	Charge les informations d'ordre info dans l'objet commande
    +	 *
    +	 *	@param  int		$id       Id of order
    +	 *	@return	void
    +	 */
    +	function info($id)
    +	{
    +		$sql = 'SELECT c.rowid, date_creation as datec, tms as datem,';
    +		$sql.= ' date_valid as datev,';
    +		$sql.= ' date_cloture as datecloture,';
    +		$sql.= ' fk_user_author, fk_user_valid, fk_user_cloture';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'commande as c';
    +		$sql.= ' WHERE c.rowid = '.$id;
    +		$result=$this->db->query($sql);
    +		if ($result)
    +		{
    +			if ($this->db->num_rows($result))
    +			{
    +				$obj = $this->db->fetch_object($result);
    +				$this->id = $obj->rowid;
    +				if ($obj->fk_user_author)
    +				{
    +					$cuser = new User($this->db);
    +					$cuser->fetch($obj->fk_user_author);
    +					$this->user_creation   = $cuser;
    +				}
     
    -                if ($obj->fk_user_valid)
    -                {
    -                    $vuser = new User($this->db);
    -                    $vuser->fetch($obj->fk_user_valid);
    -                    $this->user_validation = $vuser;
    -                }
    +				if ($obj->fk_user_valid)
    +				{
    +					$vuser = new User($this->db);
    +					$vuser->fetch($obj->fk_user_valid);
    +					$this->user_validation = $vuser;
    +				}
     
    -                if ($obj->fk_user_cloture)
    -                {
    -                    $cluser = new User($this->db);
    -                    $cluser->fetch($obj->fk_user_cloture);
    -                    $this->user_cloture   = $cluser;
    -                }
    +				if ($obj->fk_user_cloture)
    +				{
    +					$cluser = new User($this->db);
    +					$cluser->fetch($obj->fk_user_cloture);
    +					$this->user_cloture   = $cluser;
    +				}
     
    -                $this->date_creation     = $this->db->jdate($obj->datec);
    -                $this->date_modification = $this->db->jdate($obj->datem);
    -                $this->date_validation   = $this->db->jdate($obj->datev);
    -                $this->date_cloture      = $this->db->jdate($obj->datecloture);
    -            }
    +				$this->date_creation     = $this->db->jdate($obj->datec);
    +				$this->date_modification = $this->db->jdate($obj->datem);
    +				$this->date_validation   = $this->db->jdate($obj->datev);
    +				$this->date_cloture      = $this->db->jdate($obj->datecloture);
    +			}
     
    -            $this->db->free($result);
    -
    -        }
    -        else
    -        {
    -            dol_print_error($this->db);
    -        }
    -    }
    +			$this->db->free($result);
    +		}
    +		else
    +		{
    +			dol_print_error($this->db);
    +		}
    +	}
     
     
    -    /**
    -     *  Initialise an instance with random values.
    -     *  Used to build previews or test instances.
    -     *	id must be 0 if object instance is a specimen.
    -     *
    -     *  @return	void
    -     */
    -    function initAsSpecimen()
    -    {
    -        global $langs;
    +	/**
    +	 *  Initialise an instance with random values.
    +	 *  Used to build previews or test instances.
    +	 *	id must be 0 if object instance is a specimen.
    +	 *
    +	 *  @return	void
    +	 */
    +	function initAsSpecimen()
    +	{
    +		global $langs;
     
    -        dol_syslog(get_class($this)."::initAsSpecimen");
    +		dol_syslog(get_class($this)."::initAsSpecimen");
     
    -        // Load array of products prodids
    -        $num_prods = 0;
    -        $prodids = array();
    -        $sql = "SELECT rowid";
    -        $sql.= " FROM ".MAIN_DB_PREFIX."product";
    -        $sql.= " WHERE entity IN (".getEntity('product').")";
    -        $resql = $this->db->query($sql);
    -        if ($resql)
    -        {
    -            $num_prods = $this->db->num_rows($resql);
    -            $i = 0;
    -            while ($i < $num_prods)
    -            {
    -                $i++;
    -                $row = $this->db->fetch_row($resql);
    -                $prodids[$i] = $row[0];
    -            }
    -        }
    +		// Load array of products prodids
    +		$num_prods = 0;
    +		$prodids = array();
    +		$sql = "SELECT rowid";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."product";
    +		$sql.= " WHERE entity IN (".getEntity('product').")";
    +		$resql = $this->db->query($sql);
    +		if ($resql)
    +		{
    +			$num_prods = $this->db->num_rows($resql);
    +			$i = 0;
    +			while ($i < $num_prods)
    +			{
    +				$i++;
    +				$row = $this->db->fetch_row($resql);
    +				$prodids[$i] = $row[0];
    +			}
    +		}
     
    -        // Initialise parametres
    -        $this->id=0;
    -        $this->ref = 'SPECIMEN';
    -        $this->specimen=1;
    -        $this->socid = 1;
    -        $this->date = time();
    -        $this->date_lim_reglement=$this->date+3600*24*30;
    -        $this->cond_reglement_code = 'RECEP';
    -        $this->mode_reglement_code = 'CHQ';
    -        $this->availability_code   = 'DSP';
    -        $this->demand_reason_code  = 'SRC_00';
    -        $this->note_public='This is a comment (public)';
    -        $this->note_private='This is a comment (private)';
    -        // Lines
    -        $nbp = 5;
    -        $xnbp = 0;
    -        while ($xnbp < $nbp)
    -        {
    -            $line=new OrderLine($this->db);
    +		// Initialise parametres
    +		$this->id=0;
    +		$this->ref = 'SPECIMEN';
    +		$this->specimen=1;
    +		$this->socid = 1;
    +		$this->date = time();
    +		$this->date_lim_reglement=$this->date+3600*24*30;
    +		$this->cond_reglement_code = 'RECEP';
    +		$this->mode_reglement_code = 'CHQ';
    +		$this->availability_code   = 'DSP';
    +		$this->demand_reason_code  = 'SRC_00';
    +		$this->note_public='This is a comment (public)';
    +		$this->note_private='This is a comment (private)';
    +		// Lines
    +		$nbp = 5;
    +		$xnbp = 0;
    +		while ($xnbp < $nbp)
    +		{
    +			$line=new OrderLine($this->db);
     
    -            $line->desc=$langs->trans("Description")." ".$xnbp;
    -            $line->qty=1;
    -            $line->subprice=100;
    -            $line->price=100;
    -            $line->tva_tx=20;
    -            if ($xnbp == 2)
    -            {
    -                $line->total_ht=50;
    -                $line->total_ttc=60;
    -                $line->total_tva=10;
    -                $line->remise_percent=50;
    -            }
    -            else
    -            {
    -                $line->total_ht=100;
    -                $line->total_ttc=120;
    -                $line->total_tva=20;
    -                $line->remise_percent=0;
    -            }
    -            if ($num_prods > 0)
    -            {
    -            	$prodid = mt_rand(1, $num_prods);
    -            	$line->fk_product=$prodids[$prodid];
    +			$line->desc=$langs->trans("Description")." ".$xnbp;
    +			$line->qty=1;
    +			$line->subprice=100;
    +			$line->price=100;
    +			$line->tva_tx=20;
    +			if ($xnbp == 2)
    +			{
    +				$line->total_ht=50;
    +				$line->total_ttc=60;
    +				$line->total_tva=10;
    +				$line->remise_percent=50;
    +			}
    +			else
    +			{
    +				$line->total_ht=100;
    +				$line->total_ttc=120;
    +				$line->total_tva=20;
    +				$line->remise_percent=0;
    +			}
    +			if ($num_prods > 0)
    +			{
    +				$prodid = mt_rand(1, $num_prods);
    +				$line->fk_product=$prodids[$prodid];
     				$line->product_ref='SPECIMEN';
    -            }
    +			}
     
    -            $this->lines[$xnbp]=$line;
    +			$this->lines[$xnbp]=$line;
     
    -            $this->total_ht       += $line->total_ht;
    -            $this->total_tva      += $line->total_tva;
    -            $this->total_ttc      += $line->total_ttc;
    +			$this->total_ht       += $line->total_ht;
    +			$this->total_tva      += $line->total_tva;
    +			$this->total_ttc      += $line->total_ttc;
     
    -            $xnbp++;
    -        }
    -    }
    +			$xnbp++;
    +		}
    +	}
     
     
    -    /**
    -     *	Charge indicateurs this->nb de tableau de bord
    -     *
    -     *	@return     int         <0 si ko, >0 si ok
    -     */
    -    function load_state_board()
    -    {
    -        global $user;
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Charge indicateurs this->nb de tableau de bord
    +	 *
    +	 *	@return     int         <0 si ko, >0 si ok
    +	 */
    +	function load_state_board()
    +	{
    +        // phpcs:enable
    +		global $user;
     
    -        $this->nb=array();
    -        $clause = "WHERE";
    +		$this->nb=array();
    +		$clause = "WHERE";
     
    -        $sql = "SELECT count(co.rowid) as nb";
    -        $sql.= " FROM ".MAIN_DB_PREFIX."commande as co";
    -        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid";
    -        if (!$user->rights->societe->client->voir && !$user->societe_id)
    -        {
    -            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
    -            $sql.= " WHERE sc.fk_user = " .$user->id;
    -            $clause = "AND";
    -        }
    -        $sql.= " ".$clause." co.entity IN (".getEntity('commande').")";
    +		$sql = "SELECT count(co.rowid) as nb";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."commande as co";
    +		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid";
    +		if (!$user->rights->societe->client->voir && !$user->societe_id)
    +		{
    +			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
    +			$sql.= " WHERE sc.fk_user = " .$user->id;
    +			$clause = "AND";
    +		}
    +		$sql.= " ".$clause." co.entity IN (".getEntity('commande').")";
     
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    -            while ($obj=$this->db->fetch_object($resql))
    -            {
    -                $this->nb["orders"]=$obj->nb;
    -            }
    -            $this->db->free($resql);
    -            return 1;
    -        }
    -        else
    -        {
    -            dol_print_error($this->db);
    -            $this->error=$this->db->error();
    -            return -1;
    -        }
    -    }
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			while ($obj=$this->db->fetch_object($resql))
    +			{
    +				$this->nb["orders"]=$obj->nb;
    +			}
    +			$this->db->free($resql);
    +			return 1;
    +		}
    +		else
    +		{
    +			dol_print_error($this->db);
    +			$this->error=$this->db->error();
    +			return -1;
    +		}
    +	}
     
    -    /**
    +	/**
     	 * 	Create an array of order lines
     	 *
     	 * 	@return int		>0 if OK, <0 if KO
    -     */
    -    function getLinesArray()
    -    {
    -        return $this->fetch_lines();
    -    }
    +	 */
    +	function getLinesArray()
    +	{
    +		return $this->fetch_lines();
    +	}
     
     	/**
     	 *  Create a document onto disk according to template module.
    @@ -3689,7 +3774,7 @@ class Commande extends CommonOrder
     	 *  @param      int			$hidedetails    Hide details of lines
     	 *  @param      int			$hidedesc       Hide description
     	 *  @param      int			$hideref        Hide ref
    -         *  @param   null|array  $moreparams     Array to provide more information
    +	 *  @param   null|array  $moreparams     Array to provide more information
     	 *  @return     int         				0 if KO, 1 if OK
     	 */
     	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
    @@ -3726,45 +3811,45 @@ class Commande extends CommonOrder
     	public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
     	{
     		$tables = array(
    -			'commande'
    +		'commande'
     		);
     
     		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
     	}
     
    -    /**
    -     * Is the customer order delayed?
    -     *
    -     * @return bool     true if late, false if not
    -     */
    -    public function hasDelay()
    -    {
    -        global $conf;
    +	/**
    +	 * Is the customer order delayed?
    +	 *
    +	 * @return bool     true if late, false if not
    +	 */
    +	public function hasDelay()
    +	{
    +		global $conf;
     
    -        if (! ($this->statut > Commande::STATUS_DRAFT && $this->statut < Commande::STATUS_CLOSED)) {
    -            return false;   // Never late if not inside this status range
    -        }
    +		if (! ($this->statut > Commande::STATUS_DRAFT && $this->statut < Commande::STATUS_CLOSED)) {
    +			return false;   // Never late if not inside this status range
    +		}
     
    -        $now = dol_now();
    +		$now = dol_now();
     
    -        return max($this->date_commande, $this->date_livraison) < ($now - $conf->commande->client->warning_delay);
    -    }
    +		return max($this->date_commande, $this->date_livraison) < ($now - $conf->commande->client->warning_delay);
    +	}
     
    -    /**
    -     * Show the customer delayed info
    -     *
    -     * @return string       Show delayed information
    -     */
    -    public function showDelay()
    -    {
    -        global $conf, $langs;
    +	/**
    +	 * Show the customer delayed info
    +	 *
    +	 * @return string       Show delayed information
    +	 */
    +	public function showDelay()
    +	{
    +		global $conf, $langs;
     
    -        if (empty($this->date_livraison)) $text=$langs->trans("OrderDate").' '.dol_print_date($this->date_commande, 'day');
    -        else $text=$text=$langs->trans("DeliveryDate").' '.dol_print_date($this->date_livraison, 'day');
    -        $text.=' '.($conf->commande->client->warning_delay>0?'+':'-').' '.round(abs($conf->commande->client->warning_delay)/3600/24,1).' '.$langs->trans("days").' < '.$langs->trans("Today");
    +		if (empty($this->date_livraison)) $text=$langs->trans("OrderDate").' '.dol_print_date($this->date_commande, 'day');
    +		else $text=$text=$langs->trans("DeliveryDate").' '.dol_print_date($this->date_livraison, 'day');
    +		$text.=' '.($conf->commande->client->warning_delay>0?'+':'-').' '.round(abs($conf->commande->client->warning_delay)/3600/24,1).' '.$langs->trans("days").' < '.$langs->trans("Today");
     
    -        return $text;
    -    }
    +		return $text;
    +	}
     }
     
     
    @@ -3773,10 +3858,14 @@ class Commande extends CommonOrder
      */
     class OrderLine extends CommonOrderLine
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='commandedet';
    +
     	public $table_element='commandedet';
     
    -    var $oldline;
    +	var $oldline;
     
     	/**
     	 * Id of parent order
    @@ -3792,12 +3881,17 @@ class OrderLine extends CommonOrderLine
     	 */
     	public $commande_id;
     
    -    // From llx_commandedet
    -    var $fk_parent_line;
    -    var $fk_facture;
    -    var $label;
    -    var $fk_remise_except;
    -    var $rang = 0;
    +	// From llx_commandedet
    +	var $fk_parent_line;
    +	var $fk_facture;
    +
    +	/**
    +	 * @var string Order lines label
    +	 */
    +	public $label;
    +
    +	var $fk_remise_except;
    +	var $rang = 0;
     	var $fk_fournprice;
     
     	/**
    @@ -3805,8 +3899,8 @@ class OrderLine extends CommonOrderLine
     	 * @var float
     	 */
     	var $pa_ht;
    -    var $marge_tx;
    -    var $marque_tx;
    +	var $marge_tx;
    +	var $marque_tx;
     
     	/**
     	 * @deprecated
    @@ -3814,88 +3908,89 @@ class OrderLine extends CommonOrderLine
     	 */
     	var $remise;
     
    -    // Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    -    // Start and end date of the line
    -    var $date_start;
    -    var $date_end;
    +	// Added by Matelli (See http://matelli.fr/showcases/patchs-dolibarr/add-dates-in-order-lines.html)
    +	// Start and end date of the line
    +	var $date_start;
    +	var $date_end;
     
    -    var $skip_update_total; // Skip update price total for special lines
    +	var $skip_update_total; // Skip update price total for special lines
     
     
    -    /**
    -     *      Constructor
    -     *
    -     *      @param     DoliDB	$db      handler d'acces base de donnee
    -     */
    -    function __construct($db)
    -    {
    -        $this->db= $db;
    -    }
    +	/**
    +	 *      Constructor
    +	 *
    +	 *      @param     DoliDB	$db      handler d'acces base de donnee
    +	 */
    +	function __construct($db)
    +	{
    +		$this->db= $db;
    +	}
     
    -    /**
    -     *  Load line order
    -     *
    -     *  @param  int		$rowid          Id line order
    -     *  @return	int						<0 if KO, >0 if OK
    -     */
    -    function fetch($rowid)
    -    {
    -        $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_parent_line, cd.fk_product, cd.product_type, cd.label as custom_label, cd.description, cd.price, cd.qty, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx,';
    -        $sql.= ' cd.remise, cd.remise_percent, cd.fk_remise_except, cd.subprice,';
    -        $sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht, cd.rang, cd.special_code,';
    -	    $sql.= ' cd.fk_unit,';
    +	/**
    +	 *  Load line order
    +	 *
    +	 *  @param  int		$rowid          Id line order
    +	 *  @return	int						<0 if KO, >0 if OK
    +	 */
    +	function fetch($rowid)
    +	{
    +		$sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_parent_line, cd.fk_product, cd.product_type, cd.label as custom_label, cd.description, cd.price, cd.qty, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx,';
    +		$sql.= ' cd.remise, cd.remise_percent, cd.fk_remise_except, cd.subprice,';
    +		$sql.= ' cd.info_bits, cd.total_ht, cd.total_tva, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht, cd.rang, cd.special_code,';
    +		$sql.= ' cd.fk_unit,';
     		$sql.= ' cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc,';
    -        $sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc, p.tobatch as product_tobatch,';
    -        $sql.= ' cd.date_start, cd.date_end';
    -        $sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd';
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid';
    -        $sql.= ' WHERE cd.rowid = '.$rowid;
    -        $result = $this->db->query($sql);
    -        if ($result)
    -        {
    -            $objp = $this->db->fetch_object($result);
    -            $this->rowid            = $objp->rowid;
    -            $this->fk_commande      = $objp->fk_commande;
    -            $this->fk_parent_line   = $objp->fk_parent_line;
    -            $this->label            = $objp->custom_label;
    -            $this->desc             = $objp->description;
    -            $this->qty              = $objp->qty;
    -            $this->price            = $objp->price;
    -            $this->subprice         = $objp->subprice;
    -            $this->vat_src_code     = $objp->vat_src_code;
    -            $this->tva_tx           = $objp->tva_tx;
    -            $this->localtax1_tx		= $objp->localtax1_tx;
    -            $this->localtax2_tx		= $objp->localtax2_tx;
    -            $this->remise           = $objp->remise;
    -            $this->remise_percent   = $objp->remise_percent;
    -            $this->fk_remise_except = $objp->fk_remise_except;
    -            $this->fk_product       = $objp->fk_product;
    -            $this->product_type     = $objp->product_type;
    -            $this->info_bits        = $objp->info_bits;
    +		$sql.= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc, p.tobatch as product_tobatch,';
    +		$sql.= ' cd.date_start, cd.date_end';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'commandedet as cd';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid';
    +		$sql.= ' WHERE cd.rowid = '.$rowid;
    +		$result = $this->db->query($sql);
    +		if ($result)
    +		{
    +			$objp = $this->db->fetch_object($result);
    +			$this->rowid            = $objp->rowid;
    +			$this->id				= $objp->rowid;
    +			$this->fk_commande      = $objp->fk_commande;
    +			$this->fk_parent_line   = $objp->fk_parent_line;
    +			$this->label            = $objp->custom_label;
    +			$this->desc             = $objp->description;
    +			$this->qty              = $objp->qty;
    +			$this->price            = $objp->price;
    +			$this->subprice         = $objp->subprice;
    +			$this->vat_src_code     = $objp->vat_src_code;
    +			$this->tva_tx           = $objp->tva_tx;
    +			$this->localtax1_tx		= $objp->localtax1_tx;
    +			$this->localtax2_tx		= $objp->localtax2_tx;
    +			$this->remise           = $objp->remise;
    +			$this->remise_percent   = $objp->remise_percent;
    +			$this->fk_remise_except = $objp->fk_remise_except;
    +			$this->fk_product       = $objp->fk_product;
    +			$this->product_type     = $objp->product_type;
    +			$this->info_bits        = $objp->info_bits;
     			$this->special_code		= $objp->special_code;
    -            $this->total_ht         = $objp->total_ht;
    -            $this->total_tva        = $objp->total_tva;
    -            $this->total_localtax1  = $objp->total_localtax1;
    -            $this->total_localtax2  = $objp->total_localtax2;
    -            $this->total_ttc        = $objp->total_ttc;
    +			$this->total_ht         = $objp->total_ht;
    +			$this->total_tva        = $objp->total_tva;
    +			$this->total_localtax1  = $objp->total_localtax1;
    +			$this->total_localtax2  = $objp->total_localtax2;
    +			$this->total_ttc        = $objp->total_ttc;
     			$this->fk_fournprice	= $objp->fk_fournprice;
     			$marginInfos			= getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
     			$this->pa_ht			= $marginInfos[0];
     			$this->marge_tx			= $marginInfos[1];
     			$this->marque_tx		= $marginInfos[2];
    -            $this->special_code		= $objp->special_code;
    -            $this->rang             = $objp->rang;
    +			$this->special_code		= $objp->special_code;
    +			$this->rang             = $objp->rang;
     
    -            $this->ref				= $objp->product_ref;      // deprecated
    -            $this->product_ref		= $objp->product_ref;
    -            $this->libelle			= $objp->product_libelle;  // deprecated
    -            $this->product_label	= $objp->product_libelle;
    -            $this->product_desc     = $objp->product_desc;
    -            $this->product_tobatch  = $objp->product_tobatch;
    -            $this->fk_unit          = $objp->fk_unit;
    +			$this->ref				= $objp->product_ref;      // deprecated
    +			$this->product_ref		= $objp->product_ref;
    +			$this->libelle			= $objp->product_libelle;  // deprecated
    +			$this->product_label	= $objp->product_libelle;
    +			$this->product_desc     = $objp->product_desc;
    +			$this->product_tobatch  = $objp->product_tobatch;
    +			$this->fk_unit          = $objp->fk_unit;
     
    -            $this->date_start       = $this->db->jdate($objp->date_start);
    -            $this->date_end         = $this->db->jdate($objp->date_end);
    +			$this->date_start       = $this->db->jdate($objp->date_start);
    +			$this->date_end         = $this->db->jdate($objp->date_end);
     
     			$this->fk_multicurrency			= $objp->fk_multicurrency;
     			$this->multicurrency_code		= $objp->multicurrency_code;
    @@ -3904,38 +3999,38 @@ class OrderLine extends CommonOrderLine
     			$this->multicurrency_total_tva	= $objp->multicurrency_total_tva;
     			$this->multicurrency_total_ttc	= $objp->multicurrency_total_ttc;
     
    -            $this->db->free($result);
    +			$this->db->free($result);
     
    -            return 1;
    -        }
    -        else
    -        {
    -            $this->error = $this->db->lasterror();
    -            return -1;
    -        }
    -    }
    +			return 1;
    +		}
    +		else
    +		{
    +			$this->error = $this->db->lasterror();
    +			return -1;
    +		}
    +	}
     
    -    /**
    -     * 	Delete line in database
    -     *
    -     *	@param      User	$user        	User that modify
    +	/**
    +	 * 	Delete line in database
    +	 *
    +	 *	@param      User	$user        	User that modify
     	 *  @param      int		$notrigger	    0=launch triggers after, 1=disable triggers
    -     *	@return	 int  <0 si ko, >0 si ok
    -     */
    -    function delete($user=null, $notrigger=0)
    -    {
    -        global $conf, $user, $langs;
    +	 *	@return	 int  <0 si ko, >0 si ok
    +	 */
    +	function delete($user=null, $notrigger=0)
    +	{
    +		global $conf, $user, $langs;
     
     		$error=0;
     
    -	    $this->db->begin();
    +		$this->db->begin();
     
    -        $sql = 'DELETE FROM '.MAIN_DB_PREFIX."commandedet WHERE rowid=".$this->rowid;
    +		$sql = 'DELETE FROM '.MAIN_DB_PREFIX."commandedet WHERE rowid=".$this->rowid;
     
    -        dol_syslog("OrderLine::delete", LOG_DEBUG);
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    +		dol_syslog("OrderLine::delete", LOG_DEBUG);
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
     			// Remove extrafields
     			if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
     			{
    @@ -3950,63 +4045,63 @@ class OrderLine extends CommonOrderLine
     
     			if (! $error && ! $notrigger)
     			{
    -	            // Call trigger
    -	            $result=$this->call_trigger('LINEORDER_DELETE',$user);
    -	            if ($result < 0) $error++;
    -	            // End call triggers
    +				// Call trigger
    +				$result=$this->call_trigger('LINEORDER_DELETE',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
     			}
     
    -	        if (!$error) {
    -		        $this->db->commit();
    -		        return 1;
    -	        }
    +			if (!$error) {
    +				$this->db->commit();
    +				return 1;
    +			}
     
    -	        foreach($this->errors as $errmsg)
    -	        {
    -		        dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
    -		        $this->error.=($this->error?', '.$errmsg:$errmsg);
    -	        }
    -	        $this->db->rollback();
    -	        return -1*$error;
    -        }
    -        else
    -        {
    -            $this->error=$this->db->lasterror();
    -            return -1;
    -        }
    -    }
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->lasterror();
    +			return -1;
    +		}
    +	}
     
    -    /**
    -     *	Insert line into database
    -     *
    -     *	@param      User	$user        	User that modify
    -     *	@param      int		$notrigger		1 = disable triggers
    -     *	@return		int						<0 if KO, >0 if OK
    -     */
    -    function insert($user=null, $notrigger=0)
    -    {
    -        global $langs, $conf;
    +	/**
    +	 *	Insert line into database
    +	 *
    +	 *	@param      User	$user        	User that modify
    +	 *	@param      int		$notrigger		1 = disable triggers
    +	 *	@return		int						<0 if KO, >0 if OK
    +	 */
    +	function insert($user=null, $notrigger=0)
    +	{
    +		global $langs, $conf;
     
     		$error=0;
     
    -        $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'.
    +		$pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == ''); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'.
     
    -        dol_syslog(get_class($this)."::insert rang=".$this->rang);
    +		dol_syslog(get_class($this)."::insert rang=".$this->rang);
     
    -        // Clean parameters
    -        if (empty($this->tva_tx)) $this->tva_tx=0;
    -        if (empty($this->localtax1_tx)) $this->localtax1_tx=0;
    -        if (empty($this->localtax2_tx)) $this->localtax2_tx=0;
    +		// Clean parameters
    +		if (empty($this->tva_tx)) $this->tva_tx=0;
    +		if (empty($this->localtax1_tx)) $this->localtax1_tx=0;
    +		if (empty($this->localtax2_tx)) $this->localtax2_tx=0;
     		if (empty($this->localtax1_type)) $this->localtax1_type=0;
     		if (empty($this->localtax2_type)) $this->localtax2_type=0;
    -        if (empty($this->total_localtax1)) $this->total_localtax1=0;
    -        if (empty($this->total_localtax2)) $this->total_localtax2=0;
    -        if (empty($this->rang)) $this->rang=0;
    -        if (empty($this->remise)) $this->remise=0;
    -        if (empty($this->remise_percent)) $this->remise_percent=0;
    -        if (empty($this->info_bits)) $this->info_bits=0;
    -        if (empty($this->special_code)) $this->special_code=0;
    -        if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
    +		if (empty($this->total_localtax1)) $this->total_localtax1=0;
    +		if (empty($this->total_localtax2)) $this->total_localtax2=0;
    +		if (empty($this->rang)) $this->rang=0;
    +		if (empty($this->remise)) $this->remise=0;
    +		if (empty($this->remise_percent)) $this->remise_percent=0;
    +		if (empty($this->info_bits)) $this->info_bits=0;
    +		if (empty($this->special_code)) $this->special_code=0;
    +		if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
     		if (empty($this->pa_ht)) $this->pa_ht=0;
     
     		// if buy price not defined, define buyprice as configured in margin admin
    @@ -4022,65 +4117,65 @@ class OrderLine extends CommonOrderLine
     			}
     		}
     
    -        // Check parameters
    -        if ($this->product_type < 0) return -1;
    +		// Check parameters
    +		if ($this->product_type < 0) return -1;
     
    -        $this->db->begin();
    +		$this->db->begin();
     
    -        // Insertion dans base de la ligne
    -        $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'commandedet';
    -        $sql.= ' (fk_commande, fk_parent_line, label, description, qty, ';
    -        $sql.= ' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
    -        $sql.= ' fk_product, product_type, remise_percent, subprice, price, remise, fk_remise_except,';
    -        $sql.= ' special_code, rang, fk_product_fournisseur_price, buy_price_ht,';
    -        $sql.= ' info_bits, total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, date_start, date_end,';
    -	    $sql.= ' fk_unit';
    +		// Insertion dans base de la ligne
    +		$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'commandedet';
    +		$sql.= ' (fk_commande, fk_parent_line, label, description, qty, ';
    +		$sql.= ' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
    +		$sql.= ' fk_product, product_type, remise_percent, subprice, price, remise, fk_remise_except,';
    +		$sql.= ' special_code, rang, fk_product_fournisseur_price, buy_price_ht,';
    +		$sql.= ' info_bits, total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, date_start, date_end,';
    +		$sql.= ' fk_unit';
     		$sql.= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc';
     		$sql.= ')';
    -        $sql.= " VALUES (".$this->fk_commande.",";
    -        $sql.= " ".($this->fk_parent_line>0?"'".$this->db->escape($this->fk_parent_line)."'":"null").",";
    -        $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
    -        $sql.= " '".$this->db->escape($this->desc)."',";
    -        $sql.= " '".price2num($this->qty)."',";
    -        $sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").",";
    -        $sql.= " '".price2num($this->tva_tx)."',";
    -        $sql.= " '".price2num($this->localtax1_tx)."',";
    -        $sql.= " '".price2num($this->localtax2_tx)."',";
    +		$sql.= " VALUES (".$this->fk_commande.",";
    +		$sql.= " ".($this->fk_parent_line>0?"'".$this->db->escape($this->fk_parent_line)."'":"null").",";
    +		$sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
    +		$sql.= " '".$this->db->escape($this->desc)."',";
    +		$sql.= " '".price2num($this->qty)."',";
    +		$sql.= " ".(empty($this->vat_src_code)?"''":"'".$this->db->escape($this->vat_src_code)."'").",";
    +		$sql.= " '".price2num($this->tva_tx)."',";
    +		$sql.= " '".price2num($this->localtax1_tx)."',";
    +		$sql.= " '".price2num($this->localtax2_tx)."',";
     		$sql.= " '".$this->db->escape($this->localtax1_type)."',";
     		$sql.= " '".$this->db->escape($this->localtax2_type)."',";
    -        $sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").',';
    -        $sql.= " '".$this->db->escape($this->product_type)."',";
    -        $sql.= " '".price2num($this->remise_percent)."',";
    -        $sql.= " ".(price2num($this->subprice)!==''?price2num($this->subprice):"null").",";
    -        $sql.= " ".($this->price!=''?"'".price2num($this->price)."'":"null").",";
    -        $sql.= " '".price2num($this->remise)."',";
    -        $sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").',';
    -        $sql.= ' '.$this->special_code.',';
    -        $sql.= ' '.$this->rang.',';
    +		$sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").',';
    +		$sql.= " '".$this->db->escape($this->product_type)."',";
    +		$sql.= " '".price2num($this->remise_percent)."',";
    +		$sql.= " ".(price2num($this->subprice)!==''?price2num($this->subprice):"null").",";
    +		$sql.= " ".($this->price!=''?"'".price2num($this->price)."'":"null").",";
    +		$sql.= " '".price2num($this->remise)."',";
    +		$sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").',';
    +		$sql.= ' '.$this->special_code.',';
    +		$sql.= ' '.$this->rang.',';
     		$sql.= ' '.(! empty($this->fk_fournprice)?$this->fk_fournprice:"null").',';
     		$sql.= ' '.price2num($this->pa_ht).',';
    -        $sql.= " '".$this->db->escape($this->info_bits)."',";
    -        $sql.= " ".price2num($this->total_ht).",";
    -        $sql.= " ".price2num($this->total_tva).",";
    -        $sql.= " ".price2num($this->total_localtax1).",";
    -        $sql.= " ".price2num($this->total_localtax2).",";
    -        $sql.= " ".price2num($this->total_ttc).",";
    -        $sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").',';
    -        $sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").',';
    -	    $sql.= ' '.(!$this->fk_unit ? 'NULL' : $this->fk_unit);
    +		$sql.= " '".$this->db->escape($this->info_bits)."',";
    +		$sql.= " ".price2num($this->total_ht).",";
    +		$sql.= " ".price2num($this->total_tva).",";
    +		$sql.= " ".price2num($this->total_localtax1).",";
    +		$sql.= " ".price2num($this->total_localtax2).",";
    +		$sql.= " ".price2num($this->total_ttc).",";
    +		$sql.= " ".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null").',';
    +		$sql.= " ".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null").',';
    +		$sql.= ' '.(!$this->fk_unit ? 'NULL' : $this->fk_unit);
     		$sql.= ", ".(! empty($this->fk_multicurrency) ? $this->fk_multicurrency : 'NULL');
     		$sql.= ", '".$this->db->escape($this->multicurrency_code)."'";
     		$sql.= ", ".$this->multicurrency_subprice;
     		$sql.= ", ".$this->multicurrency_total_ht;
     		$sql.= ", ".$this->multicurrency_total_tva;
     		$sql.= ", ".$this->multicurrency_total_ttc;
    -        $sql.= ')';
    +		$sql.= ')';
     
    -        dol_syslog(get_class($this)."::insert", LOG_DEBUG);
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    -            $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'commandedet');
    +		dol_syslog(get_class($this)."::insert", LOG_DEBUG);
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			$this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'commandedet');
     
     			if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
     			{
    @@ -4092,42 +4187,42 @@ class OrderLine extends CommonOrderLine
     				}
     			}
     
    -            if (! $error && ! $notrigger)
    -            {
    -	            // Call trigger
    -	            $result=$this->call_trigger('LINEORDER_INSERT',$user);
    -	            if ($result < 0) $error++;
    -	            // End call triggers
    -            }
    +			if (! $error && ! $notrigger)
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('LINEORDER_INSERT',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
    +			}
     
    -	        if (!$error) {
    -		        $this->db->commit();
    -		        return 1;
    -	        }
    +			if (!$error) {
    +				$this->db->commit();
    +				return 1;
    +			}
     
    -	        foreach($this->errors as $errmsg)
    -	        {
    -		        dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
    -		        $this->error.=($this->error?', '.$errmsg:$errmsg);
    -	        }
    -	        $this->db->rollback();
    -	        return -1*$error;
    -        }
    -        else
    -        {
    -            $this->error=$this->db->error();
    -            $this->db->rollback();
    -            return -2;
    -        }
    -    }
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			$this->db->rollback();
    +			return -2;
    +		}
    +	}
     
    -    /**
    -     *	Update the line object into db
    -     *
    -     *	@param      User	$user        	User that modify
    +	/**
    +	 *	Update the line object into db
    +	 *
    +	 *	@param      User	$user        	User that modify
     	 *	@param      int		$notrigger		1 = disable triggers
    -     *	@return		int		<0 si ko, >0 si ok
    -     */
    +	 *	@return		int		<0 si ko, >0 si ok
    +	 */
     	function update(User $user, $notrigger=0)
     	{
     		global $conf,$langs;
    @@ -4150,7 +4245,7 @@ class OrderLine extends CommonOrderLine
     		if (empty($this->remise)) $this->remise=0;
     		if (empty($this->remise_percent)) $this->remise_percent=0;
     		if (empty($this->info_bits)) $this->info_bits=0;
    -        if (empty($this->special_code)) $this->special_code=0;
    +		if (empty($this->special_code)) $this->special_code=0;
     		if (empty($this->product_type)) $this->product_type=0;
     		if (empty($this->fk_parent_line)) $this->fk_parent_line=0;
     		if (empty($this->pa_ht)) $this->pa_ht=0;
    @@ -4196,7 +4291,7 @@ class OrderLine extends CommonOrderLine
     		$sql.= " , fk_product_fournisseur_price=".(! empty($this->fk_fournprice)?$this->fk_fournprice:"null");
     		$sql.= " , buy_price_ht='".price2num($this->pa_ht)."'";
     		$sql.= " , info_bits=".$this->info_bits;
    -        $sql.= " , special_code=".$this->special_code;
    +		$sql.= " , special_code=".$this->special_code;
     		$sql.= " , date_start=".(! empty($this->date_start)?"'".$this->db->idate($this->date_start)."'":"null");
     		$sql.= " , date_end=".(! empty($this->date_end)?"'".$this->db->idate($this->date_end)."'":"null");
     		$sql.= " , product_type=".$this->product_type;
    @@ -4206,9 +4301,9 @@ class OrderLine extends CommonOrderLine
     
     		// Multicurrency
     		$sql.= " , multicurrency_subprice=".price2num($this->multicurrency_subprice)."";
    -        $sql.= " , multicurrency_total_ht=".price2num($this->multicurrency_total_ht)."";
    -        $sql.= " , multicurrency_total_tva=".price2num($this->multicurrency_total_tva)."";
    -        $sql.= " , multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc)."";
    +		$sql.= " , multicurrency_total_ht=".price2num($this->multicurrency_total_ht)."";
    +		$sql.= " , multicurrency_total_tva=".price2num($this->multicurrency_total_tva)."";
    +		$sql.= " , multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc)."";
     
     		$sql.= " WHERE rowid = ".$this->rowid;
     
    @@ -4228,10 +4323,10 @@ class OrderLine extends CommonOrderLine
     
     			if (! $error && ! $notrigger)
     			{
    -	            // Call trigger
    -	            $result=$this->call_trigger('LINEORDER_UPDATE',$user);
    -	            if ($result < 0) $error++;
    -	            // End call triggers
    +				// Call trigger
    +				$result=$this->call_trigger('LINEORDER_UPDATE',$user);
    +				if ($result < 0) $error++;
    +				// End call triggers
     			}
     
     			if (!$error) {
    @@ -4255,43 +4350,44 @@ class OrderLine extends CommonOrderLine
     		}
     	}
     
    -    /**
    -     *	Update DB line fields total_xxx
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Update DB line fields total_xxx
     	 *	Used by migration
    -     *
    -     *	@return		int		<0 if KO, >0 if OK
    -     */
    -    function update_total()
    -    {
    -        $this->db->begin();
    +	 *
    +	 *	@return		int		<0 if KO, >0 if OK
    +	 */
    +	function update_total()
    +	{
    +        // phpcs:enable
    +		$this->db->begin();
     
    -        // Clean parameters
    -        if (empty($this->total_localtax1)) $this->total_localtax1=0;
    -        if (empty($this->total_localtax2)) $this->total_localtax2=0;
    +		// Clean parameters
    +		if (empty($this->total_localtax1)) $this->total_localtax1=0;
    +		if (empty($this->total_localtax2)) $this->total_localtax2=0;
     
    -        // Mise a jour ligne en base
    -        $sql = "UPDATE ".MAIN_DB_PREFIX."commandedet SET";
    -        $sql.= " total_ht='".price2num($this->total_ht)."'";
    -        $sql.= ",total_tva='".price2num($this->total_tva)."'";
    -        $sql.= ",total_localtax1='".price2num($this->total_localtax1)."'";
    -        $sql.= ",total_localtax2='".price2num($this->total_localtax2)."'";
    -        $sql.= ",total_ttc='".price2num($this->total_ttc)."'";
    -        $sql.= " WHERE rowid = ".$this->rowid;
    +		// Mise a jour ligne en base
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."commandedet SET";
    +		$sql.= " total_ht='".price2num($this->total_ht)."'";
    +		$sql.= ",total_tva='".price2num($this->total_tva)."'";
    +		$sql.= ",total_localtax1='".price2num($this->total_localtax1)."'";
    +		$sql.= ",total_localtax2='".price2num($this->total_localtax2)."'";
    +		$sql.= ",total_ttc='".price2num($this->total_ttc)."'";
    +		$sql.= " WHERE rowid = ".$this->rowid;
     
    -        dol_syslog("OrderLine::update_total", LOG_DEBUG);
    +		dol_syslog("OrderLine::update_total", LOG_DEBUG);
     
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    -            $this->db->commit();
    -            return 1;
    -        }
    -        else
    -        {
    -            $this->error=$this->db->error();
    -            $this->db->rollback();
    -            return -2;
    -        }
    -    }
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +		else
    +		{
    +			$this->error=$this->db->error();
    +			$this->db->rollback();
    +			return -2;
    +		}
    +	}
     }
    -
    diff --git a/htdocs/commande/class/commandestats.class.php b/htdocs/commande/class/commandestats.class.php
    index 6d9dde94bc4..13d7e245f05 100644
    --- a/htdocs/commande/class/commandestats.class.php
    +++ b/htdocs/commande/class/commandestats.class.php
    @@ -34,6 +34,9 @@ include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
      */
     class CommandeStats extends Stats
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element;
     
     	var $socid;
    @@ -219,6 +222,5 @@ class CommandeStats extends Stats
     
     		return $this->_getAllByProduct($sql);
     	}
    -
     }
     
    diff --git a/htdocs/commande/contact.php b/htdocs/commande/contact.php
    index 7669239134a..bd00116e026 100644
    --- a/htdocs/commande/contact.php
    +++ b/htdocs/commande/contact.php
    @@ -214,5 +214,6 @@ if ($id > 0 || ! empty($ref))
     }
     
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/customer.php b/htdocs/commande/customer.php
    index 9263ceb3f45..42def36ee28 100644
    --- a/htdocs/commande/customer.php
    +++ b/htdocs/commande/customer.php
    @@ -190,7 +190,7 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
    diff --git a/htdocs/commande/document.php b/htdocs/commande/document.php
    index ffebbaa260a..fc8192f7edb 100644
    --- a/htdocs/commande/document.php
    +++ b/htdocs/commande/document.php
    @@ -97,7 +97,7 @@ if ($id > 0 || ! empty($ref))
     		$head = commande_prepare_head($object);
     		dol_fiche_head($head, 'documents', $langs->trans('CustomerOrder'), -1, 'order');
     
    -		// Construit liste des fichiers
    +		// Build file list
     		$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     		$totalsize=0;
     		foreach($filearray as $key => $file)
    @@ -189,6 +189,6 @@ else
     }
     
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/commande/index.php b/htdocs/commande/index.php
    index 5cfb87c7a25..4c596620c6c 100644
    --- a/htdocs/commande/index.php
    +++ b/htdocs/commande/index.php
    @@ -479,6 +479,6 @@ if (! empty($conf->commande->enabled))
     print '</div></div></div>';
     
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/commande/info.php b/htdocs/commande/info.php
    index 4bac4a3a447..6c0b5f42ec6 100644
    --- a/htdocs/commande/info.php
    +++ b/htdocs/commande/info.php
    @@ -128,5 +128,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
    index a9da48fd626..2a9e215faa4 100644
    --- a/htdocs/commande/list.php
    +++ b/htdocs/commande/list.php
    @@ -1,15 +1,15 @@
     <?php
    -/* Copyright (C) 2001-2005 Rodolphe Quiedeville   <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2016 Laurent Destailleur    <eldy@users.sourceforge.net>
    - * Copyright (C) 2005      Marc Barilley / Ocebo  <marc@ocebo.com>
    - * Copyright (C) 2005-2012 Regis Houssin          <regis.houssin@capnetworks.com>
    - * Copyright (C) 2012      Juanjo Menent          <jmenent@2byte.es>
    - * Copyright (C) 2013      Christophe Battarel    <christophe.battarel@altairis.fr>
    - * Copyright (C) 2013      Cédric Salvador        <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2015      Frederic France        <frederic.france@free.fr>
    - * Copyright (C) 2015      Marcos García          <marcosgdf@gmail.com>
    - * Copyright (C) 2015      Jean-François Ferry    <jfefe@aternatik.fr>
    - * Copyright (C) 2016	   Ferran Marcet		  <fmarcet@2byte.es>
    +/* Copyright (C) 2001-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2013       Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2015-2018  Frédéric France         <frederic.france@netlogic.fr>
    + * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
    + * Copyright (C) 2016       Ferran Marcet           <fmarcet@2byte.es>
      *
      * 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
    @@ -214,7 +214,6 @@ if (empty($reshook))
     	$uploaddir = $conf->commande->dir_output;
     	$trigger_name='ORDER_SENTBYMAIL';
     	include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
    -
     }
     
     
    @@ -487,7 +486,7 @@ if ($resql)
     		print $langs->trans('DateInvoice');
     		print '</td>';
     		print '<td>';
    -		print $form->select_date('', '', '', '', '', '', 1, 1);
    +		print $form->selectDate('', '', '', '', '', '', 1, 1);
     		print '</td>';
     		print '</tr>';
     		print '<tr>';
    @@ -1163,5 +1162,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/note.php b/htdocs/commande/note.php
    index 6cff3bfb3bc..bf02c9b993c 100644
    --- a/htdocs/commande/note.php
    +++ b/htdocs/commande/note.php
    @@ -142,5 +142,6 @@ if ($id > 0 || ! empty($ref))
     }
     
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/orderstoinvoice.php b/htdocs/commande/orderstoinvoice.php
    index 03d379270b1..a8da25e07f9 100644
    --- a/htdocs/commande/orderstoinvoice.php
    +++ b/htdocs/commande/orderstoinvoice.php
    @@ -1,12 +1,13 @@
     <?php
    -/* Copyright (C) 2001-2005 Rodolphe Quiedeville   	<rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2013 Laurent Destailleur   	<eldy@users.sourceforge.net>
    - * Copyright (C) 2005      Marc Barilley / Ocebo  	<marc@ocebo.com>
    - * Copyright (C) 2005-2012 Regis Houssin          	<regis.houssin@capnetworks.com>
    - * Copyright (C) 2012	   Andreu Bisquerra Gaya  	<jove@bisquerra.com>
    - * Copyright (C) 2012	   David Rodriguez Martinez <davidrm146@gmail.com>
    - * Copyright (C) 2012-2018 Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2015	   Ferran Marcet			<fmarcet@2byte.es>
    +/* Copyright (C) 2001-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2013  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Andreu Bisquerra Gaya   <jove@bisquerra.com>
    + * Copyright (C) 2012       David Rodriguez Martinez <davidrm146@gmail.com>
    + * Copyright (C) 2012-2018  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2015       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -117,7 +118,6 @@ if (($action == 'create' || $action == 'add') && !$error)
     
     		$originid=$orders_id[0];
     		$_GET['originid']=$orders_id[0];
    -
     	}
     	if (isset($_POST['orders_to_invoice']))
     	{
    @@ -127,7 +127,6 @@ if (($action == 'create' || $action == 'add') && !$error)
     
     		$originid=$orders_id[0];
     		$_POST['originid']=$orders_id[0];
    -
     	}
     
     	$projectid		= GETPOST('projectid','int')?GETPOST('projectid','int'):0;
    @@ -442,7 +441,7 @@ if ($action == 'create' && !$error)
     
     	// Date invoice
     	print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td>';
    -	$html->select_date('','','','','',"add",1,1);
    +	print $html->selectDate('', '', '', '', '', "add", 1, 1);
     	print '</td></tr>';
     	// Payment term
     	print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
    @@ -530,8 +529,6 @@ if ($action == 'create' && !$error)
     
     	print '</td></tr>';
     	print "</table>\n";
    -
    -
     }
     
     // Mode liste
    @@ -596,8 +593,8 @@ if (($action != 'create' && $action != 'add') || ($action == 'create' && $error)
     		$num = $db->num_rows($resql);
     		print load_fiche_titre($title);
     		$i = 0;
    -		$period=$html->select_date($date_start,'date_start',0,0,1,'',1,0,1).' - '.$html->select_date($date_end,'date_end',0,0,1,'',1,0,1);
    -		$periodely=$html->select_date($date_starty,'date_start_dely',0,0,1,'',1,0,1).' - '.$html->select_date($date_endy,'date_end_dely',0,0,1,'',1,0,1);
    +		$period=$html->selectDate($date_start,'date_start',0,0,1,'',1,0).' - '.$html->selectDate($date_end,'date_end',0,0,1,'',1,0);
    +		$periodely=$html->selectDate($date_starty,'date_start_dely',0,0,1,'',1,0).' - '.$html->selectDate($date_endy,'date_end_dely',0,0,1,'',1,0);
     
     		if (! empty($socid))
     		{
    @@ -654,7 +651,7 @@ if (($action != 'create' && $action != 'add') || ($action == 'create' && $error)
     		print '</form>';
     
     		print '<form name="orders2invoice" action="orderstoinvoice.php" method="GET">';
    -		
    +
     		$generic_commande = new Commande($db);
     
     		while ($i < $num)
    @@ -736,8 +733,8 @@ if (($action != 'create' && $action != 'add') || ($action == 'create' && $error)
     	{
     		dol_print_error($db);
     	}
    -
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php
    index 8f259808357..d85b30792be 100644
    --- a/htdocs/commande/stats/index.php
    +++ b/htdocs/commande/stats/index.php
    @@ -302,6 +302,7 @@ print '</form>';
     print '<br><br>';
     
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -346,6 +347,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    @@ -369,7 +371,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/annuel.php b/htdocs/compta/bank/annuel.php
    index a786cf5ca28..47f31eac308 100644
    --- a/htdocs/compta/bank/annuel.php
    +++ b/htdocs/compta/bank/annuel.php
    @@ -24,7 +24,7 @@
      *		\brief       Page to report input-output of a bank account
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
    @@ -339,7 +339,6 @@ else
     				$i++;
     			}
     			$db->free($resql);
    -
     		}
     		else
     		{
    @@ -494,5 +493,6 @@ else
     
     print "\n</div><br>\n";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php
    index ec41a28327f..31eaa9e8f6d 100644
    --- a/htdocs/compta/bank/bankentries_list.php
    +++ b/htdocs/compta/bank/bankentries_list.php
    @@ -8,6 +8,7 @@
      * Copyright (C) 2016       Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2017       Alexandre Spangaro   <aspangaro@zendsi.com>
      * Copyright (C) 2018       Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -29,7 +30,7 @@
      *	\brief      List of bank transactions
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
    @@ -203,12 +204,12 @@ if (empty($reshook))
     }
     
     // Conciliation
    -if (GETPOST('confirm_reconcile') && $user->rights->banque->consolidate)
    +if ((GETPOST('confirm_savestatement','alpha') || GETPOST('confirm_reconcile','alpha')) && $user->rights->banque->consolidate)
     {
         $error=0;
     
         // Definition, nettoyage parametres
    -    $num_releve=trim(GETPOST("num_releve"));
    +    $num_releve=trim(GETPOST("num_releve","alpha"));
     
         if ($num_releve)
         {
    @@ -221,7 +222,7 @@ if (GETPOST('confirm_reconcile') && $user->rights->banque->consolidate)
                     {
                         $result=$bankline->fetch($row);
                         $bankline->num_releve=$num_releve; //$_POST["num_releve"];
    -                    $result=$bankline->update_conciliation($user, GETPOST("cat"));
    +                    $result=$bankline->update_conciliation($user, GETPOST("cat"), GETPOST('confirm_reconcile','alpha')?1:0);	// If we confirm_reconcile, we set flag 'rappro' to 1.
                         if ($result < 0)
                         {
                             setEventMessages($bankline->error, $bankline->errors, 'errors');
    @@ -247,7 +248,21 @@ if (GETPOST('confirm_reconcile') && $user->rights->banque->consolidate)
     
         if (! $error)
         {
    -        header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);	// To avoid to submit twice and allow back
    +    	$param='action=reconcile&contextpage=banktransactionlist&id='.$id.'&search_account='.$id;
    +		$param.='&search_conciliated='.urlencode($search_conciliated);
    +		if ($page) $param.='&page='.urlencode($page);
    +		if ($offset) $param.='&offset='.urlencode($offset);
    +		if ($search_thirdparty) $param.='&search_thirdparty='.urlencode($search_thirdparty);
    +		if ($search_num_releve) $param.='&search_num_releve='.urlencode($search_num_releve);
    +		if ($search_start_dt) $param.='&search_start_dt='.urlencode($search_start_dt);
    +		if ($search_end_dt) $param.='&search_end_dt='.urlencode($search_end_dt);
    +		if ($search_start_dv) $param.='&search_start_dv='.urlencode($search_start_dv);
    +		if ($search_end_dv) $param.='&search_end_dv='.urlencode($search_end_dv);
    +		if ($search_type) $param.='&search_type='.urlencode($search_type);
    +		if ($search_debit) $param.='&search_debit='.urlencode($search_debit);
    +		if ($search_credit) $param.='&search_credit='.urlencode($search_credit);
    +		$param.='&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder);
    +		header('Location: '.$_SERVER["PHP_SELF"].'?'.$param);	// To avoid to submit twice and allow the back button
             exit;
         }
     }
    @@ -301,7 +316,7 @@ if (GETPOST('save') && ! $cancel && $user->rights->banque->modifier)
         	$error++;
         }*/
     
    -    if (! $error)
    +    if (! $error && ! empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT))
         {
         	$objecttmp = new Account($db);
         	$objecttmp->fetch($bankaccountid);
    @@ -428,7 +443,7 @@ if ($id > 0 || ! empty($ref))
                 if ($user->rights->banque->consolidate) {
                 	$newparam = $param;
                 	$newparam = preg_replace('/search_conciliated=\d+/i','',$newparam);
    -            	$buttonreconcile = '<a class="butActionNew" style="margin-bottom: 5px !important; margin-top: 5px !important" href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?action=reconcile&search_conciliated=0'.$newparam.'">'.$langs->trans("Conciliate").'</a>';
    +            	$buttonreconcile = '<a class="butActionNew" style="margin-bottom: 5px !important; margin-top: 5px !important" href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?action=reconcile&sortfield=b.datev,b.dateo,b.rowid&amp;sortorder=asc,asc,asc&search_conciliated=0'.$newparam.'">'.$langs->trans("Conciliate").'</a>';
                 } else {
                 	$buttonreconcile = '<a class="butActionNewRefused" style="margin-bottom: 5px !important; margin-top: 5px !important" title="'.$langs->trans("NotEnoughPermissions").'" href="#">'.$langs->trans("Conciliate").'</a>';
                 }
    @@ -578,6 +593,8 @@ if ($resql)
     	        print Form::selectarray('cat', $options, GETPOST('cat'), 1);
     	    }
     	    print '<br>'.$langs->trans("ThenCheckLinesAndConciliate").' ';
    +	    print '<input class="button" name="confirm_savestatement" type="submit" value="'.$langs->trans("SaveStatementOnly").'">';
    +	    print ' '.$langs->trans("or").' ';
     	    print '<input class="button" name="confirm_reconcile" type="submit" value="'.$langs->trans("Conciliate").'">';
     	    print ' '.$langs->trans("or").' ';
     	    print '<input type="submit" name="cancel" class="button" value="'.$langs->trans("Cancel").'">';
    @@ -629,7 +646,7 @@ if ($resql)
     	}
     
     	// Form to add a transaction with no invoice
    -	if ($user->rights->banque->modifier && $action == 'addline')
    +	if ($user->rights->banque->modifier && $action == 'addline' && ! empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT))
     	{
     		print load_fiche_titre($langs->trans("AddBankRecordLong"),'','');
     
    @@ -666,7 +683,7 @@ if ($resql)
     		}
     		print '</td>';
     		print '<td class="nowrap">';
    -		$form->select_date(empty($dateop)?-1:$dateop,'op',0,0,0,'transaction');
    +		print $form->selectDate(empty($dateop)?-1:$dateop, 'op', 0, 0, 0, 'transaction');
     		print '</td>';
     		print '<td>&nbsp;</td>';
     		print '<td class="nowrap">';
    @@ -728,7 +745,7 @@ if ($resql)
     	{
     		if (empty($conf->global->BANK_DISABLE_DIRECT_INPUT))
     		{
    -			if (! empty($conf->global->BANK_USE_VARIOUS_PAYMENT))	// If direct entries is done using miscellaneous payments
    +			if (empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT))	// If direct entries is done using miscellaneous payments
     			{
     				if ($user->rights->banque->modifier) {
     					$newcardbutton = '<a class="butActionNew" href="'.DOL_URL_ROOT.'/compta/bank/various_payment/card.php?action=create&accountid='.$search_account.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.urlencode($search_account)).'"><span class="valignmiddle">'.$langs->trans("AddBankRecord").'</span>';
    @@ -787,17 +804,17 @@ if ($resql)
     	$moreforfilter.='<div class="divsearchfield">';
     	$moreforfilter .= $langs->trans('DateOperationShort').' : ';
     	$moreforfilter .= '<div class="nowrap'.($conf->browser->layout=='phone'?' centpercent':'').' inline-block">'.$langs->trans('From') . ' ';
    -	$moreforfilter .= $form->select_date($search_dt_start, 'search_start_dt', 0, 0, 1, "search_form", 1, 0, 1).'</div>';
    +	$moreforfilter .= $form->selectDate($search_dt_start, 'search_start_dt', 0, 0, 1, "search_form", 1, 0).'</div>';
     	//$moreforfilter .= ' - ';
    -	$moreforfilter .= '<div class="nowrap'.($conf->browser->layout=='phone'?' centpercent':'').' inline-block">'.$langs->trans('to') . ' ' . $form->select_date($search_dt_end, 'search_end_dt', 0, 0, 1, "search_form", 1, 0, 1).'</div>';
    +	$moreforfilter .= '<div class="nowrap'.($conf->browser->layout=='phone'?' centpercent':'').' inline-block">'.$langs->trans('to') . ' ' . $form->selectDate($search_dt_end, 'search_end_dt', 0, 0, 1, "search_form", 1, 0).'</div>';
     	$moreforfilter .= '</div>';
     
     	$moreforfilter.='<div class="divsearchfield">';
     	$moreforfilter .= $langs->trans('DateValueShort').' : ';
     	$moreforfilter .= '<div class="nowrap'.($conf->browser->layout=='phone'?' centpercent':'').' inline-block">'.$langs->trans('From') . ' ';
    -	$moreforfilter .= $form->select_date($search_dv_start, 'search_start_dv', 0, 0, 1, "search_form", 1, 0, 1).'</div>';
    +	$moreforfilter .= $form->selectDate($search_dv_start, 'search_start_dv', 0, 0, 1, "search_form", 1, 0).'</div>';
     	//$moreforfilter .= ' - ';
    -	$moreforfilter .= '<div class="nowrap'.($conf->browser->layout=='phone'?' centpercent':'').' inline-block">'.$langs->trans('to') . ' ' . $form->select_date($search_dv_end, 'search_end_dv', 0, 0, 1, "search_form", 1, 0, 1).'</div>';
    +	$moreforfilter .= '<div class="nowrap'.($conf->browser->layout=='phone'?' centpercent':'').' inline-block">'.$langs->trans('to') . ' ' . $form->selectDate($search_dv_end, 'search_end_dv', 0, 0, 1, "search_form", 1, 0).'</div>';
     	$moreforfilter .= '</div>';
     
     	if (! empty($conf->categorie->enabled))
    @@ -1400,16 +1417,17 @@ if ($resql)
     
         	if (! empty($arrayfields['b.num_releve']['checked']))
         	{
    -            print '<td class="nowrap" align="center">';
    +            print '<td class="nowraponall" align="center">';
             	// Transaction reconciliated or edit link
             	if ($bankaccount->canBeConciliated() > 0)
             	{
    -            	if ($objp->conciliated)  // If line not conciliated and account can be conciliated
    +        		if ($objp->num_releve)
                 	{
    -            	    print '<a href="releve.php?num='.$objp->num_releve.'&amp;account='.$objp->bankid.'">'.$objp->num_releve.'</a>';
    +            	    print '<a href="releve.php?num='.$objp->num_releve.'&account='.$objp->bankid.'&save_lastsearch_values=1">'.$objp->num_releve.'</a>';
                 	}
    -            	else if ($action == 'reconcile')
    +            	if (! $objp->conciliated && $action == 'reconcile')
                 	{
    +            		if ($objp->num_releve) print '&nbsp;';
                 	    print '<input class="flat" name="rowid['.$objp->rowid.']" type="checkbox" value="'.$objp->rowid.'" size="1"'.(! empty($_POST['rowid'][$objp->rowid])?' checked':'').'>';
                 	}
             	}
    @@ -1434,7 +1452,7 @@ if ($resql)
         	// Transaction reconciliated or edit link
         	if ($objp->conciliated && $bankaccount->canBeConciliated() > 0)  // If line not conciliated and account can be conciliated
         	{
    -    	    print '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$objp->rowid.'&amp;account='.$objp->bankid.'&amp;page='.$page.'">';
    +    	    print '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?save_lastsearch_values=1&amp;rowid='.$objp->rowid.'&amp;account='.$objp->bankid.'&amp;page='.$page.'">';
         	    print img_edit();
         	    print '</a>';
         	}
    @@ -1442,13 +1460,13 @@ if ($resql)
         	{
         	    if ($user->rights->banque->modifier || $user->rights->banque->consolidate)
         	    {
    -    	        print '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$objp->rowid.'&amp;account='.$objp->bankid.'&amp;page='.$page.'">';
    +    	        print '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?save_lastsearch_values=1&amp;rowid='.$objp->rowid.'&amp;account='.$objp->bankid.'&amp;page='.$page.'">';
         	        print img_edit();
         	        print '</a>';
         	    }
         	    else
         	    {
    -    	        print '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$objp->rowid.'&amp;account='.$objp->bankid.'&amp;page='.$page.'">';
    +    	        print '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?save_lastsearch_values=1&amp;rowid='.$objp->rowid.'&amp;account='.$objp->bankid.'&amp;page='.$page.'">';
         	        print img_view();
         	        print '</a>';
         	    }
    @@ -1529,6 +1547,6 @@ if ($_POST["action"] == "search" && ! $num)
     	print '<div class="opacitymedium">'.$langs->trans("NoRecordFound").'</div>';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/bilan.php b/htdocs/compta/bank/bilan.php
    index 5e5194d55c8..99856a2dea2 100644
    --- a/htdocs/compta/bank/bilan.php
    +++ b/htdocs/compta/bank/bilan.php
    @@ -22,7 +22,7 @@
      *		\brief      Page de bilan
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
     // Load translation files required by the page
    @@ -92,5 +92,6 @@ print "<tr class=\"oddeven\"><td>".$langs->trans("BankBalance")."</td><td align=
     
     print "</table>";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/budget.php b/htdocs/compta/bank/budget.php
    index 280cd9bdbc0..ccec902bf7c 100644
    --- a/htdocs/compta/bank/budget.php
    +++ b/htdocs/compta/bank/budget.php
    @@ -24,7 +24,7 @@
      *		\brief      Page de budget
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
     // Load translation files required by the page
    @@ -96,5 +96,6 @@ else
     }
     print "</table>";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php
    index db497733863..6d2fa406ea7 100644
    --- a/htdocs/compta/bank/card.php
    +++ b/htdocs/compta/bank/card.php
    @@ -6,6 +6,7 @@
      * Copyright (C) 2014-2017	Alexandre Spangaro		<aspangaro@zendsi.com>
      * Copyright (C) 2015		Jean-François Ferry		<jfefe@aternatik.fr>
      * Copyright (C) 2016		Marcos García			<marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -27,7 +28,7 @@
      *		\brief      Page to create/view a bank account
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
    @@ -59,7 +60,8 @@ $extrafields = new ExtraFields($db);
     // fetch optionals attributes and labels
     $extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
     
    -
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$hookmanager->initHooks(array('bankcard','globalcard'));
     
     /*
      * Actions
    @@ -284,7 +286,7 @@ if ($action == 'confirm_delete' && $_POST["confirm"] == "yes" && $user->rights->
     $form = new Form($db);
     $formbank = new FormBank($db);
     $formcompany = new FormCompany($db);
    -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db);
    +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db);
     
     $countrynotdefined=$langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')';
     
    @@ -431,7 +433,7 @@ if ($action == 'create')
     
     	print '<tr><td>'.$langs->trans("Date").'</td>';
     	print '<td>';
    -	$form->select_date('', 're', 0, 0, 0, 'formsoc');
    +	print $form->selectDate('', 're', 0, 0, 0, 'formsoc');
     	print '</td></tr>';
     
     	print '<tr><td>'.$langs->trans("BalanceMinimalAllowed").'</td>';
    @@ -574,7 +576,6 @@ else
     		if ($action == 'delete')
     		{
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id,$langs->trans("DeleteAccount"),$langs->trans("ConfirmDeleteAccount"),"confirm_delete");
    -
     		}
     
     		// Print form confirm
    @@ -764,7 +765,6 @@ else
     		}
     
     		print '</div>';
    -
     	}
     
     	/* ************************************************************************** */
    @@ -1031,8 +1031,8 @@ else
     
     		print '</form>';
     	}
    -
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/categ.php b/htdocs/compta/bank/categ.php
    index be029fcb2f5..f76f73183b3 100644
    --- a/htdocs/compta/bank/categ.php
    +++ b/htdocs/compta/bank/categ.php
    @@ -26,7 +26,7 @@
      *      \brief      Page ajout de categories bancaires
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/bankcateg.class.php';
     
    @@ -34,6 +34,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/bankcateg.class.php';
     $langs->loadLangs(array('banks', 'categories'));
     
     $action=GETPOST('action','aZ09');
    +$optioncss  = GETPOST('optioncss','aZ');												// Option for the css output (always '' except when 'print')
     
     if (!$user->rights->banque->configurer)
       accessforbidden();
    @@ -80,16 +81,36 @@ if ($categid) {
     llxHeader();
     
     
    -print load_fiche_titre($langs->trans("RubriquesTransactions"), '', 'title_bank.png');
    +print load_fiche_titre($langs->trans("RubriquesTransactions"));
     
     print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    +if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    +print '<input type="hidden" name="action" value="list">';
    +/*print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
    +print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
    +print '<input type="hidden" name="page" value="'.$page.'">';
    +print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
    +*/
     
    +print '<div class="div-table-responsive">';		// You can use div-table-responsive-no-min if you dont need reserved height for your table
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("Ref").'</td><td colspan="2">'.$langs->trans("Label").'</td>';
     print "</tr>\n";
     
    +// Line to add category
    +if ($action != 'edit')
    +{
    +
    +	print '<tr class="oddeven">';
    +	print '<td>&nbsp;</td><td><input name="label" type="text" size="45"></td>';
    +	print '<td align="center"><input type="submit" name="add" class="button" value="'.$langs->trans("Add").'"></td>';
    +	print '</tr>';
    +}
    +
    +
     $sql = "SELECT rowid, label";
     $sql.= " FROM ".MAIN_DB_PREFIX."bank_categ";
     $sql.= " WHERE entity = ".$conf->entity;
    @@ -129,19 +150,11 @@ if ($result)
     	$db->free($result);
     }
     
    +print '</table>';
    +print '</div>';
     
    -/*
    - * Line to add category
    - */
    -if ($action != 'edit')
    -{
    -
    -	print '<tr class="oddeven">';
    -	print '<td>&nbsp;</td><td><input name="label" type="text" size="45"></td>';
    -	print '<td align="center"><input type="submit" name="add" class="button" value="'.$langs->trans("Add").'"></td>';
    -	print '</tr>';
    -}
    -
    -print '</table></form>';
    +print '</form>';
     
    +// End of page
     llxFooter();
    +$db->close();
    diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php
    index 6ba712f9ff2..5a8d1326e48 100644
    --- a/htdocs/compta/bank/class/account.class.php
    +++ b/htdocs/compta/bank/class/account.class.php
    @@ -36,8 +36,19 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Account extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element = 'bank_account';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element = 'bank_account';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'account';
     
     	/**
    @@ -48,7 +59,7 @@ class Account extends CommonObject
     	public $rowid;
     
     	/**
    -	 * Label
    +	 * Account Label
     	 * @var string
     	 */
     	public $label;
    @@ -160,6 +171,10 @@ class Account extends CommonObject
     	 * @var string
     	 */
     	public $account_number;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_accountancy_journal;
     
     	/**
    @@ -286,6 +301,7 @@ class Account extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Add a link between bank line record and its source
     	 *
    @@ -298,6 +314,7 @@ class Account extends CommonObject
     	 */
     	function add_url_line($line_id, $url_id, $url, $label, $type)
     	{
    +        // phpcs:enable
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
     		$sql.= "fk_bank";
     		$sql.= ", url_id";
    @@ -325,6 +342,7 @@ class Account extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 		TODO Move this into AccountLine
     	 *      Return array with links from llx_bank_url
    @@ -332,10 +350,11 @@ class Account extends CommonObject
     	 *      @param  int         $fk_bank    To search using bank transaction id
     	 *      @param  int         $url_id     To search using link to
     	 *      @param  string      $type       To search using type
    -	 *      @return array|-1                Array of links array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> ) or -1 on error
    +	 *      @return array|int               Array of links array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> ) or -1 on error
     	 */
     	function get_url($fk_bank='', $url_id='', $type='')
     	{
    +        // phpcs:enable
     		$lines = array();
     
     		// Check parameters
    @@ -774,14 +793,16 @@ class Account extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *    	Update BBAN (RIB) account fields
    +	 *  Update BBAN (RIB) account fields
     	 *
    -	 *    	@param	User	$user       Object user making update
    -	 *		@return	int					<0 if KO, >0 if OK
    +	 *  @param	User	$user       Object user making update
    +	 *	@return	int					<0 if KO, >0 if OK
     	 */
     	function update_bban(User $user = null)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		// Clean parameters
    @@ -943,8 +964,10 @@ class Account extends CommonObject
     	 * Existing categories are left untouch.
     	 *
     	 * @param int[]|int $categories Category or categories IDs
    +     * @return void
     	 */
    -	public function setCategories($categories) {
    +    public function setCategories($categories)
    +    {
     		// Handle single category
     		if (! is_array($categories)) {
     			$categories = array($categories);
    @@ -1058,6 +1081,7 @@ class Account extends CommonObject
     		return $this->LibStatut($this->clos,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return label of given object status
     	 *
    @@ -1067,6 +1091,7 @@ class Account extends CommonObject
     	 */
     	function LibStatut($statut, $mode = 0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('banks');
     
    @@ -1095,6 +1120,7 @@ class Account extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Renvoi si un compte peut etre supprimer ou non (sans mouvements)
     	 *
    @@ -1102,6 +1128,7 @@ class Account extends CommonObject
     	 */
     	function can_be_deleted()
     	{
    +        // phpcs:enable
     		$can_be_deleted=false;
     
     		$sql = "SELECT COUNT(rowid) as nb";
    @@ -1162,6 +1189,7 @@ class Account extends CommonObject
     		return price2num($solde, 'MU');
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -1171,6 +1199,7 @@ class Account extends CommonObject
     	 */
     	function load_board(User $user, $filteraccountid = 0)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
    @@ -1217,6 +1246,7 @@ class Account extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb de tableau de bord
     	 *		@param		int			$filteraccountid	To get info for a particular account id
    @@ -1224,6 +1254,7 @@ class Account extends CommonObject
     	 */
     	function load_state_board($filteraccountid = 0)
     	{
    +        // phpcs:enable
     		global $user;
     
     		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
    @@ -1300,13 +1331,19 @@ class Account extends CommonObject
     	 */
     	function getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0)
     	{
    -		global $conf, $langs;
    +		global $conf, $langs, $user;
     
     		$result='';
     		$label = '<u>' . $langs->trans("ShowAccount") . '</u>';
     		$label .= '<br><b>' . $langs->trans('BankAccount') . ':</b> ' . $this->label;
     		$label .= '<br><b>' . $langs->trans('AccountNumber') . ':</b> ' . $this->number;
     		$label .= '<br><b>' . $langs->trans("AccountCurrency") . ':</b> ' . $this->currency_code;
    +
    +		if (empty($user->rights->banque->lire) || !empty($user->socid))
    +		{
    +			$option = 'nolink';
    +		}
    +
     		if (! empty($conf->accounting->enabled))
     		{
     			include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
    @@ -1337,6 +1374,11 @@ class Account extends CommonObject
     		$linkstart = '<a href="'.$url.$linkclose;
     		$linkend = '</a>';
     
    +                if ($option == 'nolink') {
    +                    $linkstart = '';
    +                    $linkend = '';
    +                }
    +
     		$result .= $linkstart;
     		if ($withpicto) $result.=img_object(($notooltip?'':$label), $this->picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
     		if ($withpicto != 2) $result.= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
    @@ -1491,7 +1533,6 @@ class Account extends CommonObject
     	 */
     	function info($id)
     	{
    -
     	}
     
     	/**
    @@ -1536,7 +1577,6 @@ class Account extends CommonObject
     
     		//Get the order the properties are shown
     		return $fieldarray;
    -
     	}
     
     	/**
    @@ -1610,7 +1650,6 @@ class Account extends CommonObject
     		$this->owner_address   = 'Owner address';
     		$this->country_id      = 1;
     	}
    -
     }
     
     
    @@ -1619,36 +1658,93 @@ class Account extends CommonObject
      */
     class AccountLine extends CommonObject
     {
    -	var $error;
    -	var $db;
    -	var $element='bank';
    -	var $table_element='bank';
    -	var $picto = 'generic';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -	var $id;
    -	var $ref;
    -	var $datec;
    -	var $dateo;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='bank';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='bank';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'generic';
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +    /**
    +     * @var string Ref
    +     */
    +    public $ref;
    +
    +	public $datec;
    +	public $dateo;
     
     	/**
     	 * Value date
     	 */
    -	var $datev;
    -	var $amount;
    -	var $label;
    -	var $note;
    -	var $fk_user_author;
    -	var $fk_user_rappro;
    -	var $fk_type;
    -	var $rappro;        // Is it conciliated
    -	var $num_releve;    // If conciliated, what is bank statement
    -	var $num_chq;       // Num of cheque
    -	var $bank_chq;      // Bank of cheque
    -	var $fk_bordereau;  // Id of cheque receipt
    +	public $datev;
    +	public $amount;
     
    -	var $fk_account;            // Id of bank account
    -	var $bank_account_label;    // Label of bank account
    +    /**
    +     * @var string bank transaction lines label
    +     */
    +    public $label;
     
    +    public $note;
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_rappro;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_type;
    +
    +	public $rappro;        // Is it conciliated
    +	public $num_releve;    // If conciliated, what is bank statement
    +	public $num_chq;       // Num of cheque
    +	public $bank_chq;      // Bank of cheque
    +
    +	/**
    +     * @var int ID of cheque receipt
    +     */
    +	public $fk_bordereau;
    +
    +	/**
    +     * @var int ID of bank account
    +     */
    +	public $fk_account;
    +
    +	public $bank_account_label;    // Label of bank account
    +
    +    /**
    +	 * Issuer
    +	 * @var Societe
    +	 */
     	public $emetteur;
     
     	/**
    @@ -1834,6 +1930,7 @@ class AccountLine extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Delete bank line records
     	 *
    @@ -1842,6 +1939,7 @@ class AccountLine extends CommonObject
     	 */
     	function delete_urls(User $user = null)
     	{
    +        // phpcs:enable
     		$nbko=0;
     
     		if ($this->rappro)
    @@ -1904,15 +2002,18 @@ class AccountLine extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *		Update conciliation field
    +	 *	Update conciliation field
     	 *
    -	 *		@param	User	$user		Objet user making update
    -	 *		@param 	int		$cat		Category id
    -	 *		@return	int					<0 if KO, >0 if OK
    +	 *	@param	User	$user			Objet user making update
    +	 *	@param 	int		$cat			Category id
    +	 *	@param	int		$conciliated	1=Set transaction to conciliated, 0=Keep transaction non conciliated
    +	 *	@return	int						<0 if KO, >0 if OK
     	 */
    -	function update_conciliation(User $user, $cat)
    +	function update_conciliation(User $user, $cat, $conciliated=1)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$this->db->begin();
    @@ -1928,9 +2029,9 @@ class AccountLine extends CommonObject
     		}
     
     		$sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
    -		$sql.= " rappro = 1";
    +		$sql.= " rappro = ".$conciliated;
     		$sql.= ", num_releve = '".$this->db->escape($this->num_releve)."'";
    -		$sql.= ", fk_user_rappro = ".$user->id;
    +		if ($conciliated) $sql.= ", fk_user_rappro = ".$user->id;
     		$sql.= " WHERE rowid = ".$this->id;
     
     		dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
    @@ -1966,6 +2067,7 @@ class AccountLine extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Increase/decrease value date of a rowid
     	 *
    @@ -1975,6 +2077,7 @@ class AccountLine extends CommonObject
     	 */
     	function datev_change($rowid,$sign=1)
     	{
    +        // phpcs:enable
     		$sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".$rowid;
     		$resql = $this->db->query($sql);
     		if ($resql)
    @@ -2004,6 +2107,7 @@ class AccountLine extends CommonObject
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Increase value date of a rowid
     	 *
    @@ -2012,9 +2116,11 @@ class AccountLine extends CommonObject
     	 */
     	function datev_next($id)
     	{
    +        // phpcs:enable
     		return $this->datev_change($id,1);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Decrease value date of a rowid
     	 *
    @@ -2023,10 +2129,12 @@ class AccountLine extends CommonObject
     	 */
     	function datev_previous($id)
     	{
    +        // phpcs:enable
     		return $this->datev_change($id,-1);
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Increase/decrease operation date of a rowid
     	 *
    @@ -2036,6 +2144,7 @@ class AccountLine extends CommonObject
     	 */
     	function dateo_change($rowid,$sign=1)
     	{
    +        // phpcs:enable
     		$sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".$rowid;
     		$resql = $this->db->query($sql);
     		if ($resql)
    @@ -2065,6 +2174,7 @@ class AccountLine extends CommonObject
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Increase operation date of a rowid
     	 *
    @@ -2073,9 +2183,11 @@ class AccountLine extends CommonObject
     	 */
     	function dateo_next($id)
     	{
    +        // phpcs:enable
     		return $this->dateo_change($id,1);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Decrease operation date of a rowid
     	 *
    @@ -2084,6 +2196,7 @@ class AccountLine extends CommonObject
     	 */
     	function dateo_previous($id)
     	{
    +        // phpcs:enable
     		return $this->dateo_change($id,-1);
     	}
     
    @@ -2190,6 +2303,7 @@ class AccountLine extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -2199,6 +2313,7 @@ class AccountLine extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		//$langs->load('companies');
     		/*
    @@ -2268,6 +2383,4 @@ class AccountLine extends CommonObject
     		}
     		return 0;
     	}
    -
     }
    -
    diff --git a/htdocs/compta/bank/class/bankcateg.class.php b/htdocs/compta/bank/class/bankcateg.class.php
    index 176fdb626a5..cc291c6be64 100644
    --- a/htdocs/compta/bank/class/bankcateg.class.php
    +++ b/htdocs/compta/bank/class/bankcateg.class.php
    @@ -30,11 +30,21 @@ class BankCateg // extends CommonObject
     {
     	//public $element='bank_categ';			//!< Id that identify managed objects
     	//public $table_element='bank_categ';	//!< Name of table without prefix where object is stored
    -    public $picto='generic';
    -    
    -	public $id;
    -	public $label;
    -   
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto='generic';
    +
    +	/**
    +     * @var int ID
    +     */
    +    public $id;
    +
    +	/**
    +     * @var string bank categories label
    +     */
    +    public $label;
    +
     
     	/**
     	 * Constructor
    @@ -205,7 +215,7 @@ class BankCateg // extends CommonObject
     		{
     		    $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
         		$sql.= " WHERE fk_categorie = ".$this->id;
    -    		
    +
         		$resql = $this->db->query($sql);
         		if (!$resql)
         		{
    @@ -213,13 +223,13 @@ class BankCateg // extends CommonObject
         		    $this->errors[] = "Error ".$this->db->lasterror();
         		}
     		}
    -		
    +
     		// Delete link between tag and bank lines
     		if (! $error)
     		{
     		    $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class";
     		    $sql.= " WHERE fk_categ = ".$this->id;
    -		
    +
     		    $resql = $this->db->query($sql);
     		    if (!$resql)
     		    {
    @@ -227,21 +237,21 @@ class BankCateg // extends CommonObject
     		        $this->errors[] = "Error ".$this->db->lasterror();
     		    }
     		}
    -		
    +
     		// Delete bank categ
     		if (! $error)
     		{
         		$sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_categ";
         		$sql .= " WHERE rowid=".$this->id;
    -    
    +
         		$resql = $this->db->query($sql);
    -    		if (!$resql) 
    +    		if (!$resql)
         		{
         			$error++;
         			$this->errors[] = "Error ".$this->db->lasterror();
         		}
     		}
    -		
    +
         	// Commit or rollback
     		if ($error) {
     			foreach ($this->errors as $errmsg) {
    @@ -339,5 +349,4 @@ class BankCateg // extends CommonObject
     		$this->id = 0;
     		$this->label = '';
     	}
    -
     }
    diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php
    index fe56ea99504..47edacb2410 100644
    --- a/htdocs/compta/bank/class/paymentvarious.class.php
    +++ b/htdocs/compta/bank/class/paymentvarious.class.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2017       Alexandre Spangaro  <aspangaro@zendsi.com>
    +/* Copyright (C) 2017       Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,25 +31,65 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class PaymentVarious extends CommonObject
     {
    -	public $element='variouspayment';		//!< Id that identify managed objects
    -	public $table_element='payment_various';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='variouspayment';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='payment_various';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'bill';
     
    -	var $id;
    -	var $ref;
    -	var $tms;
    -	var $datep;
    -	var $datev;
    -	var $sens;
    -	var $amount;
    -	var $type_payment;
    -	var $num_payment;
    -	var $label;
    -	var $accountancy_code;
    -	var $fk_project;
    -	var $fk_bank;
    -	var $fk_user_author;
    -	var $fk_user_modif;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +	 * @var string Ref
    +	 */
    +	public $ref;
    +
    +	public $tms;
    +	public $datep;
    +	public $datev;
    +	public $sens;
    +	public $amount;
    +	public $type_payment;
    +	public $num_payment;
    +
    +	/**
    +     * @var string various payments label
    +     */
    +    public $label;
    +
    +	public $accountancy_code;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_project;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_modif;
     
     
     	/**
    @@ -61,14 +102,13 @@ class PaymentVarious extends CommonObject
     		$this->db = $db;
     		$this->element = 'payment_various';
     		$this->table_element = 'payment_various';
    -		return 1;
     	}
     
     	/**
     	 * Update database
     	 *
     	 * @param   User	$user        	User that modify
    -	 * @param	int		$notrigger	    0=no, 1=yes (no update trigger)
    +	 * @param   int		$notrigger      0=no, 1=yes (no update trigger)
     	 * @return  int         			<0 if KO, >0 if OK
     	 */
     	function update($user=null, $notrigger=0)
    @@ -81,9 +121,9 @@ class PaymentVarious extends CommonObject
     		$this->amount=trim($this->amount);
     		$this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_author=trim($this->fk_user_author);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_author = (int) $this->fk_user_author;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     
     		$this->db->begin();
     
    @@ -281,9 +321,9 @@ class PaymentVarious extends CommonObject
     		$this->amount=price2num(trim($this->amount));
     		$this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_author=trim($this->fk_user_author);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_author = (int) $this->fk_user_author;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
     		if (! $this->label)
    @@ -363,13 +403,14 @@ class PaymentVarious extends CommonObject
     
     					// Insert payment into llx_bank
     					// Add link 'payment_various' in bank_url between payment and bank transaction
    -					if ($this->sens == '0') $sign='-';
    +					$sign=1;
    +					if ($this->sens == '0') $sign=-1;
     
     					$bank_line_id = $acc->addline(
     						$this->datep,
     						$this->type_payment,
     						$this->label,
    -						$sign.abs($this->amount),
    +						$sign * abs($this->amount),
     						$this->num_payment,
     						'',
     						$user
    @@ -411,7 +452,6 @@ class PaymentVarious extends CommonObject
     				$result=$this->call_trigger('PAYMENT_VARIOUS_CREATE',$user);
     				if ($result < 0) $error++;
     				// End call triggers
    -
     			}
     			else $error++;
     
    @@ -434,6 +474,7 @@ class PaymentVarious extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update link between payment various and line generate into llx_bank
     	 *
    @@ -442,6 +483,7 @@ class PaymentVarious extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = 'UPDATE '.MAIN_DB_PREFIX.'payment_various SET fk_bank = '.$id_bank;
     		$sql.= ' WHERE rowid = '.$this->id;
     		$result = $this->db->query($sql);
    @@ -468,6 +510,7 @@ class PaymentVarious extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -477,39 +520,40 @@ class PaymentVarious extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
    -			if ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    -			if ($statut==2 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    +			elseif ($statut==2 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==2 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==2 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
    -			if ($statut==1 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    -			if ($statut==2 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==1 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    +			elseif ($statut==2 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
     		}
     	}
     
    @@ -517,24 +561,71 @@ class PaymentVarious extends CommonObject
     	/**
     	 *	Send name clicable (with possibly the picto)
     	 *
    -	 *	@param  int		$withpicto		0=No picto, 1=Include picto into link, 2=Only picto
    -	 *	@param  string	$option			link option
    -	 *	@return string					Chaine with URL
    +	 *	@param  int		$withpicto					0=No picto, 1=Include picto into link, 2=Only picto
    +	 *	@param  string	$option						link option
    +	 *  @param  int     $save_lastsearch_value	 	-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
    +     *  @param	int  	$notooltip		 			1=Disable tooltip
    +	 *	@return string								String with URL
     	 */
    -	function getNomUrl($withpicto=0,$option='')
    +	function getNomUrl($withpicto=0, $option='', $save_lastsearch_value=-1, $notooltip=0)
     	{
    +		global $db, $conf, $langs, $hookmanager;
     		global $langs;
     
    -		$result='';
    -		$label=$langs->trans("ShowVariousPayment").': '.$this->ref;
    +		if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
     
    -		$linkstart = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
    +		$result='';
    +
    +		$label='<u>'.$langs->trans("ShowVariousPayment").'</u>';
    +		$label.= '<br>';
    +		$label.= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
    +
    +		$url = DOL_URL_ROOT.'/compta/bank/various_payment/card.php?id='.$this->id;
    +
    +		if ($option != 'nolink')
    +		{
    +			// Add param to save lastsearch_values or not
    +			$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
    +			if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
    +			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
    +		}
    +
    +		$linkclose='';
    +		if (empty($notooltip))
    +		{
    +			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
    +			{
    +				$label=$langs->trans("ShowMyObject");
    +				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
    +			}
    +			$linkclose.=' title="'.dol_escape_htmltag($label, 1).'"';
    +			$linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
    +
    +			/*
    +			 $hookmanager->initHooks(array('myobjectdao'));
    +			 $parameters=array('id'=>$this->id);
    +			 $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +			 if ($reshook > 0) $linkclose = $hookmanager->resPrint;
    +			 */
    +		}
    +		else $linkclose = ($morecss?' class="'.$morecss.'"':'');
    +
    +		$linkstart = '<a href="'.$url.'"';
    +		$linkstart.=$linkclose.'>';
     		$linkend='</a>';
     
     		$result .= $linkstart;
     		if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
    -		if ($withpicto != 2) $result.= ($maxlen?dol_trunc($this->ref,$maxlen):$this->ref);
    +		if ($withpicto != 2) $result.= $this->ref;
     		$result .= $linkend;
    +		//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
    +
    +		global $action;
    +		$hookmanager->initHooks(array('variouspayment'));
    +		$parameters=array('id'=>$this->id, 'getnomurl'=>$result);
    +		$reshook=$hookmanager->executeHooks('getNomUrl',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +		if ($reshook > 0) $result = $hookmanager->resPrint;
    +		else $result .= $hookmanager->resPrint;
     
     		return $result;
     	}
    @@ -582,5 +673,4 @@ class PaymentVarious extends CommonObject
     			dol_print_error($this->db);
     		}
     	}
    -
     }
    diff --git a/htdocs/compta/bank/document.php b/htdocs/compta/bank/document.php
    index 33e74dc3691..f908b68b35c 100644
    --- a/htdocs/compta/bank/document.php
    +++ b/htdocs/compta/bank/document.php
    @@ -24,7 +24,7 @@
      * 	\ingroup    banque
      * 	\brief      Page de gestion des documents attaches a un compte bancaire
      */
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT . "/core/lib/bank.lib.php";
     require_once DOL_DOCUMENT_ROOT . "/core/lib/files.lib.php";
     require_once DOL_DOCUMENT_ROOT . "/core/lib/images.lib.php";
    @@ -105,7 +105,7 @@ if ($id > 0 || !empty($ref)) {
             dol_fiche_head($head, 'document', $langs->trans("FinancialAccount"), -1, 'account');
     
     
    -        // Construit liste des fichiers
    +        // Build file list
             $filearray = dol_dir_list($upload_dir, "files", 0, '', '\.meta$',
                     $sortfield,
                     (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
    @@ -147,7 +147,6 @@ else {
         exit;
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/graph.php b/htdocs/compta/bank/graph.php
    index b829002a990..517c616ec28 100644
    --- a/htdocs/compta/bank/graph.php
    +++ b/htdocs/compta/bank/graph.php
    @@ -23,7 +23,7 @@
      *	\brief      Page graph des transactions bancaires
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
    @@ -265,7 +265,7 @@ else
     		unset($amounts);
     	}
     
    -	// Tableau 2
    +	// Graph Balance for the year
     
     	if ($mode == 'standard')
     	{
    @@ -384,7 +384,7 @@ else
     		$px2->SetTitle($title);
     		$px2->SetWidth($WIDTH);
     		$px2->SetHeight($HEIGHT);
    -		$px2->SetType(array('lines','lines','lines'));
    +		$px2->SetType(array('linesnopoint','linesnopoint','linesnopoint'));
     		$px2->setBgColor('onglet');
     		$px2->setBgColorGrid(array(255,255,255));
     		$px2->SetHideXGrid(true);
    @@ -403,7 +403,7 @@ else
     		unset($amounts);
     	}
     
    -	// Tableau 3 - All time line
    +	// Graph 3 - Balance for all time line
     
     	if ($mode == 'showalltime')
     	{
    @@ -500,7 +500,7 @@ else
     		$px3->SetTitle($title);
     		$px3->SetWidth($WIDTH);
     		$px3->SetHeight($HEIGHT);
    -		$px3->SetType(array('lines','lines','lines'));
    +		$px3->SetType(array('linesnopoint','linesnopoint','linesnopoint'));
     		$px3->setBgColor('onglet');
     		$px3->setBgColorGrid(array(255,255,255));
     		$px3->SetPrecisionY(0);
    @@ -864,7 +864,6 @@ if ($mode == 'showalltime')
     
     print '</table>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/info.php b/htdocs/compta/bank/info.php
    index ab43b9374aa..7eaeb515aa9 100644
    --- a/htdocs/compta/bank/info.php
    +++ b/htdocs/compta/bank/info.php
    @@ -21,7 +21,7 @@
      *     \brief      Onglet info d'une ecriture bancaire
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
    @@ -71,5 +71,6 @@ print '</td></tr></table>';
     
     print '</div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/ligne.php b/htdocs/compta/bank/ligne.php
    index e006f78c6e7..1587c5c10e8 100644
    --- a/htdocs/compta/bank/ligne.php
    +++ b/htdocs/compta/bank/ligne.php
    @@ -7,6 +7,7 @@
      * Copyright (C) 2015-2017 Alexandre Spangaro	<aspangaro@zendsi.com>
      * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
      * Copyright (C) 2016      Marcos García        <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -28,12 +29,12 @@
      *	\brief      Page to edit a bank transaction record
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array('banks', 'categories', 'compta', 'bills'));
    +$langs->loadLangs(array('banks', 'categories', 'compta', 'bills', 'other'));
     if (! empty($conf->adherent->enabled)) $langs->load("members");
     if (! empty($conf->don->enabled)) $langs->load("donations");
     if (! empty($conf->loan->enabled)) $langs->load("loan");
    @@ -98,8 +99,10 @@ if ($action == 'confirm_delete_categ' && $confirm == "yes" && $user->rights->ban
         	{
             	dol_print_error($db);
         	}
    -	} else {
    -		setEventMessage('Missing ids','errors');
    +	}
    +	else
    +	{
    +		setEventMessages($langs->trans("MissingIds"), null, 'errors');
     	}
     }
     
    @@ -448,7 +451,6 @@ if ($result)
                     $receipt=new RemiseCheque($db);
                     $receipt->fetch($objp->receiptid);
                     print ' &nbsp; &nbsp; '.$langs->trans("CheckReceipt").': '.$receipt->getNomUrl(2);
    -
                 }
                 print '</td>';
             }
    @@ -495,7 +497,7 @@ if ($result)
             if ($user->rights->banque->modifier || $user->rights->banque->consolidate)
             {
                 print '<td>';
    -            print $form->select_date($db->jdate($objp->do),'dateo','','','','update',1,0,1,$objp->rappro);
    +            print $form->selectDate($db->jdate($objp->do), 'dateo', '', '', '', 'update', 1, 0, $objp->rappro);
                 if (! $objp->rappro)
                 {
                     print ' &nbsp; ';
    @@ -519,7 +521,7 @@ if ($result)
             if ($user->rights->banque->modifier || $user->rights->banque->consolidate)
             {
                 print '<td>';
    -            print $form->select_date($db->jdate($objp->dv),'datev','','','','update',1,0,1,$objp->rappro);
    +            print $form->selectDate($db->jdate($objp->dv), 'datev', '', '', '', 'update', 1, 0, $objp->rappro);
                 if (! $objp->rappro)
                 {
                     print ' &nbsp; ';
    @@ -679,13 +681,12 @@ if ($result)
     
     			print '</form>';
             }
    -
         }
     
         $db->free($result);
     }
     else dol_print_error($db);
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php
    index 3a67a3d5309..79c26adfa47 100644
    --- a/htdocs/compta/bank/list.php
    +++ b/htdocs/compta/bank/list.php
    @@ -1,6 +1,4 @@
     <?php
    -use Stripe\BankAccount;
    -
     /* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    @@ -27,7 +25,7 @@ use Stripe\BankAccount;
      *       \brief      Home page of bank module
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
    @@ -428,7 +426,7 @@ foreach ($accounts as $key=>$type)
         // Ref
         if (! empty($arrayfields['b.ref']['checked']))
         {
    -        print '<td>'.$obj->getNomUrl(1).'</td>';
    +        print '<td class="nowrap">'.$obj->getNomUrl(1).'</td>';
     	    if (! $i) $totalarray['nbfield']++;
         }
     
    @@ -604,7 +602,6 @@ print "</div>";
     
     print "</form>";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php
    index 1d9d5526700..3f1bede8e20 100644
    --- a/htdocs/compta/bank/releve.php
    +++ b/htdocs/compta/bank/releve.php
    @@ -25,7 +25,7 @@
      *		\brief      Page to show a bank statement report
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
    @@ -813,7 +813,6 @@ else
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/transfer.php b/htdocs/compta/bank/transfer.php
    index 765001e75a5..38109b964b4 100644
    --- a/htdocs/compta/bank/transfer.php
    +++ b/htdocs/compta/bank/transfer.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2012	   Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -26,7 +27,7 @@
      *		\brief      Page de saisie d'un virement
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
    @@ -253,7 +254,7 @@ $form->select_comptes($account_to, 'account_to', 0, '', 1, '', empty($conf->mult
     print "</td>\n";
     
     print "<td>";
    -$form->select_date((! empty($dateo)?$dateo:''),'','','','','add');
    +print $form->selectDate((! empty($dateo)?$dateo:''), '', '', '', '', 'add');
     print "</td>\n";
     print '<td><input name="label" class="flat quatrevingtpercent" type="text" value="'.dol_escape_htmltag($label).'"></td>';
     print '<td><input name="amount" class="flat" type="text" size="6" value="'.dol_escape_htmltag($amount).'"></td>';
    @@ -265,5 +266,6 @@ print '<br><div class="center"><input type="submit" class="button" value="'.$lan
     
     print "</form>";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php
    index 0fb8880ce87..9bd00c81894 100644
    --- a/htdocs/compta/bank/treso.php
    +++ b/htdocs/compta/bank/treso.php
    @@ -49,6 +49,9 @@ $result=restrictedArea($user,'banque',$id,'bank_account&bank_account','','',$fie
     $vline=isset($_GET["vline"])?$_GET["vline"]:$_POST["vline"];
     $page=isset($_GET["page"])?$_GET["page"]:0;
     
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$hookmanager->initHooks(array('banktreso','globalcard'));
    +
     /*
      * View
      */
    @@ -130,6 +133,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     
     
     	// Remainder to pay in future
    +  $sqls = array();
     
     	// Customer invoices
     	$sql = "SELECT 'invoice' as family, f.rowid as objid, f.facnumber as ref, f.total_ttc, f.type, f.date_lim_reglement as dlr,";
    @@ -138,79 +142,55 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
     	$sql.= " WHERE f.entity = ".$conf->entity;
     	$sql.= " AND f.paye = 0 AND f.fk_statut = 1";	// Not paid
    -    $sql.= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice
    -    $sql.= " ORDER BY dlr ASC";
    +  $sql.= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice
    +  $sql.= " ORDER BY dlr ASC";
    +  $sqls[] = $sql;
     
     	// Supplier invoices
    -	$sql2= " SELECT 'invoice_supplier' as family, ff.rowid as objid, ff.ref as ref, ff.ref_supplier as ref_supplier, (-1*ff.total_ttc) as total_ttc, ff.type, ff.date_lim_reglement as dlr,";
    -	$sql2.= " s.rowid as socid, s.nom as name, s.fournisseur";
    -	$sql2.= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff";
    -	$sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid";
    -	$sql2.= " WHERE ff.entity = ".$conf->entity;
    -	$sql2.= " AND ff.paye = 0 AND fk_statut = 1";	// Not paid
    -    $sql2.= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice
    -    $sql2.= " ORDER BY dlr ASC";
    +	$sql = " SELECT 'invoice_supplier' as family, ff.rowid as objid, ff.ref as ref, ff.ref_supplier as ref_supplier, (-1*ff.total_ttc) as total_ttc, ff.type, ff.date_lim_reglement as dlr,";
    +	$sql.= " s.rowid as socid, s.nom as name, s.fournisseur";
    +	$sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff";
    +	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid";
    +	$sql.= " WHERE ff.entity = ".$conf->entity;
    +	$sql.= " AND ff.paye = 0 AND fk_statut = 1";	// Not paid
    +  $sql.= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice
    +  $sql.= " ORDER BY dlr ASC";
    +  $sqls[] = $sql;
     
     	// Social contributions
    -	$sql3= " SELECT 'social_contribution' as family, cs.rowid as objid, cs.libelle as ref, (-1*cs.amount) as total_ttc, ccs.libelle as type, cs.date_ech as dlr";
    -    $sql3.= ", cs.fk_account";
    -	$sql3.= " FROM ".MAIN_DB_PREFIX."chargesociales as cs";
    -	$sql3.= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id";
    -	$sql3.= " WHERE cs.entity = ".$conf->entity;
    -	$sql3.= " AND cs.paye = 0";	// Not paid
    -    $sql3.= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution
    -	$sql3.= " ORDER BY dlr ASC";
    +	$sql = " SELECT 'social_contribution' as family, cs.rowid as objid, cs.libelle as ref, (-1*cs.amount) as total_ttc, ccs.libelle as type, cs.date_ech as dlr";
    +  $sql.= ", cs.fk_account";
    +	$sql.= " FROM ".MAIN_DB_PREFIX."chargesociales as cs";
    +	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id";
    +	$sql.= " WHERE cs.entity = ".$conf->entity;
    +	$sql.= " AND cs.paye = 0";	// Not paid
    +  $sql.= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution
    +	$sql.= " ORDER BY dlr ASC";
    +  $sqls[] = $sql;
    +
    +  // others sql
    +  $parameters = array();
    +  $reshook = $hookmanager->executeHooks('addMoreSQL', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +  if(empty($reshook) and isset($hookmanager->resArray['sql'])){
    +    $sqls[] = $hookmanager->resArray['sql'];
    +  }
     
     	$error=0;
     	$tab_sqlobjOrder=array();
     	$tab_sqlobj=array();
     
    -	// List customer invoices
    -	$result = $db->query($sql);
    -	if ($result)
    -	{
    -		$num = $db->num_rows($result);
    -		for ($i = 0;$i < $num;$i++)
    -		{
    -			$sqlobj = $db->fetch_object($result);
    -			$tab_sqlobj[] = $sqlobj;
    -			$tab_sqlobjOrder[]= $db->jdate($sqlobj->dlr);
    -		}
    -		$db->free($result);
    -	}
    -	else $error++;
    -
    -	// List supplier invoices
    -	$result2=$db->query($sql2);
    -	if ($result2)
    -	{
    -		$num = $db->num_rows($result2);
    -		for ($i = 0;$i < $num;$i++)
    -		{
    -			$sqlobj = $db->fetch_object($result2);
    -			$tab_sqlobj[] = $sqlobj;
    -			$tab_sqlobjOrder[]= $db->jdate($sqlobj->dlr);
    -		}
    -		$db->free($result2);
    -	}
    -	else $error++;
    -
    -	// List social contributions
    -	$result3=$db->query($sql3);
    -	if ($result3)
    -	{
    -		$num = $db->num_rows($result3);
    -
    -		for ($i = 0;$i < $num;$i++)
    -		{
    -			$sqlobj = $db->fetch_object($result3);
    -			$tab_sqlobj[] = $sqlobj;
    -			$tab_sqlobjOrder[]= $db->jdate($sqlobj->dlr);
    -		}
    -		$db->free($result3);
    -	}
    -	else $error++;
    -
    +  foreach($sqls as $sql){
    +    $resql = $db->query($sql);
    +    if($resql){
    +      while($sqlobj = $db->fetch_object($resql)){
    +        $tab_sqlobj[] = $sqlobj;
    +        $tab_sqlobjOrder[]= $db->jdate($sqlobj->dlr);
    +      }
    +      $db->free($resql);
    +    }else{
    +      $error++;
    +    }
    +  }
     
     	// Sort array
     	if (! $error)
    @@ -228,7 +208,6 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     
     		$num = count($tab_sqlobj);
     
    -		//$num = $db->num_rows($result);
     		$i = 0;
     		while ($i < $num)
     		{
    @@ -236,7 +215,6 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     			$ref = '';
     			$refcomp = '';
     
    -			//$obj = $db->fetch_object($result);
     			$obj = array_shift($tab_sqlobj);
     
     			if ($obj->family == 'invoice_supplier')
    @@ -284,6 +262,14 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     				$paiement = -1*$socialcontribstatic->getSommePaiement();	// Payment already done
     			}
     
    +      $parameters = array('obj' => $obj);
    +      $reshook = $hookmanager->executeHooks('moreFamily', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +      if(empty($reshook)){
    +        $ref = isset($hookmanager->resArray['ref']) ? $hookmanager->resArray['ref'] : '';
    +        $refcomp = isset($hookmanager->resArray['refcomp']) ? $hookmanager->resArray['refcomp'] : '';
    +        $paiement = isset($hookmanager->resArray['paiement']) ? $hookmanager->resArray['paiement'] : 0;
    +      }
    +
     			$total_ttc = $obj->total_ttc;
     			if ($paiement) $total_ttc = $obj->total_ttc - $paiement;
     			$solde += $total_ttc;
    @@ -291,8 +277,6 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     			// We discard lines with a remainder to pay to 0
     			if (price2num($total_ttc) != 0)
     			{
    -
    -
         			// Show line
         			print '<tr class="oddeven">';
         			print '<td>';
    @@ -315,20 +299,28 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
     		dol_print_error($db);
     	}
     
    -	// Solde actuel
    +	// Other lines
    +	$parameters = array('solde' => $solde);
    +	$reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if(empty($reshook)){
    +		print $hookmanager->resPrint;
    +    $solde = isset($hookmanager->resArray['solde']) ? $hookmanager->resArray['solde'] : $solde;
    +	}
     
    +  // solde
     	print '<tr class="liste_total">';
     	print '<td align="left" colspan="5">'.$langs->trans("FutureBalance").' ('.$object->currency_code.')</td>';
     	print '<td align="right" class="nowrap">'.price($solde, 0, $langs, 0, 0, -1, $object->currency_code).'</td>';
     	print '</tr>';
     
     	print "</table>";
    -    print "</div>";
    +  print "</div>";
     }
     else
     {
     	print $langs->trans("ErrorBankAccountNotFound");
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php
    index 1b4d7579892..0f417777417 100644
    --- a/htdocs/compta/bank/various_payment/card.php
    +++ b/htdocs/compta/bank/various_payment/card.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2017       Alexandre Spangaro  <aspangaro@zendsi.com>
    +/* Copyright (C) 2017       Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -85,7 +86,7 @@ if (empty($reshook))
     	{
     		if ($action != 'addlink')
     		{
    -			$urltogo=$backtopage?$backtopage:dol_buildpath('/compta/bank/various_payment/index.php',1);
    +			$urltogo=$backtopage?$backtopage:dol_buildpath('/compta/bank/various_payment/list.php',1);
     			header("Location: ".$urltogo);
     			exit;
     		}
    @@ -154,7 +155,8 @@ if (empty($reshook))
     			if ($ret > 0)
     			{
     				$db->commit();
    -				header("Location: index.php");
    +				$urltogo=($backtopage ? $backtopage : DOL_URL_ROOT.'/compta/bank/various_payment/list.php');
    +				header("Location: ".$urltogo);
     				exit;
     			}
     			else
    @@ -189,7 +191,7 @@ if (empty($reshook))
     				if ($result >= 0)
     				{
     					$db->commit();
    -					header("Location: ".DOL_URL_ROOT.'/compta/bank/various_payment/index.php');
    +					header("Location: ".DOL_URL_ROOT.'/compta/bank/various_payment/list.php');
     					exit;
     				}
     				else
    @@ -220,7 +222,7 @@ if (empty($reshook))
     llxHeader("",$langs->trans("VariousPayment"));
     
     $form = new Form($db);
    -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db);
    +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db);
     if (! empty($conf->projet->enabled)) $formproject = new FormProjets($db);
     
     if ($id)
    @@ -255,13 +257,13 @@ if ($action == 'create')
     	// Date payment
     	print '<tr><td>';
     	print fieldLabel('DatePayment','datep',1).'</td><td>';
    -	print $form->select_date((empty($datep)?-1:$datep),"datep",'','','','add',1,1);
    +	print $form->selectDate((empty($datep)?-1:$datep),"datep",'','','','add',1,1);
     	print '</td></tr>';
     
     	// Date value for bank
     	print '<tr><td>';
     	print fieldLabel('DateValue','datev',0).'</td><td>';
    -	print $form->select_date((empty($datev)?-1:$datev),"datev",'','','','add',1,1);
    +	print $form->selectDate((empty($datev)?-1:$datev),"datev",'','','','add',1,1);
     	print '</td></tr>';
     
     	// Label
    @@ -375,7 +377,7 @@ if ($id)
     	{
     		$langs->load("projects");
     		$morehtmlref.=$langs->trans('Project') . ' ';
    -		if ($user->rights->tax->charges->creer)
    +		if ($user->rights->banque->modifier)
     		{
     			if ($action != 'classify')
     				$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
    @@ -394,16 +396,14 @@ if ($id)
     			if (! empty($object->fk_project)) {
     				$proj = new Project($db);
     				$proj->fetch($object->fk_project);
    -				$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
    -				$morehtmlref.=$proj->ref;
    -				$morehtmlref.='</a>';
    +				$morehtmlref.=$proj->getNomUrl(1);
     			} else {
     				$morehtmlref.='';
     			}
     		}
     	}
     	$morehtmlref.='</div>';
    -	$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/index.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
    +	$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/list.php?restore_lastsearch_values=1'.(! empty($socid)?'&socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
     
     	dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright);
     
    @@ -499,8 +499,6 @@ if ($id)
     	print "</div>";
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/various_payment/document.php b/htdocs/compta/bank/various_payment/document.php
    index cf596860a4b..c255ef19c16 100644
    --- a/htdocs/compta/bank/various_payment/document.php
    +++ b/htdocs/compta/bank/various_payment/document.php
    @@ -27,6 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("compta", "banks", "bills", "users", "accountancy"));
    @@ -81,15 +82,15 @@ if ($object->id)
     {
     	$head=various_payment_prepare_head($object);
     
    -	dol_fiche_head($head, 'documents',  $langs->trans("VariousPayment"), 0, 'payment');
    +	dol_fiche_head($head, 'documents',  $langs->trans("VariousPayment"), -1, 'payment');
     
     	$morehtmlref='<div class="refidno">';
     	// Project
     	if (! empty($conf->projet->enabled))
     	{
     		$langs->load("projects");
    -		$morehtmlref.=$langs->trans('Project') . ' ';
    -		if ($user->rights->tax->charges->creer)
    +		$morehtmlref.=$langs->trans('Project') . ' : ';
    +		if ($user->rights->banque->modifier && 0)
     		{
     			if ($action != 'classify')
     				$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
    @@ -108,23 +109,21 @@ if ($object->id)
     			if (! empty($object->fk_project)) {
     				$proj = new Project($db);
     				$proj->fetch($object->fk_project);
    -				$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
    -				$morehtmlref.=$proj->ref;
    -				$morehtmlref.='</a>';
    +				$morehtmlref.=$proj->getNomUrl(1);
     			} else {
     				$morehtmlref.='';
     			}
     		}
     	}
     	$morehtmlref.='</div>';
    -	$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/index.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
    +	$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/list.php?restore_lastsearch_values=1'.(! empty($socid)?'&socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
     
     	dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright);
     
     	print '<div class="fichecenter">';
     	print '<div class="underbanner clearboth"></div>';
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -154,6 +153,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/various_payment/info.php b/htdocs/compta/bank/various_payment/info.php
    index bb66871d6c0..d9f8709b155 100644
    --- a/htdocs/compta/bank/various_payment/info.php
    +++ b/htdocs/compta/bank/various_payment/info.php
    @@ -25,6 +25,7 @@ require '../../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("compta", "banks", "bills", "users", "accountancy"));
    @@ -49,15 +50,56 @@ $object->info($id);
     
     $head = various_payment_prepare_head($object);
     
    -dol_fiche_head($head, 'info', $langs->trans("VariousPayment"), 0, 'payment');
    +dol_fiche_head($head, 'info', $langs->trans("VariousPayment"), -1, 'payment');
     
     
    +$morehtmlref='<div class="refidno">';
    +// Project
    +if (! empty($conf->projet->enabled))
    +{
    +	$langs->load("projects");
    +	$morehtmlref.=$langs->trans('Project') . ' : ';
    +	if ($user->rights->banque->modifier && 0)
    +	{
    +		if ($action != 'classify')
    +			$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
    +			if ($action == 'classify') {
    +				//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
    +				$morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
    +				$morehtmlref.='<input type="hidden" name="action" value="classin">';
    +				$morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +				$morehtmlref.=$formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
    +				$morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    +				$morehtmlref.='</form>';
    +			} else {
    +				$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
    +			}
    +	} else {
    +		if (! empty($object->fk_project)) {
    +			$proj = new Project($db);
    +			$proj->fetch($object->fk_project);
    +			$morehtmlref.=$proj->getNomUrl(1);
    +		} else {
    +			$morehtmlref.='';
    +		}
    +	}
    +}
    +$morehtmlref.='</div>';
    +$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/list.php?restore_lastsearch_values=1'.(! empty($socid)?'&socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
    +
    +dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright);
    +
    +print '<div class="fichecenter">';
    +print '<div class="underbanner clearboth"></div>';
    +
    +print '<br>';
    +
     print '<table width="100%"><tr><td>';
     dol_print_object_info($object);
     print '</td></tr></table>';
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/bank/various_payment/index.php b/htdocs/compta/bank/various_payment/list.php
    similarity index 97%
    rename from htdocs/compta/bank/various_payment/index.php
    rename to htdocs/compta/bank/various_payment/list.php
    index 6535e0c0082..91608666601 100644
    --- a/htdocs/compta/bank/various_payment/index.php
    +++ b/htdocs/compta/bank/various_payment/list.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2017       Alexandre Spangaro  <aspangaro@zendsi.com>
    - * Copyright (C) 2017       Laurent Destailleur <eldy@users.sourceforge.net>
    +/* Copyright (C) 2017       Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2017       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -17,7 +18,7 @@
      */
     
     /**
    - *  \file       htdocs/compta/bank/various_payment/index.php
    + *  \file       htdocs/compta/bank/various_payment/list.php
      *  \ingroup    bank
      *  \brief      List of various payments
      */
    @@ -189,7 +190,7 @@ if ($result)
     	// Date
     	print '<td class="liste_titre center">';
     	print '<div class="nowrap">';
    -	print $form->select_date($search_date, 'date_doc', 0, 0, 1);
    +	print $form->selectDate($search_date, 'date_doc', 0, 0, 1);
     	print '</div>';
     	print '</td>';
     
    @@ -344,5 +345,6 @@ else
     }
     
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/charges/index.php b/htdocs/compta/charges/index.php
    index 4b3caf4f790..e367054fc40 100644
    --- a/htdocs/compta/charges/index.php
    +++ b/htdocs/compta/charges/index.php
    @@ -568,7 +568,6 @@ if (! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read))
     
     print '</form>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/compta-files.php b/htdocs/compta/compta-files.php
    new file mode 100644
    index 00000000000..d8f4885a3b2
    --- /dev/null
    +++ b/htdocs/compta/compta-files.php
    @@ -0,0 +1,316 @@
    +<?php
    +/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2017      Pierre-Henry Favre   <support@atm-consulting.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +/**
    + *  \file       htdocs/compta/compta-files.php
    + *  \ingroup    compta
    + *  \brief      Page to show portoflio and files of a thirdparty and download it
    + */
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
    +
    +restrictedArea($user,'banque');
    +
    +$langs->load("companies");
    +if (! empty($conf->facture->enabled)) $langs->load("bills");
    +$date_start =GETPOST('date_start','alpha');
    +$date_startDay= GETPOST('date_startday','int');
    +$date_startMonth= GETPOST('date_startmonth','int');
    +$date_startYear= GETPOST('date_startyear','int');
    +$date_start=($date_startDay)?dol_mktime(0,0,0,$date_startMonth,$date_startDay,$date_startYear):strtotime($date_start);
    +$date_stop =GETPOST('date_stop','alpha');
    +$date_stopDay= GETPOST('date_stopday','int');
    +$date_stopMonth= GETPOST('date_stopmonth','int');
    +$date_stopYear= GETPOST('date_stopyear','int');
    +//FIXME doldate
    +$date_stop=($date_stopDay)?dol_mktime(0,0,0,$date_stopMonth,$date_stopDay,$date_stopYear):strtotime($date_stop);
    +$action =GETPOST('action','alpha');
    +// Security check
    +//if ($user->societe_id) $id=$user->societe_id;
    +//$result = restrictedArea($user, 'societe', $id, '&societe');
    +//$object = new Societe($db);
    +//if ($id > 0) $object->fetch($id);
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$hookmanager->initHooks(array('comptafilescard','globalcard'));
    +// Load variable for pagination
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    +$sortfield = GETPOST('sortfield','alpha');
    +$sortorder = GETPOST('sortorder','alpha');
    +$page = GETPOST('page','int');
    +if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
    +$offset = $limit * $page;
    +$pageprev = $page - 1;
    +$pagenext = $page + 1;
    +if (! $sortfield) $sortfield="f.datef,f.rowid"; // Set here default search field
    +if (! $sortorder) $sortorder="DESC";
    +$arrayfields=array(
    +    'date'=>array('label'=>"Date", 'checked'=>1),
    +    //...
    +);
    +
    +
    +/*
    + * Actions
    + */
    +
    +//$parameters = array('socid' => $id);
    +//$reshook = $hookmanager->executeHooks('doActions', $parameters, $object); // Note that $object may have been modified by some hooks
    +//if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
    +
    +
    +
    +/*
    + * View
    + */
    +
    +$filesarray=array();
    +$result=false;
    +if(($action=="searchfiles"||$action=="dl" ) && $date_start && $date_stop){
    +    $wheretail=" '".$db->idate($date_start)."' AND '".$db->idate($date_stop)."'";
    +    $sql="SELECT rowid as id, facnumber as ref,paye as paid,total_ttc,fk_soc,datef as date, 'Invoice' as item FROM ".MAIN_DB_PREFIX."facture";
    +    $sql.=" WHERE datef between ".$wheretail;
    +    $sql.=" UNION ALL";
    +    $sql.=" SELECT rowid as id,ref, paye as paid, total_ttc, fk_soc,datef as date, 'InvoiceSupplier' as item  FROM ".MAIN_DB_PREFIX."facture_fourn";
    +    $sql.=" WHERE datef between  ".$wheretail;
    +    $sql.=" UNION ALL";
    +    $sql.=" SELECT rowid as id,ref,paid,total_ttc,fk_user_author as fk_soc,date_fin as date,'Expense' as item  FROM ".MAIN_DB_PREFIX."expensereport";
    +    $sql.=" WHERE date_fin between  ".$wheretail;
    +    $sql.=" UNION ALL";
    +    $sql.=" SELECT rowid as id,ref,paid,amount as total_ttc,CONCAT(firstname,' ',lastname) as fk_soc,datedon as date,'Donation' as item  FROM ".MAIN_DB_PREFIX."don";
    +    $sql.=" WHERE datedon between  ".$wheretail;
    +    $sql.=" UNION ALL";
    +    $sql.=" SELECT rowid as id,label as ref,1 as paid,amount as total_ttc,fk_user as fk_soc,datep as date,'Salary' as item  FROM ".MAIN_DB_PREFIX."payment_salary";
    +    $sql.=" WHERE datep between  ".$wheretail;
    +    $sql.=" UNION ALL";
    +    $sql.=" SELECT rowid as id,num_paiement as ref,1 as paid,amount as total_ttc,fk_charge as fk_soc,datep as date,'Charge' as item  FROM ".MAIN_DB_PREFIX."paiementcharge";
    +    $sql.=" WHERE datep between  ".$wheretail;
    +    $resd = $db->query($sql);
    +    $files=array();
    +    $link='';
    +
    +    if ($resd)
    +     {
    +         $numd = $db->num_rows($resd);
    +
    +        $upload_dir ='';
    +         $i=0;
    +         while($i<$numd)
    +         {
    +
    +
    +            $objd = $db->fetch_object($resd);
    +
    +            switch($objd->item){
    +            case "Invoice":
    +                $subdir=dol_sanitizeFileName($objd->ref);
    +                $upload_dir = $conf->facture->dir_output.'/'.$subdir;
    +                $link="../../document.php?modulepart=facture&file=".str_replace('/','%2F',$subdir).'%2F';
    +                break;
    +            case "InvoiceSupplier":
    +                $subdir=get_exdir($objd->id,2,0,0,$objd,'invoice_supplier').dol_sanitizeFileName($objd->ref);
    +                $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir;
    +                $link="../../document.php?modulepart=facture_fournisseur&file=".str_replace('/','%2F',$subdir).'%2F';
    +                break;
    +            case "Expense":
    +                $subdir=dol_sanitizeFileName($objd->ref);
    +                $upload_dir = $conf->expensereport->dir_output.'/'.$subdir;
    +                $link="../../document.php?modulepart=expensereport&file=".str_replace('/','%2F',$subdir).'%2F';
    +                break;
    +            case "Salary":
    +                $subdir=dol_sanitizeFileName($objd->id);
    +                $upload_dir = $conf->salaries->dir_output.'/'.$subdir;
    +                $link="../../document.php?modulepart=salaries&file=".str_replace('/','%2F',$subdir).'%2F';
    +                break;
    +            case "Donation":
    +                $subdir=get_exdir(null,2,0,1,$objd,'donation'). '/'. dol_sanitizeFileName($objd->id);
    +                $upload_dir = $conf->don->dir_output . '/' . $subdir;
    +                $link="../../document.php?modulepart=don&file=".str_replace('/','%2F',$subdir).'%2F';
    +                break;
    +            case "Charge":
    +                $subdir=dol_sanitizeFileName($objd->id);
    +                $upload_dir = $conf->tax->dir_output . '/' . $subdir;
    +                $link="../../document.php?modulepart=tax&file=".str_replace('/','%2F',$subdir).'%2F';
    +                break;
    +            default:
    +                break;
    +            }
    +
    +            if(!empty($upload_dir)){
    +                $result=true;
    +                $files=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1);
    +                foreach ($files as $key => $file){
    +                    $file['date']=$db->idate($objd->date);
    +                    $file['paid']=$objd->paid;
    +                    $file['amount']=$objd->total_ttc;
    +                    $file['ref']=$objd->ref;
    +                    $file['fk']=$objd->fk_soc;
    +                    $file['item']=$objd->item;
    +                    $file['link']=$link.$file['name'];
    +                    $out.= '<br><a href="'.$link.$file['name'].'">'.$file['name'].'</a>';
    +                    $filesarray[]=$file;
    +                }
    +                if(count($files)<1){
    +                    $nofile['date']=$db->idate($objd->date);
    +                    $nofile['paid']=$objd->paid;
    +                    $nofile['amount']=$objd->total_ttc;
    +                    $nofile['ref']=$objd->ref;
    +                    $nofile['fk']=$objd->fk_soc;
    +                    $nofile['item']=$objd->item;
    +                     $filesarray[]=$nofile;
    +                }
    +            }
    +          $i++;
    +         }
    +     }
    +     $db->free($resd);
    +}
    +/*
    + * cleanup of old ZIP
    + */
    +//FIXME
    +/*
    +*ZIP creation
    +*/
    +if($result & $action=="dl"){
    +        unset($zip);
    +   $log='date,type,ref,total,paid,filename,item_id'."\n";
    +        $zipname = ($date_start)."-".($date_stop).'_export.zip';
    +        $zip = new ZipArchive;
    +        $res = $zip->open($zipname, ZipArchive::OVERWRITE|ZipArchive::CREATE);
    +        if ($res){
    +          foreach ($filesarray as $key=> $file) {
    +                    if(file_exists($file["fullname"])) $zip->addFile($file["fullname"],$file["name"]);//
    +                    $log.=$file['date'].','.$file['item'].','.$file['ref'].','.$file['amount'].','.$file['paid'].','.$file["name"].','.$file['fk']."\n";
    +           }
    +          $zip->addFromString('log.csv', $log);
    +          $zip->close();
    +        ///Then download the zipped file.
    +          header('Content-Type: application/zip');
    +          header('Content-disposition: attachment; filename='.$zipname);
    +          header('Content-Length: ' . filesize($zipname));
    +          readfile($zipname);
    +                unlink($zipname);
    +          exit();
    +        }
    +}
    +// None
    +/*
    + *      View
    + */
    +$form = new Form($db);
    +$userstatic=new User($db);
    +$title=$langs->trans("ComptaFiles").' - '.$langs->trans("List");
    +//if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name.' - '.$langs->trans("Symmary");
    +$help_url='EN:Module_Accounting|FR:Module_Compatibilite'; //FIXME
    +llxHeader('',$title,$help_url);
    +print   '<div><form name="searchfiles" action="?action=searchfiles'.$tail.'" method="POST" >'."\n\t\t\t";
    +print    '<a>'.$langs->trans("dateStart").': '.$form->select_date($date_start,'date_start',0,0,0,"",1,1,1)."\n</a>";
    +print    '<a>'.$langs->trans("dateStop").': '.$form->select_date($date_stop,'date_stop',0,0,0,"",1,1,1)."\n</a>";
    +print   '<input class="butAction" type="submit" value="Go" /></form></div>'."\n\t\t";
    +if (!empty($date_start) && !empty($date_stop))echo dol_print_date($date_start)." - ".dol_print_date($date_stop);
    +print '<table class="noborder" width="100%">';
    +print '<tr class="liste_titre">';
    +//if (! empty($arrayfields['f.datef']['checked']))
    +print_liste_field_titre($arrayfields['date']['label'],$_SERVER["PHP_SELF"],"date","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    +print '<td>'.$langs->trans("Type").'</td>';
    +print '<td align="right">'.$langs->trans("Ref").'</td>';
    +print '<td>'.$langs->trans("File").'</td>';
    +print '<td>'.$langs->trans("Paid").'</td>';
    +print '<td align="right">'.$langs->trans("Debit").'</td>';
    +print '<td align="right">'.$langs->trans("Credit").'</td>';
    +print '<td align="right">'.$langs->trans("Balance").'</td>';
    +print '</tr>';
    +if ($result)
    +{
    +    $TData = dol_sort_array($filesarray, 'date', 'ASC');
    +        if(empty($TData)) {
    +                        print '<tr class="oddeven"><td colspan="7">'.$langs->trans("NoItem").'</td></tr>';
    +        } else {
    +                        // Sort array by date ASC to calucalte balance
    +
    +                        $totalDebit = 0;
    +                        $totalCredit = 0;
    +                        // Balance calculation
    +                        $balance = 0;
    +                        foreach($TData as &$data1) {
    +                                if($data1['item']!='Invoice'&& $data1['item']!='Donation' ){
    +                                     $data1['amount']=-$data1['amount'];
    +                                }
    +                                if ($data1['amount']>0){
    +                               }else{
    +                               }
    +                               $balance += $data1['amount'];
    +                                $data1['balance'] = $balance;
    +                        }
    +                // Display array
    +                foreach($TData as $data) {
    +                        $html_class = '';
    +                        //if (!empty($data['fk_facture'])) $html_class = 'facid-'.$data['fk_facture'];
    +                        //elseif (!empty($data['fk_paiement'])) $html_class = 'payid-'.$data['fk_paiement'];
    +                        print '<tr class="oddeven '.$html_class.'">';
    +                        print "<td align=\"center\">";
    +                        print dol_print_date($data['date'],'day');
    +                        print "</td>\n";
    +                        print '<td aling="left">'.$data['item'].'</td>';
    +                         print '<td aling="left">'.$data['ref'].'</td>';
    +                        print '<td> <a href='.$data['link'].">".$data['name']."</a></td>\n";
    +                        print '<td aling="left">'.$data['paid'].'</td>';
    +                        print '<td align="right">'.(($data['amount'] > 0) ? price(abs($data['amount'])) : '')."</td>\n";
    +                        $totalDebit += ($data['amount'] > 0) ? abs($data['amount']) : 0;
    +                        print '<td align="right">'.(($data['amount'] > 0) ? '' : price(abs($data['amount'])))."</td>\n";
    +                        $totalCredit += ($data['amount'] > 0) ? 0 : abs($data['amount']);
    +                        // Balance
    +                        print '<td align="right">'.price($data['balance'])."</td>\n";
    +                        print "</tr>\n";
    +                }
    +                print '<tr class="liste_total">';
    +                print '<td colspan="5">&nbsp;</td>';
    +                print '<td align="right">'.price($totalDebit).'</td>';
    +                print '<td align="right">'.price($totalCredit).'</td>';
    +                print '<td align="right">'.price(price2num($totalDebit - $totalCredit, 'MT')).'</td>';
    +                print '<td></td>';
    +                print "</tr>\n";
    +                }
    +        }
    +print "</table>";
    +print   '<form name="dl" action="?action=dl" method="POST" >'."\n\t\t\t";
    +
    +print   '<input type="hidden" name="date_start" value="'.dol_print_date($date_start,'dayxcard').'" />';
    +print   '<input type="hidden" name="date_stop"  value="'.dol_print_date($date_stop, 'dayxcard').'" />';
    +
    +//print   '<input type="hidden" name="date_stopDay"  value="'.dol_print_date($date_stop, '%d').'" />';
    +//print   '<input type="hidden" name="date_stopMonth"  value="'.dol_print_date($date_stop, '%m').'" />';
    +//print   '<input type="hidden" name="date_stopYear"  value="'.dol_print_date($date_stop, '%Y').'" />';
    +
    +//print   '<input type="hidden" name="date_startDay"  value="'.dol_print_date($date_start, '%d').'" />';
    +//print   '<input type="hidden" name="date_startMonth"  value="'.dol_print_date($date_start, '%m').'" />';
    +//print   '<input type="hidden" name="date_startYear"  value="'.dol_print_date($date_start, '%m').'" />';
    +
    +
    +print   '<input class="butAction" type="submit" value="Download" /></form>'."\n\t\t</th>\n\t\t<th>\n\t\t\t";
    +
    +
    +
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/compta/deplacement/card.php b/htdocs/compta/deplacement/card.php
    index 05d509e268d..383ff1c571a 100644
    --- a/htdocs/compta/deplacement/card.php
    +++ b/htdocs/compta/deplacement/card.php
    @@ -3,7 +3,8 @@
      * Copyright (C) 2004-2012	Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012	Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2012		Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2013       Florian Henry		  	<florian.henry@open-concept.pro>
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -20,8 +21,8 @@
      */
     
     /**
    - *  \file       	htdocs/compta/deplacement/card.php
    - *  \brief      	Page to show a trip card
    + *  \file       htdocs/compta/deplacement/card.php
    + *  \brief      Page to show a trip card
      */
     
     require '../../main.inc.php';
    @@ -263,7 +264,7 @@ if ($action == 'create')
     
         print "<tr>";
         print '<td class="fieldrequired">'.$langs->trans("Date").'</td><td>';
    -    print $form->select_date($datec?$datec:-1,'','','','','add',1,1,1);
    +    print $form->selectDate($datec?$datec:-1, '', '', '', '', 'add', 1, 1);
         print '</td></tr>';
     
         // Km
    @@ -360,7 +361,7 @@ else if ($id)
     
                 // Date
                 print '<tr><td class="fieldrequired">'.$langs->trans("Date").'</td><td>';
    -            print $form->select_date($object->date,'',0,0,0,'update',1,0,1);
    +            print $form->selectDate($object->date, '', 0, 0, 0, 'update', 1, 0);
                 print '</td></tr>';
     
                 // Km
    @@ -420,7 +421,6 @@ else if ($id)
                 if ($action == 'delete')
                 {
                     print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete");
    -
                 }
     
                 $soc = new Societe($db);
    @@ -577,7 +577,6 @@ else if ($id)
         }
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/deplacement/class/deplacement.class.php b/htdocs/compta/deplacement/class/deplacement.class.php
    index 05664080ed3..2476f65b09f 100644
    --- a/htdocs/compta/deplacement/class/deplacement.class.php
    +++ b/htdocs/compta/deplacement/class/deplacement.class.php
    @@ -31,23 +31,52 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Deplacement extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='deplacement';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='deplacement';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line = '';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element = '';
    -	public $ismultientitymanaged = 0;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     
    -	var $datec;         // Creation date
    -	var $dated;
    -	var $fk_user_author;
    -	var $fk_user;
    -	var $km;
    -	var $socid;
    -	var $statut;		// 0=draft, 1=validated
    -	var $extraparams=array();
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 0;
     
    -	var $statuts=array();
    -	var $statuts_short=array();
    +	public $datec;         // Creation date
    +	public $dated;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_author;
    +
    +	/**
    +	 * @var int User ID
    +	 */
    +	public $fk_user;
    +
    +	public $km;
    +	public $socid;
    +	public $statut;		// 0=draft, 1=validated
    +	public $extraparams=array();
    +
    +	public $statuts=array();
    +	public $statuts_short=array();
     
        /**
     	* Constructor
    @@ -146,7 +175,6 @@ class Deplacement extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -293,6 +321,7 @@ class Deplacement extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -302,35 +331,36 @@ class Deplacement extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts_short[$statut]);
     			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts_short[$statut]);
     			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
     			if ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
     			if ($statut==2 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
     			if ($statut==2 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
     			if ($statut==1 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    @@ -445,6 +475,4 @@ class Deplacement extends CommonObject
     			dol_print_error($this->db);
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/compta/deplacement/class/deplacementstats.class.php b/htdocs/compta/deplacement/class/deplacementstats.class.php
    index 75ac39a7cca..e490c90f1ed 100644
    --- a/htdocs/compta/deplacement/class/deplacementstats.class.php
    +++ b/htdocs/compta/deplacement/class/deplacementstats.class.php
    @@ -30,6 +30,9 @@ include_once DOL_DOCUMENT_ROOT . '/compta/deplacement/class/deplacement.class.ph
      */
     class DeplacementStats extends Stats
     {
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element;
     
         var $socid;
    diff --git a/htdocs/compta/deplacement/document.php b/htdocs/compta/deplacement/document.php
    index 59d92140c86..7ec837c81f2 100644
    --- a/htdocs/compta/deplacement/document.php
    +++ b/htdocs/compta/deplacement/document.php
    @@ -91,7 +91,7 @@ if ($object->id)
     	dol_fiche_head($head, 'documents',  $langs->trans("TripCard"), 0, 'trip');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -122,13 +122,12 @@ if ($object->id)
         $permission = $user->rights->deplacement->creer;
         $param = '&id=' . $object->id;
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/deplacement/index.php b/htdocs/compta/deplacement/index.php
    index a390023e280..84c0c718c70 100644
    --- a/htdocs/compta/deplacement/index.php
    +++ b/htdocs/compta/deplacement/index.php
    @@ -191,7 +191,6 @@ if ($result)
     
                 $i++;
             }
    -
         }
         else
         {
    @@ -204,7 +203,6 @@ else dol_print_error($db);
     
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/deplacement/info.php b/htdocs/compta/deplacement/info.php
    index 6a62484323f..f63b1765efb 100644
    --- a/htdocs/compta/deplacement/info.php
    +++ b/htdocs/compta/deplacement/info.php
    @@ -59,5 +59,6 @@ if ($id)
         print '</div>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/deplacement/list.php b/htdocs/compta/deplacement/list.php
    index bdbdad0a712..20d300d9da4 100644
    --- a/htdocs/compta/deplacement/list.php
    +++ b/htdocs/compta/deplacement/list.php
    @@ -212,6 +212,6 @@ else
         dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/deplacement/stats/index.php b/htdocs/compta/deplacement/stats/index.php
    index cf652948a6e..207e19fc265 100644
    --- a/htdocs/compta/deplacement/stats/index.php
    +++ b/htdocs/compta/deplacement/stats/index.php
    @@ -256,6 +256,7 @@ print '</table>';
     print '</form>';
     print '<br><br>';
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="border" width="100%">';
     print '<tr height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -288,7 +289,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    -
    +print '</div>';
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     
    @@ -312,7 +313,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/admin/facture_cust_extrafields.php b/htdocs/compta/facture/admin/facture_cust_extrafields.php
    index 2c676e399de..1fe26e82a54 100644
    --- a/htdocs/compta/facture/admin/facture_cust_extrafields.php
    +++ b/htdocs/compta/facture/admin/facture_cust_extrafields.php
    @@ -80,7 +80,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -93,7 +93,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -114,6 +114,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php b/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php
    index 18aa3c99442..23c0d79a33c 100644
    --- a/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php
    +++ b/htdocs/compta/facture/admin/facture_rec_cust_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,7 +94,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -115,6 +115,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/admin/facturedet_cust_extrafields.php b/htdocs/compta/facture/admin/facturedet_cust_extrafields.php
    index 2b90ae7fe05..0947f788719 100644
    --- a/htdocs/compta/facture/admin/facturedet_cust_extrafields.php
    +++ b/htdocs/compta/facture/admin/facturedet_cust_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,7 +94,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -113,6 +113,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/admin/facturedet_rec_cust_extrafields.php b/htdocs/compta/facture/admin/facturedet_rec_cust_extrafields.php
    index 97f8b78b195..46d9ed28335 100644
    --- a/htdocs/compta/facture/admin/facturedet_rec_cust_extrafields.php
    +++ b/htdocs/compta/facture/admin/facturedet_rec_cust_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,7 +94,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +	print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -113,6 +113,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
    index be65b2ec5ab..050f8786c3a 100644
    --- a/htdocs/compta/facture/card.php
    +++ b/htdocs/compta/facture/card.php
    @@ -1,19 +1,20 @@
     <?php
    -/* Copyright (C) 2002-2006 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
    - * Copyright (C) 2004-2016 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
    - * Copyright (C) 2005-2015 Regis Houssin         <regis.houssin@capnetworks.com>
    - * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
    - * Copyright (C) 2010-2015 Juanjo Menent         <jmenent@2byte.es>
    - * Copyright (C) 2012-2013 Christophe Battarel   <christophe.battarel@altairis.fr>
    - * Copyright (C) 2012-2013 Cédric Salvador       <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2012-2014 Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) 2013      Jean-Francois FERRY   <jfefe@aternatik.fr>
    - * Copyright (C) 2013-2014 Florian Henry         <florian.henry@open-concept.pro>
    - * Copyright (C) 2013      Cédric Salvador       <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2014-2018 Ferran Marcet	 	 <fmarcet@2byte.es>
    - * Copyright (C) 2015-2016 Marcos García         <marcosgdf@gmail.com>
    +/* Copyright (C) 2002-2006  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004       Eric Seigne             <eric.seigne@ryxeo.com>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2015  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2006       Andre Cianfarani        <acianfa@free.fr>
    + * Copyright (C) 2010-2015  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012-2013  Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2012-2013  Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2012-2014  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2013       Jean-Francois FERRY     <jfefe@aternatik.fr>
    + * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2014-2018  Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2015-2016  Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -743,7 +744,6 @@ if (empty($reshook))
     				{
     					$error++;
     				}
    -
     			}
     			if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT)
     			{
    @@ -764,7 +764,6 @@ if (empty($reshook))
     						break;
     					}
     				}
    -
     			}
     
     			if (empty($error))
    @@ -959,7 +958,7 @@ if (empty($reshook))
     
     							if($facture_source->type == Facture::TYPE_SITUATION)
     							{
    -							    $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id 
    +							    $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id
     							    $line->fk_prev_id  = $line->id; // Credit note line need to be linked to the situation invoice it is create from
     
     							    if(!empty($facture_source->tab_previous_situation_invoice))
    @@ -999,15 +998,11 @@ if (empty($reshook))
     							                $line->multicurrency_total_ht  = $line->multicurrency_total_ht  - $prevLine->multicurrency_total_ht;
     							                $line->multicurrency_total_tva = $line->multicurrency_total_tva - $prevLine->multicurrency_total_tva;
     							                $line->multicurrency_total_ttc = $line->multicurrency_total_ttc - $prevLine->multicurrency_total_ttc;
    -
    -
     							            }
     							        }
     
     							        // prorata
     							        $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent;
    -
    -
     							    }
     							}
     
    @@ -1039,7 +1034,6 @@ if (empty($reshook))
     
     						$object->update_price(1);
     					}
    -
     				}
     
     				if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0)
    @@ -1341,7 +1335,6 @@ if (empty($reshook))
     								$subprice_diff = $object->lines[0]->subprice - $diff / (1 + $object->lines[0]->tva_tx / 100);
     								$object->updateline($object->lines[0]->id, $object->lines[0]->desc, $subprice_diff, $object->lines[0]->qty, $object->lines[0]->remise_percent, $object->lines[0]->date_start, $object->lines[0]->date_end, $object->lines[0]->tva_tx, 0, 0, 'HT', $object->lines[0]->info_bits, $object->lines[0]->product_type, 0, 0, 0, $object->lines[0]->pa_ht, $object->lines[0]->label, 0, array(), 100);
     							}
    -
     						}
     						else
     						{
    @@ -1488,7 +1481,6 @@ if (empty($reshook))
     							setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
     							$error++;
     						}
    -
     					} else {
     						setEventMessages($object->error, $object->errors, 'errors');
     						$error++;
    @@ -1543,8 +1535,8 @@ if (empty($reshook))
     						$line->origin_id = $line->id;
     						$line->fk_prev_id = $line->id;
     						$line->fetch_optionals($line->id);
    -						$line->situation_percent =  $line->get_prev_progress($object->id); // get good progress including credit note 
    -						
    +						$line->situation_percent =  $line->get_prev_progress($object->id); // get good progress including credit note
    +
     						// Si fk_remise_except defini on vérifie si la réduction à déjà été appliquée
     						if ($line->fk_remise_except)
     						{
    @@ -1724,8 +1716,10 @@ if (empty($reshook))
     
     				if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
     					$idprod = $res->fk_product_child;
    -				} else {
    -					setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors');
    +				}
    +				else
    +				{
    +					setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
     					$error++;
     				}
     			}
    @@ -1967,7 +1961,7 @@ if (empty($reshook))
     			if ($tva_npr)
     				$info_bits |= 0x01;
     
    -			if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))) {
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
     				$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
     				setEventMessages($mesg, null, 'errors');
     			} else {
    @@ -2039,7 +2033,7 @@ if (empty($reshook))
     		}
     	}
     
    -	elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel','alpha'))
    +	elseif ($action == 'updateline' && $user->rights->facture->creer && ! GETPOST('cancel','alpha'))
     	{
     		if (! $object->fetch($id) > 0)	dol_print_error($db);
     		$object->fetch_thirdparty();
    @@ -2130,7 +2124,7 @@ if (empty($reshook))
     			$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
     
     			// Check price is not lower than minimum (check is done only for standard or replacement invoices)
    -			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))) {
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) ) && (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
     				setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
     				$error++;
     			}
    @@ -2262,7 +2256,7 @@ if (empty($reshook))
     		}
     	}
     
    -	else if ($action == 'updateligne' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) {
    +	else if ($action == 'updateline' && $user->rights->facture->creer && $_POST['cancel'] == $langs->trans('Cancel')) {
     		header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition
     		exit();
     	}
    @@ -2360,7 +2354,6 @@ if (empty($reshook))
                                     $line->situation_percent = $line->situation_percent - $maxPrevSituationPercent;
     
                                     if($line->update()<0) $errors++;
    -
     	                        }
     	                    }
     	                }
    @@ -2464,7 +2457,7 @@ if (empty($reshook))
     
     	        if($error)
     	        {
    -	            setEventMessage($langs->trans('ErrorsOnXLines',$error), 'errors');
    +	            setEventMessages($langs->trans('ErrorsOnXLines',$error), null, 'errors');
     	        }
     	    }
     	}
    @@ -2690,7 +2683,6 @@ if ($action == 'create')
     		print ajax_combobox('fac_replacement');
     		print ajax_combobox('fac_avoir');
     		print ajax_combobox('situations');
    -
     	}
     
     	if ($origin == 'contrat')
    @@ -2881,7 +2873,8 @@ if ($action == 'create')
     	// Standard invoice
     	print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
     	$tmp='<input type="radio" id="radio_standard" name="type" value="0"' . (GETPOST('type') == 0 ? ' checked' : '') . '> ';
    -	$desc = $form->textwithpicto($tmp.$langs->trans("InvoiceStandardAsk"), $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
    +	$tmp  = $tmp.'<label for="radio_standard" >'.$langs->trans("InvoiceStandardAsk").'</label>';
    +	$desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3);
     	print $desc;
     	print '</div></div>';
     
    @@ -2900,7 +2893,8 @@ if ($action == 'create')
         		});
         		</script>';
     
    -			$desc = $form->textwithpicto($tmp.$langs->trans("InvoiceDeposit"), $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
    +			$tmp  = $tmp.'<label for="radio_deposit" >'.$langs->trans("InvoiceDeposit").'</label>';
    +			$desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3);
     			print '<table class="nobordernopadding"><tr><td>';
     			print $desc;
     			print '</td>';
    @@ -2924,8 +2918,9 @@ if ($action == 'create')
     		{
     			// First situation invoice
     			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
    -			$tmp='<input type="radio" name="type" value="5"' . (GETPOST('type') == 5 ? ' checked' : '') . '> ';
    -			$desc = $form->textwithpicto($tmp.$langs->trans("InvoiceFirstSituationAsk"), $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3);
    +			$tmp='<input id="radio_situation invoice" type="radio" name="type" value="5"' . (GETPOST('type') == 5 ? ' checked' : '') . '> ';
    +			$tmp  = $tmp.'<label for="radio_situation invoice" >'.$langs->trans("InvoiceFirstSituationAsk").'</label>';
    +			$desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3);
     			print $desc;
     			print '</div></div>';
     
    @@ -2935,7 +2930,7 @@ if ($action == 'create')
     			$tmp='<input type="radio" name="type" value="5"' . (GETPOST('type') == 5 && GETPOST('originid') ? ' checked' : '');
     			if ($opt == ('<option value ="0" selected>' . $langs->trans('NoSituations') . '</option>') || (GETPOST('origin') && GETPOST('origin') != 'facture' && GETPOST('origin') != 'commande')) $tmp.=' disabled';
     			$tmp.= '> ';
    -			$text = $tmp.$langs->trans("InvoiceSituationAsk") . ' ';
    +			$text = '<label>'.$tmp.$langs->trans("InvoiceSituationAsk") . '</label> ';
     			$text .= '<select class="flat" id="situations" name="situations">';
     			$text .= $opt;
     			$text .= '</select>';
    @@ -2959,7 +2954,7 @@ if ($action == 'create')
         			});
         		});
         		</script>';
    -			$text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' ';
    +			$text = '<label>'.$tmp.$langs->trans("InvoiceReplacementAsk") . '</label>';
     			$text .= '<select class="flat" name="fac_replacement" id="fac_replacement"';
     			if (! $options)
     				$text .= ' disabled';
    @@ -2980,13 +2975,14 @@ if ($action == 'create')
     	{
     		print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
     		$tmp='<input type="radio" name="type" id="radio_replacement" value="0" disabled> ';
    -		$text = $tmp.$langs->trans("InvoiceReplacement") . ' ';
    +		$text = '<label>'.$tmp.$langs->trans("InvoiceReplacement") . '</label> ';
     		$text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') ';
     		$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3);
     		print $desc;
     		print '</div></div>';
     	}
    -
    +	
    +	
     	if (empty($origin))
     	{
     		if ($socid > 0)
    @@ -3013,7 +3009,7 @@ if ($action == 'create')
         				});
         			});
         			</script>';
    -				$text = $tmp.$langs->transnoentities("InvoiceAvoirAsk") . ' ';
    +				$text = '<label>'.$tmp.$langs->transnoentities("InvoiceAvoirAsk") . '</label> ';
     				// $text.='<input type="text" value="">';
     				$text .= '<select class="flat valignmiddle" name="fac_avoir" id="fac_avoir"';
     				if (! $optionsav)
    @@ -3042,7 +3038,7 @@ if ($action == 'create')
     			print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
     			if (empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE)) $tmp='<input type="radio" name="type" id="radio_creditnote" value="0" disabled> ';
     			else $tmp='<input type="radio" name="type" id="radio_creditnote" value="2" > ';
    -			$text = $tmp.$langs->trans("InvoiceAvoir") . ' ';
    +			$text = '<label>'.$tmp.$langs->trans("InvoiceAvoir") . '</label> ';
     			$text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') ';
     			$desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3);
     			print $desc;
    @@ -3053,7 +3049,7 @@ if ($action == 'create')
     	// Template invoice
     	print '<div class="tagtr listofinvoicetype"><div class="tagtd listofinvoicetype">';
     	$tmp='<input type="radio" name="type" id="radio_template" value="0" disabled> ';
    -	$text = $tmp.$langs->trans("RepeatableInvoice") . ' ';
    +	$text = '<label>'.$tmp.$langs->trans("RepeatableInvoice") . '</label> ';
     	//$text.= '('.$langs->trans("YouMustCreateStandardInvoiceFirst").') ';
     	$desc = $form->textwithpicto($text, $langs->transnoentities("YouMustCreateStandardInvoiceFirstDesc"), 1, 'help', '', 0, 3);
     	print $desc;
    @@ -3061,6 +3057,41 @@ if ($action == 'create')
     
     	print '</div>';
     
    +	
    +	if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) // Hidden conf
    +	{
    +    	// Add auto select default document model
    +    	$listtType=array(Facture::TYPE_STANDARD,Facture::TYPE_REPLACEMENT,Facture::TYPE_CREDIT_NOTE,Facture::TYPE_DEPOSIT,Facture::TYPE_SITUATION);
    +    	$jsListType='';
    +    	foreach ($listtType as $type)
    +    	{
    +    	    $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type;
    +    	    $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF;
    +    	    $jsListType.=(!empty($jsListType)?',':'').'"'.$type.'":"'.$curent.'"';
    +    	}
    +    	
    +    	print '<script type="text/javascript" language="javascript">
    +        		$(document).ready(function() {
    +                    var listType = {'.$jsListType.'};
    +        			$("[name=\'type\'").change(function() {
    +        				if($( this ).prop("checked"))
    +                        {
    +                            if(($( this ).val() in listType))
    +                            {
    +                                $("#model").val(listType[$( this ).val()]);
    +                            }
    +                            else
    +                            {
    +                                $("#model").val("'.$conf->global->FACTURE_ADDON_PDF.'");
    +                            }
    +                        }
    +        			});
    +        		});
    +        		</script>';
    +	}
    +	
    +	
    +	
     	print '</td></tr>';
     
     	if ($socid > 0)
    @@ -3080,7 +3111,7 @@ if ($action == 'create')
     
     	// Date invoice
     	print '<tr><td class="fieldrequired">' . $langs->trans('DateInvoice') . '</td><td colspan="2">';
    -	print $form->select_date($datefacture?$datefacture:$dateinvoice, '', '', '', '', "add", 1, 1, 1);
    +	print $form->selectDate($datefacture?$datefacture:$dateinvoice, '', '', '', '', "add", 1, 1);
     	print '</td></tr>';
     
     	// Date point of tax
    @@ -3088,7 +3119,7 @@ if ($action == 'create')
     	{
     		print '<tr><td class="fieldrequired">' . $langs->trans('DatePointOfTax') . '</td><td colspan="2">';
     		$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
    -		print $form->select_date($date_pointoftax?$date_pointoftax:-1, 'date_pointoftax', '', '', '', "add", 1, 1, 1);
    +		print $form->selectDate($date_pointoftax?$date_pointoftax:-1, 'date_pointoftax', '', '', '', "add", 1, 1);
     		print '</td></tr>';
     	}
     
    @@ -3151,7 +3182,14 @@ if ($action == 'create')
     	print '<td colspan="2">';
     	include_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php';
     	$liste = ModelePDFFactures::liste_modeles($db);
    -	print $form->selectarray('model', $liste, $conf->global->FACTURE_ADDON_PDF);
    +	if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)){ // Hidden conf
    +	   $paramkey='FACTURE_ADDON_PDF_'.$object->type;
    +	   $curent = !empty($conf->global->$paramkey)?$conf->global->$paramkey:$conf->global->FACTURE_ADDON_PDF;
    +	}
    +	else{
    +	   $curent = $conf->global->FACTURE_ADDON_PDF;
    +	}
    +	print $form->selectarray('model', $liste, $curent);
     	print "</td></tr>";
     
     	// Multicurrency
    @@ -3611,7 +3649,6 @@ else if ($id > 0 || ! empty($ref))
     	{
     		$payment_id = GETPOST('paiement_id');
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 'no', 1);
    -
     	}
     
     	// Confirmation de la suppression d'une ligne produit
    @@ -3631,13 +3668,11 @@ else if ($id > 0 || ! empty($ref))
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?facid=' . $object->id, $langs->trans('CloneInvoice'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
     	}
     
    -	if (! $formconfirm)
    -	{
    -		$parameters = array('lineid' => $lineid);
    -		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    @@ -4189,7 +4224,6 @@ else if ($id > 0 || ! empty($ref))
     	            print '<td align="right">' . price($next_invoice->total_ttc) . '</td>';
     	            print '<td align="right">' . $next_invoice->getLibStatut(3, $totalpaye) . '</td>';
     	            print '</tr>';
    -
     	        }
     
     	        $total_global_ht += $total_next_ht;
    @@ -4471,6 +4505,7 @@ else if ($id > 0 || ! empty($ref))
     
     			print '<tr class="liste_titre nodrag nodrop">';
     
    +			// Adds a line numbering column
     			if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
     				print '<td align="center" width="5">&nbsp;</td>';
     			}
    @@ -4494,6 +4529,7 @@ else if ($id > 0 || ! empty($ref))
     			print '<td width="10">&nbsp;</td>';
     			print "</tr>\n";
     
    +			// Adds a line numbering column
     			if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
     				print '<td align="center" width="5">&nbsp;</td>';
     			}
    @@ -4517,7 +4553,7 @@ else if ($id > 0 || ! empty($ref))
     
     	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#addline' : '#line_' . GETPOST('lineid')) . '" method="POST">
     	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
    -	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
    +	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
     	<input type="hidden" name="mode" value="">
     	<input type="hidden" name="id" value="' . $object->id . '">
     	';
    @@ -4915,5 +4951,6 @@ else if ($id > 0 || ! empty($ref))
     	include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php
    index 7012b0ef800..5075d9d8cb7 100644
    --- a/htdocs/compta/facture/class/api_invoices.class.php
    +++ b/htdocs/compta/facture/class/api_invoices.class.php
    @@ -32,7 +32,7 @@ class Invoices extends DolibarrApi
          * @var array   $FIELDS     Mandatory fields, checked when create and update object
          */
         static $FIELDS = array(
    -        'socid'
    +        'socid',
         );
     
         /**
    @@ -104,7 +104,8 @@ class Invoices extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -245,29 +246,30 @@ class Invoices extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function createInvoiceFromOrder($orderid) {
    +    function createInvoiceFromOrder($orderid)
    +    {
     
             require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
     
             if(! DolibarrApiAccess::$user->rights->commande->lire) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($orderid)) {
    -                throw new RestException(400, 'Order ID is mandatory');
    +            throw new RestException(400, 'Order ID is mandatory');
             }
     
             $order = new Commande($this->db);
             $result = $order->fetch($orderid);
             if( ! $result ) {
    -                throw new RestException(404, 'Order not found');
    +            throw new RestException(404, 'Order not found');
             }
     
             $result = $this->invoice->createFromOrder($order, DolibarrApiAccess::$user);
             if( $result < 0) {
    -                throw new RestException(405, $this->invoice->error);
    +            throw new RestException(405, $this->invoice->error);
             }
             $this->invoice->fetchObjectLinked();
             return $this->_cleanObjectDatas($this->invoice);
    @@ -282,7 +284,8 @@ class Invoices extends DolibarrApi
          *
          * @return int
          */
    -    function getLines($id) {
    +    function getLines($id)
    +    {
         	if(! DolibarrApiAccess::$user->rights->facture->lire) {
         		throw new RestException(401);
         	}
    @@ -319,7 +322,8 @@ class Invoices extends DolibarrApi
          * @throws 401
          * @throws 404
          */
    -    function putLine($id, $lineid, $request_data = null) {
    +    function putLine($id, $lineid, $request_data = null)
    +    {
         	if(! DolibarrApiAccess::$user->rights->facture->creer) {
         		throw new RestException(401);
         	}
    @@ -383,7 +387,8 @@ class Invoices extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function deleteLine($id, $lineid) {
    +    function deleteLine($id, $lineid)
    +    {
     
         	if(! DolibarrApiAccess::$user->rights->facture->creer) {
         		throw new RestException(401);
    @@ -511,67 +516,68 @@ class Invoices extends DolibarrApi
          * @throws 404
          * @throws 400
          */
    -    function postLine($id, $request_data = null) {
    -      if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                        throw new RestException(401);
    -                  }
    +    function postLine($id, $request_data = null)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->facture->creer) {
    +            throw new RestException(401);
    +        }
     
    -      $result = $this->invoice->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Invoice not found');
    -      }
    +        $result = $this->invoice->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Invoice not found');
    +        }
     
    -      if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
    -                          throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    +        if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
     
    -      $request_data = (object) $request_data;
    +        $request_data = (object) $request_data;
     
    -      // Reset fk_parent_line for no child products and special product
    -      if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) {
    -              $request_data->fk_parent_line = 0;
    -      }
    +        // Reset fk_parent_line for no child products and special product
    +        if (($request_data->product_type != 9 && empty($request_data->fk_parent_line)) || $request_data->product_type == 9) {
    +            $request_data->fk_parent_line = 0;
    +        }
     
    -      // calculate pa_ht
    -      $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht);
    -      $pa_ht = $marginInfos[0];
    +        // calculate pa_ht
    +        $marginInfos = getMarginInfos($request_data->subprice, $request_data->remise_percent, $request_data->tva_tx, $request_data->localtax1_tx, $request_data->localtax2_tx, $request_data->fk_fournprice, $request_data->pa_ht);
    +        $pa_ht = $marginInfos[0];
     
    -      $updateRes = $this->invoice->addline(
    -                              $request_data->desc,
    -                              $request_data->subprice,
    -                              $request_data->qty,
    -                              $request_data->tva_tx,
    -                              $request_data->localtax1_tx,
    -                              $request_data->localtax2_tx,
    -                              $request_data->fk_product,
    -                              $request_data->remise_percent,
    -                              $request_data->date_start,
    -                              $request_data->date_end,
    -                              $request_data->fk_code_ventilation,
    -                              $request_data->info_bits,
    -                              $request_data->fk_remise_except,
    -                              'HT',
    -                              0,
    -                              $request_data->product_type,
    -                              $request_data->rang,
    -                              $request_data->special_code,
    -                              $request_data->origin,
    -                              $request_data->origin_id,
    -                              $request_data->fk_parent_line,
    -                              empty($request_data->fk_fournprice)?null:$request_data->fk_fournprice,
    -                              $pa_ht,
    -                              $request_data->label,
    -                              $request_data->array_options,
    -                              $request_data->situation_percent,
    -                              $request_data->fk_prev_id,
    -                              $request_data->fk_unit
    -      );
    +        $updateRes = $this->invoice->addline(
    +            $request_data->desc,
    +            $request_data->subprice,
    +            $request_data->qty,
    +            $request_data->tva_tx,
    +            $request_data->localtax1_tx,
    +            $request_data->localtax2_tx,
    +            $request_data->fk_product,
    +            $request_data->remise_percent,
    +            $request_data->date_start,
    +            $request_data->date_end,
    +            $request_data->fk_code_ventilation,
    +            $request_data->info_bits,
    +            $request_data->fk_remise_except,
    +            'HT',
    +            0,
    +            $request_data->product_type,
    +            $request_data->rang,
    +            $request_data->special_code,
    +            $request_data->origin,
    +            $request_data->origin_id,
    +            $request_data->fk_parent_line,
    +            empty($request_data->fk_fournprice)?null:$request_data->fk_fournprice,
    +            $pa_ht,
    +            $request_data->label,
    +            $request_data->array_options,
    +            $request_data->situation_percent,
    +            $request_data->fk_prev_id,
    +            $request_data->fk_unit
    +        );
     
    -      if ($updateRes < 0) {
    +        if ($updateRes < 0) {
                 throw new RestException(400, 'Unable to insert the new line. Check your inputs. '.$this->invoice->error);
    -      }
    +        }
     
    -      return $updateRes;
    +        return $updateRes;
         }
     
         /**
    @@ -647,23 +653,23 @@ class Invoices extends DolibarrApi
         function settodraft($id, $idwarehouse=-1)
         {
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             $result = $this->invoice->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Invoice not found');
    +            throw new RestException(404, 'Invoice not found');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
     
             $result = $this->invoice->set_draft(DolibarrApiAccess::$user, $idwarehouse);
             if ($result == 0) {
    -                throw new RestException(304, 'Nothing done.');
    +            throw new RestException(304, 'Nothing done.');
             }
             if ($result < 0) {
    -                throw new RestException(500, 'Error : '.$this->invoice->error);
    +            throw new RestException(500, 'Error : '.$this->invoice->error);
             }
     
             $result = $this->invoice->fetch($id);
    @@ -750,23 +756,23 @@ class Invoices extends DolibarrApi
         function settopaid($id, $close_code='', $close_note='')
         {
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             $result = $this->invoice->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Invoice not found');
    +            throw new RestException(404, 'Invoice not found');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
     
             $result = $this->invoice->set_paid(DolibarrApiAccess::$user, $close_code, $close_note);
             if ($result == 0) {
    -                throw new RestException(304, 'Error nothing done. May be object is already validated');
    +            throw new RestException(304, 'Error nothing done. May be object is already validated');
             }
             if ($result < 0) {
    -                throw new RestException(500, 'Error : '.$this->invoice->error);
    +            throw new RestException(500, 'Error : '.$this->invoice->error);
             }
     
     
    @@ -801,23 +807,23 @@ class Invoices extends DolibarrApi
         function settounpaid($id)
         {
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             $result = $this->invoice->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Invoice not found');
    +            throw new RestException(404, 'Invoice not found');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('facture',$this->invoice->id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
     
             $result = $this->invoice->set_unpaid(DolibarrApiAccess::$user);
             if ($result == 0) {
    -                throw new RestException(304, 'Nothing done');
    +            throw new RestException(304, 'Nothing done');
             }
             if ($result < 0) {
    -                throw new RestException(500, 'Error : '.$this->invoice->error);
    +            throw new RestException(500, 'Error : '.$this->invoice->error);
             }
     
     
    @@ -849,30 +855,31 @@ class Invoices extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function useDiscount($id, $discountid) {
    +    function useDiscount($id, $discountid)
    +    {
     
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($id)) {
    -                throw new RestException(400, 'Invoice ID is mandatory');
    +            throw new RestException(400, 'Invoice ID is mandatory');
             }
             if(empty($discountid)) {
    -                throw new RestException(400, 'Discount ID is mandatory');
    +            throw new RestException(400, 'Discount ID is mandatory');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
     
             $result = $this->invoice->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Invoice not found');
    +            throw new RestException(404, 'Invoice not found');
             }
     
             $result = $this->invoice->insert_discount($discountid);
             if( $result < 0) {
    -                throw new RestException(405, $this->invoice->error);
    +            throw new RestException(405, $this->invoice->error);
             }
     
             return $result;
    @@ -894,32 +901,33 @@ class Invoices extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function useCreditNote($id, $discountid) {
    +    function useCreditNote($id, $discountid)
    +    {
     
             require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php';
     
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($id)) {
    -                throw new RestException(400, 'Invoice ID is mandatory');
    +            throw new RestException(400, 'Invoice ID is mandatory');
             }
             if(empty($discountid)) {
    -                throw new RestException(400, 'Credit ID is mandatory');
    +            throw new RestException(400, 'Credit ID is mandatory');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
             $discount = new DiscountAbsolute($this->db);
             $result = $discount->fetch($discountid);
             if( ! $result ) {
    -                throw new RestException(404, 'Credit not found');
    +            throw new RestException(404, 'Credit not found');
             }
     
             $result = $discount->link_to_invoice(0, $id);
             if( $result < 0) {
    -                throw new RestException(405, $discount->error);
    +            throw new RestException(405, $discount->error);
             }
     
             return $result;
    @@ -938,27 +946,28 @@ class Invoices extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -    function getPayments($id) {
    +    function getPayments($id)
    +    {
     
             if(! DolibarrApiAccess::$user->rights->facture->lire) {
    -                throw new RestException(401);
    +            throw new RestException(401);
             }
             if(empty($id)) {
    -                throw new RestException(400, 'Invoice ID is mandatory');
    +            throw new RestException(400, 'Invoice ID is mandatory');
             }
     
             if( ! DolibarrApi::_checkAccessToResource('facture',$id)) {
    -                throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
             }
     
             $result = $this->invoice->fetch($id);
             if( ! $result ) {
    -                throw new RestException(404, 'Invoice not found');
    +            throw new RestException(404, 'Invoice not found');
             }
     
             $result = $this->invoice->getListOfPayments();
             if( $result < 0) {
    -                throw new RestException(405, $this->invoice->error);
    +            throw new RestException(405, $this->invoice->error);
             }
     
             return $result;
    @@ -985,8 +994,9 @@ class Invoices extends DolibarrApi
          * @throws 401
          * @throws 404
          */
    -    function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='') {
    -    	global $conf;
    +    function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement='', $comment='', $chqemetteur='', $chqbank='')
    +    {
    +        global $conf;
     
         	require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
     
    @@ -1111,7 +1121,7 @@ class Invoices extends DolibarrApi
             require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
     
             if(! DolibarrApiAccess::$user->rights->facture->creer) {
    -                throw new RestException(403);
    +            throw new RestException(403);
             }
             foreach($arrayofamounts as $id => $amount) {
             	if(empty($id)) {
    @@ -1215,18 +1225,19 @@ class Invoices extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
    -    	$object = parent::_cleanObjectDatas($object);
    +        $object = parent::_cleanObjectDatas($object);
     
             unset($object->note);
    -    	unset($object->address);
    -    	unset($object->barcode_type);
    -    	unset($object->barcode_type_code);
    -    	unset($object->barcode_type_label);
    -    	unset($object->barcode_type_coder);
    +        unset($object->address);
    +        unset($object->barcode_type);
    +        unset($object->barcode_type_code);
    +        unset($object->barcode_type_label);
    +        unset($object->barcode_type_coder);
     
    -    	return $object;
    +        return $object;
         }
     
         /**
    @@ -1241,11 +1252,11 @@ class Invoices extends DolibarrApi
         {
             $invoice = array();
             foreach (Invoices::$FIELDS as $field) {
    -            if (!isset($data[$field]))
    +            if (!isset($data[$field])) {
                     throw new RestException(400, "$field field missing");
    +            }
                 $invoice[$field] = $data[$field];
             }
             return $invoice;
         }
    -
     }
    diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php
    index a82f06ad851..ad33432484f 100644
    --- a/htdocs/compta/facture/class/facture-rec.class.php
    +++ b/htdocs/compta/facture/class/facture-rec.class.php
    @@ -39,36 +39,59 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
      */
     class FactureRec extends CommonInvoice
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='facturerec';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='facture_rec';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line='facturedet_rec';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_facture';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='bill';
     
    -	var $entity;
    -	var $number;
    -	var $date;
    -	var $amount;
    -	var $remise;
    -	var $tva;
    -	var $total;
    -	var $db_table;
    -	var $propalid;
    +	/**
    +	 * @var int Entity
    +	 */
    +	public $entity;
     
    -	var $date_last_gen;
    -	var $date_when;
    -	var $nb_gen_done;
    -	var $nb_gen_max;
    +	public $number;
    +	public $date;
    +	public $amount;
    +	public $remise;
    +	public $tva;
    +	public $total;
    +	public $db_table;
    +	public $propalid;
     
    -	var $frequency;
    -	var $unit_frequency;
    +	public $date_last_gen;
    +	public $date_when;
    +	public $nb_gen_done;
    +	public $nb_gen_max;
     
    -	var $rang;
    -	var $special_code;
    +	public $frequency;
    +	public $unit_frequency;
     
    -	var $usenewprice=0;
    +	public $rang;
    +	public $special_code;
     
    -	var $suspended;			// status
    +	public $usenewprice=0;
    +
    +	public $suspended;			// status
     
     	const STATUS_NOTSUSPENDED = 0;
     	const STATUS_SUSPENDED = 1;
    @@ -432,18 +455,20 @@ class FactureRec extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Recupere les lignes de factures predefinies dans this->lines
     	 *
    -	 *	@return     int         1 if OK, < 0 if KO
    - 	 */
    +	 *  @return     int         1 if OK, < 0 if KO
    +     */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		$this->lines=array();
     
     		// Retreive all extrafield for line
     		// fetch optionals attributes and labels
    -		require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
    +		require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     		$extrafieldsline=new ExtraFields($this->db);
     		$extrafieldsline=$extrafieldsline->fetch_name_optionals_label('facturedet_rec',true);
     
    @@ -983,8 +1008,8 @@ class FactureRec extends CommonInvoice
     
     		$error=0;
     
    -		$langs->load("bills");
    -		$langs->load('main');
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","bills"));
     
     		$nb_create=0;
     
    @@ -1173,6 +1198,7 @@ class FactureRec extends CommonInvoice
     		return $this->LibStatut($this->frequency?1:0, $this->suspended, $mode, $alreadypaid, empty($this->type)?0:$this->type);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return label of a status
     	 *
    @@ -1185,6 +1211,7 @@ class FactureRec extends CommonInvoice
     	 */
     	function LibStatut($recur, $status, $mode=0, $alreadypaid=-1, $type=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('bills');
     
    @@ -1203,7 +1230,7 @@ class FactureRec extends CommonInvoice
     				else return $langs->trans("Draft");
     			}
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			$prefix='Short';
     			if ($recur)
    @@ -1217,7 +1244,7 @@ class FactureRec extends CommonInvoice
     				else return $langs->trans("Draft");
     			}
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($recur)
     			{
    @@ -1230,7 +1257,7 @@ class FactureRec extends CommonInvoice
     				else return img_picto($langs->trans('Draft'),'statut0').' '.$langs->trans('Draft');
     			}
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($recur)
     			{
    @@ -1244,7 +1271,7 @@ class FactureRec extends CommonInvoice
     				else return img_picto($langs->trans('Draft'),'statut0');
     			}
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			$prefix='';
     			if ($recur)
    @@ -1258,7 +1285,7 @@ class FactureRec extends CommonInvoice
     				else return img_picto($langs->trans('Draft'),'statut0').' '.$langs->trans('Draft');
     			}
     		}
    -		if ($mode == 5 || $mode == 6)
    +		elseif ($mode == 5 || $mode == 6)
     		{
     			$prefix='';
     			if ($mode == 5) $prefix='Short';
    @@ -1639,7 +1666,14 @@ class FactureRec extends CommonInvoice
      */
     class FactureLigneRec extends CommonInvoiceLine
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='facturedetrec';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='facturedet_rec';
     
     	var $date_start_fill;
    @@ -1843,7 +1877,5 @@ class FactureLigneRec extends CommonInvoiceLine
         		$this->db->rollback();
         		return -2;
         	}
    -
         }
    -
     }
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index 315325c2474..3d98271bb26 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -53,16 +53,37 @@ if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accoun
      */
     class Facture extends CommonInvoice
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='facture';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='facture';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line = 'facturedet';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element = 'fk_facture';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='bill';
    +
     	/**
     	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 * @var int
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
     	 * @var integer
    @@ -77,11 +98,18 @@ class Facture extends CommonInvoice
     	public $socid;
     
     	public $author;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_valid;
    +
     	public $date;              // Date invoice
    -	public $date_creation;		// Creation date
    -	public $date_validation;	// Validation date
     	public $datem;
     	public $ref_client;
     	public $ref_int;
    @@ -105,21 +133,34 @@ class Facture extends CommonInvoice
     	public $close_note;
     	//! 1 if invoice paid COMPLETELY, 0 otherwise (do not use it anymore, use statut and close_code)
     	public $paye;
    +	//! key of module source when invoice generated from a dedicated module ('cashdesk', 'takepos', ...)
    +	public $module_source;
    +	//! key of pos source ('0', '1', ...)
    +	public $pos_source;
    +	//! id of template invoice when generated from a template invoice
    +	public $fk_fac_rec_source;
     	//! id of source invoice if replacement invoice or credit note
     	public $fk_facture_source;
     	public $linked_objects=array();
     	public $date_lim_reglement;
     	public $cond_reglement_code;		// Code in llx_c_paiement
     	public $mode_reglement_code;		// Code in llx_c_paiement
    -	public $fk_bank;					// Field to store bank id to use when payment mode is withdraw
    +
    +	/**
    +     * @var int ID Field to store bank id to use when payment mode is withdraw
    +     */
    +	public $fk_bank;
    +
     	/**
     	 * @deprecated
     	 */
     	public $products=array();
    +
     	/**
     	 * @var FactureLigne[]
     	 */
     	public $lines=array();
    +
     	public $line;
     	public $extraparams=array();
     	public $specimen;
    @@ -127,7 +168,11 @@ class Facture extends CommonInvoice
     	public $fac_rec;
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     	public $multicurrency_tx;
     	public $multicurrency_total_ht;
    @@ -192,7 +237,7 @@ class Facture extends CommonInvoice
     	const TYPE_SITUATION = 5;
     
     	/**
    -	 * Draft
    +	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
     
    @@ -419,7 +464,7 @@ class Facture extends CommonInvoice
     		$sql.= ", note_public";
     		$sql.= ", ref_client, ref_int";
             $sql.= ", fk_account";
    -		$sql.= ", fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet";
    +		$sql.= ", module_source, pos_source, fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet";
     		$sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf";
     		$sql.= ", situation_cycle_ref, situation_counter, situation_final";
     		$sql.= ", fk_incoterms, location_incoterms";
    @@ -443,6 +488,8 @@ class Facture extends CommonInvoice
     		$sql.= ", ".($this->ref_client?"'".$this->db->escape($this->ref_client)."'":"null");
     		$sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null");
     		$sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL');
    +		$sql.= ", ".($this->module_source ? "'".$this->db->escape($this->module_source)."'" : "null");
    +		$sql.= ", ".($this->pos_source != '' ? "'".$this->db->escape($this->pos_source)."'" : "null");
     		$sql.= ", ".($this->fk_fac_rec_source?"'".$this->db->escape($this->fk_fac_rec_source)."'":"null");
     		$sql.= ", ".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null");
     		$sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null");
    @@ -943,6 +990,7 @@ class Facture extends CommonInvoice
     		$this->user_valid         = '';
     		$this->fk_facture_source  = 0;
     		$this->date_creation      = '';
    +		$this->date_modification = '';
     		$this->date_validation    = '';
     		$this->ref_client         = '';
     		$this->close_code         = '';
    @@ -1159,7 +1207,8 @@ class Facture extends CommonInvoice
     		if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id;
     		else $url = DOL_URL_ROOT.'/compta/facture/card.php?facid='.$this->id;
     
    -		if ($short) return $url;
    +        if (!$user->rights->facture->lire)
    +            $option = 'nolink';
     
     		if ($option !== 'nolink')
     		{
    @@ -1169,6 +1218,8 @@ class Facture extends CommonInvoice
     			if ($add_save_lastsearch_values) $url.='&save_lastsearch_values=1';
     		}
     
    +		if ($short) return $url;
    +
     		$picto='bill';
     		if ($this->type == self::TYPE_REPLACEMENT) $picto.='r';	// Replacement invoice
     		if ($this->type == self::TYPE_CREDIT_NOTE) $picto.='a';	// Credit note
    @@ -1190,7 +1241,7 @@ class Facture extends CommonInvoice
                 if (! empty($this->total_tva))
                     $label.= '<br><b>' . $langs->trans('VAT') . ':</b> ' . price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
                 if (! empty($this->total_localtax1) && $this->total_localtax1 != 0)		// We keep test != 0 because $this->total_localtax1 can be '0.00000000'
    -                $label.= '<br><b>eee' . $langs->trans('LT1') . ':</b> ' . price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency);
    +                $label.= '<br><b>' . $langs->trans('LT1') . ':</b> ' . price($this->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency);
                 if (! empty($this->total_localtax2) && $this->total_localtax2 != 0)
                     $label.= '<br><b>' . $langs->trans('LT2') . ':</b> ' . price($this->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency);
                 if (! empty($this->total_ttc))
    @@ -1214,6 +1265,11 @@ class Facture extends CommonInvoice
             $linkstart.=$linkclose.'>';
     		$linkend='</a>';
     
    +        if ($option == 'nolink') {
    +            $linkstart = '';
    +            $linkend = '';
    +        }
    +
     		$result .= $linkstart;
     		if ($withpicto) $result.=img_object(($notooltip?'':$label), $picto, ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
     		if ($withpicto != 2) $result.= ($max?dol_trunc($this->ref,$max):$this->ref);
    @@ -1221,12 +1277,14 @@ class Facture extends CommonInvoice
     
     		if ($addlinktonotes)
     		{
    -		    $txttoshow=($user->societe_id>0?$this->note_public:$this->note_private);
    +		    $txttoshow=($user->socid > 0 ? $this->note_public : $this->note_private);
     		    if ($txttoshow)
     		    {
                     $notetoshow=$langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($txttoshow,1);
         		    $result.=' <span class="note inline-block">';
    -    		    $result.='<a href="'.DOL_URL_ROOT.'/compta/facture/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">'.img_picto('','object_generic').'</a>';
    +    		    $result.='<a href="'.DOL_URL_ROOT.'/compta/facture/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
    +    		    $result.=img_picto('','note');
    +    		    $result.='</a>';
         		    //$result.=img_picto($langs->trans("ViewNote"),'object_generic');
         		    //$result.='</a>';
         		    $result.='</span>';
    @@ -1302,6 +1360,7 @@ class Facture extends CommonInvoice
     				$this->date_pointoftax		= $this->db->jdate($obj->date_pointoftax);
     				$this->date_creation		= $this->db->jdate($obj->datec);
     				$this->date_validation		= $this->db->jdate($obj->datev);
    +				$this->date_modification		= $this->db->jdate($obj->datem);
     				$this->datem				= $this->db->jdate($obj->datem);
     				$this->remise_percent		= $obj->remise_percent;
     				$this->remise_absolue		= $obj->remise_absolue;
    @@ -1392,6 +1451,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load all detailed lines into this->lines
     	 *
    @@ -1399,6 +1459,7 @@ class Facture extends CommonInvoice
     	 */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		$this->lines=array();
     
     		$sql = 'SELECT l.rowid, l.fk_facture, l.fk_product, l.fk_parent_line, l.label as custom_label, l.description, l.product_type, l.price, l.qty, l.vat_src_code, l.tva_tx,';
    @@ -1537,7 +1598,6 @@ class Facture extends CommonInvoice
     				}
     			}
     		}
    -
     	}
     
     	/**
    @@ -1652,6 +1712,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume the discount)
     	 *
    @@ -1660,6 +1721,7 @@ class Facture extends CommonInvoice
     	 */
     	function insert_discount($idremise)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    @@ -1752,6 +1814,7 @@ class Facture extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set customer ref
     	 *
    @@ -1761,6 +1824,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_ref_client($ref_client, $notrigger=0)
     	{
    +        // phpcs:enable
     	    global $user;
     
     		$error=0;
    @@ -1945,7 +2009,8 @@ class Facture extends CommonInvoice
     
     							if (! dol_delete_file($file,0,0,0,$this)) // For triggers
     							{
    -								$this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
    +								$langs->load("errors");
    +								$this->error=$langs->trans("ErrorFailToDeleteFile",$file);
     								$this->db->rollback();
     								return 0;
     							}
    @@ -1954,7 +2019,8 @@ class Facture extends CommonInvoice
     						{
     							if (! dol_delete_dir_recursive($dir)) // For remove dir and meta
     							{
    -								$this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
    +								$langs->load("errors");
    +								$this->error=$langs->trans("ErrorFailToDeleteDir",$dir);
     								$this->db->rollback();
     								return 0;
     							}
    @@ -1985,6 +2051,7 @@ class Facture extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Tag la facture comme paye completement (si close_code non renseigne) => this->fk_statut=2, this->paye=1
     	 *  ou partiellement (si close_code renseigne) + appel trigger BILL_PAYED => this->fk_statut=2, this->paye stay 0
    @@ -1996,6 +2063,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_paid($user, $close_code='', $close_note='')
     	{
    +        // phpcs:enable
     		$error=0;
     
     		if ($this->paye != 1)
    @@ -2043,6 +2111,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Tag la facture comme non payee completement + appel trigger BILL_UNPAYED
     	 *	Fonction utilisee quand un paiement prelevement est refuse,
    @@ -2053,6 +2122,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_unpaid($user)
     	{
    +        // phpcs:enable
     		$error=0;
     
     		$this->db->begin();
    @@ -2090,6 +2160,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Tag invoice as canceled, with no payment on it (example for replacement invoice or payment never received) + call trigger BILL_CANCEL
     	 *	Warning, if option to decrease stock on invoice was set, this function does not change stock (it might be a cancel because
    @@ -2102,6 +2173,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_canceled($user, $close_code='', $close_note='')
     	{
    +        // phpcs:enable
     
     		dol_syslog(get_class($this)."::set_canceled rowid=".$this->id, LOG_DEBUG);
     
    @@ -2393,7 +2465,6 @@ class Facture extends CommonInvoice
         				else $this->situation_final = 1;
     
     				$this->setFinal($user);
    -
                     }
     			}
     		}
    @@ -2453,6 +2524,7 @@ class Facture extends CommonInvoice
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set draft status
     	 *
    @@ -2462,6 +2534,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_draft($user,$idwarehouse=-1)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$error=0;
    @@ -3018,6 +3091,7 @@ class Facture extends CommonInvoice
     		else return $situation_percent < $obj->situation_percent;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Update invoice line with percentage
     	 *
    @@ -3027,9 +3101,10 @@ class Facture extends CommonInvoice
     	 */
     	function update_percent($line, $percent)
     	{
    +        // phpcs:enable
     	    global $mysoc,$user;
     
    -		include_once(DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php');
    +		include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php';
     
     		// Cap percentages to 100
     		if ($percent > 100) $percent = 100;
    @@ -3114,6 +3189,7 @@ class Facture extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set percent discount
     	 *
    @@ -3124,6 +3200,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_remise($user, $remise, $notrigger=0)
     	{
    +        // phpcs:enable
     		// Clean parameters
     		if (empty($remise)) $remise=0;
     
    @@ -3178,6 +3255,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set absolute discount
     	 *
    @@ -3188,6 +3266,7 @@ class Facture extends CommonInvoice
     	 */
     	function set_remise_absolue($user, $remise, $notrigger=0)
     	{
    +        // phpcs:enable
     		if (empty($remise)) $remise=0;
     
     		if ($user->rights->facture->creer)
    @@ -3378,6 +3457,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of invoices (eventually filtered on a user) into an array
     	 *
    @@ -3393,6 +3473,7 @@ class Facture extends CommonInvoice
     	 */
     	function liste_array($shortlist=0, $draft=0, $excluser='', $socid=0, $limit=0, $offset=0, $sortfield='f.datef,f.rowid', $sortorder='DESC')
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		$ga = array();
    @@ -3452,6 +3533,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of invoices qualified to be replaced by another invoice.
     	 *	Invoices matching the following rules are returned:
    @@ -3462,6 +3544,7 @@ class Facture extends CommonInvoice
     	 */
     	function list_replacable_invoices($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$return = array();
    @@ -3500,6 +3583,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of invoices qualified to be corrected by a credit note.
     	 *	Invoices matching the following rules are returned:
    @@ -3510,6 +3594,7 @@ class Facture extends CommonInvoice
     	 */
     	function list_qualified_avoir_invoices($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$return = array();
    @@ -3573,6 +3658,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a withdrawal request for a standing order.
     	 *  Use the remain to pay excluding all existing open direct debit requests.
    @@ -3583,6 +3669,7 @@ class Facture extends CommonInvoice
     	 */
     	function demande_prelevement($fuser, $amount=0)
     	{
    +        // phpcs:enable
     
     		$error=0;
     
    @@ -3683,6 +3770,7 @@ class Facture extends CommonInvoice
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Supprime une demande de prelevement
     	 *
    @@ -3692,6 +3780,7 @@ class Facture extends CommonInvoice
     	 */
     	function demande_prelevement_delete($fuser, $did)
     	{
    +        // phpcs:enable
     		$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande';
     		$sql .= ' WHERE rowid = '.$did;
     		$sql .= ' AND traite = 0';
    @@ -3708,6 +3797,7 @@ class Facture extends CommonInvoice
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -3716,11 +3806,12 @@ class Facture extends CommonInvoice
     	 */
     	function load_board($user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$clause = " WHERE";
     
    -		$sql = "SELECT f.rowid, f.date_lim_reglement as datefin,f.fk_statut";
    +		$sql = "SELECT f.rowid, f.date_lim_reglement as datefin,f.fk_statut, f.total";
     		$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
     		if (!$user->rights->societe->client->voir && !$user->societe_id)
     		{
    @@ -3753,6 +3844,7 @@ class Facture extends CommonInvoice
     				$generic_facture->statut = $obj->fk_statut;
     
     				$response->nbtodo++;
    +				$response->total += $obj->total;
     
     				if ($generic_facture->hasDelay()) {
     					$response->nbtodolate++;
    @@ -3952,6 +4044,7 @@ class Facture extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -3959,6 +4052,7 @@ class Facture extends CommonInvoice
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		$this->nb=array();
    @@ -4012,7 +4106,7 @@ class Facture extends CommonInvoice
     	 *  @param  int			$hidedetails    Hide details of lines
     	 *  @param  int			$hidedesc       Hide description
     	 *  @param  int			$hideref        Hide ref
    -	 * @param   null|array  $moreparams     Array to provide more information
    +	 *  @param   null|array  $moreparams     Array to provide more information
     	 *	@return int        					<0 if KO, >0 if OK
     	 */
     	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
    @@ -4021,12 +4115,15 @@ class Facture extends CommonInvoice
     
     		$langs->load("bills");
     
    -		if (! dol_strlen($modele)) {
    -
    +		if (! dol_strlen($modele))
    +		{
     			$modele = 'crabe';
    +			$thisTypeConfName = 'FACTURE_ADDON_PDF_'.$this->type;
     
     			if ($this->modelpdf) {
     				$modele = $this->modelpdf;
    +			} elseif (! empty($conf->global->$thisTypeConfName)) {
    +				$modele = $conf->global->$thisTypeConfName;
     			} elseif (! empty($conf->global->FACTURE_ADDON_PDF)) {
     				$modele = $conf->global->FACTURE_ADDON_PDF;
     			}
    @@ -4065,6 +4162,7 @@ class Facture extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Checks if the invoice is the first of a cycle
     	 *
    @@ -4072,9 +4170,11 @@ class Facture extends CommonInvoice
     	 */
     	function is_first()
     	{
    +        // phpcs:enable
     		return ($this->situation_counter == 1);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns an array containing the previous situations as Facture objects
     	 *
    @@ -4082,6 +4182,7 @@ class Facture extends CommonInvoice
     	 */
     	function get_prev_sits()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'facture';
    @@ -4154,6 +4255,7 @@ class Facture extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Checks if the invoice is the last in its cycle
     	 *
    @@ -4162,6 +4264,7 @@ class Facture extends CommonInvoice
     	 */
     	function is_last_in_cycle()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (!empty($this->situation_cycle_ref)) {
    @@ -4224,45 +4327,52 @@ class Facture extends CommonInvoice
      */
     class FactureLigne extends CommonInvoiceLine
     {
    -    public $element='facturedet';
    -    public $table_element='facturedet';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='facturedet';
     
    -	var $oldline;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='facturedet';
    +
    +	public $oldline;
     
     	//! From llx_facturedet
     	//! Id facture
    -	var $fk_facture;
    +	public $fk_facture;
     	//! Id parent line
    -	var $fk_parent_line;
    +	public $fk_parent_line;
     	/**
     	 * @deprecated
     	 */
    -	var $label;
    +	public $label;
     	//! Description ligne
    -	var $desc;
    +	public $desc;
     
    -	var $localtax1_type;	// Local tax 1 type
    -	var $localtax2_type;	// Local tax 2 type
    -	var $fk_remise_except;	// Link to line into llx_remise_except
    -	var $rang = 0;
    +	public $localtax1_type;	// Local tax 1 type
    +	public $localtax2_type;	// Local tax 2 type
    +	public $fk_remise_except;	// Link to line into llx_remise_except
    +	public $rang = 0;
     
    -	var $fk_fournprice;
    -	var $pa_ht;
    -	var $marge_tx;
    -	var $marque_tx;
    +	public $fk_fournprice;
    +	public $pa_ht;
    +	public $marge_tx;
    +	public $marque_tx;
     
    -	var $special_code;	// Liste d'options non cumulabels:
    +	public $special_code;	// Liste d'options non cumulabels:
     	// 1: frais de port
     	// 2: ecotaxe
     	// 3: ??
     
    -	var $origin;
    -	var $origin_id;
    +	public $origin;
    +	public $origin_id;
     
    -	var $fk_code_ventilation = 0;
    +	public $fk_code_ventilation = 0;
     
    -	var $date_start;
    -	var $date_end;
    +	public $date_start;
    +	public $date_end;
     
     	// Ne plus utiliser
     	//var $price;         	// P.U. HT apres remise % de ligne (exemple 80)
    @@ -4273,17 +4383,17 @@ class FactureLigne extends CommonInvoiceLine
     	 * @deprecated
     	 * @see product_ref
     	 */
    -	var $ref;				// Product ref (deprecated)
    -	var $product_ref;       // Product ref
    +	public $ref;				// Product ref (deprecated)
    +	public $product_ref;       // Product ref
     	/**
     	 * @deprecated
     	 * @see product_label
     	 */
    -	var $libelle;      		// Product label (deprecated)
    -	var $product_label;     // Product label
    -	var $product_desc;  	// Description produit
    +	public $libelle;      		// Product label (deprecated)
    +	public $product_label;     // Product label
    +	public $product_desc;  	// Description produit
     
    -	var $skip_update_total; // Skip update price total for special lines
    +	public $skip_update_total; // Skip update price total for special lines
     
     	/**
     	 * @var int Situation advance percentage
    @@ -4296,12 +4406,12 @@ class FactureLigne extends CommonInvoiceLine
     	public $fk_prev_id;
     
     	// Multicurrency
    -	var $fk_multicurrency;
    -	var $multicurrency_code;
    -	var $multicurrency_subprice;
    -	var $multicurrency_total_ht;
    -	var $multicurrency_total_tva;
    -	var $multicurrency_total_ttc;
    +	public $fk_multicurrency;
    +	public $multicurrency_code;
    +	public $multicurrency_subprice;
    +	public $multicurrency_total_ht;
    +	public $multicurrency_total_tva;
    +	public $multicurrency_total_ttc;
     
     	/**
     	 *	Load invoice line from database
    @@ -4333,6 +4443,7 @@ class FactureLigne extends CommonInvoiceLine
     			$objp = $this->db->fetch_object($result);
     
     			$this->rowid				= $objp->rowid;
    +			$this->id					= $objp->rowid;
     			$this->fk_facture			= $objp->fk_facture;
     			$this->fk_parent_line		= $objp->fk_parent_line;
     			$this->label				= $objp->custom_label;
    @@ -4601,7 +4712,6 @@ class FactureLigne extends CommonInvoiceLine
     
     			$this->db->commit();
     			return $this->id;
    -
     		}
     		else
     		{
    @@ -4783,6 +4893,7 @@ class FactureLigne extends CommonInvoiceLine
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Update DB line fields total_xxx
     	 *	Used by migration
    @@ -4791,6 +4902,7 @@ class FactureLigne extends CommonInvoiceLine
     	 */
     	function update_total()
     	{
    +        // phpcs:enable
     		$this->db->begin();
     		dol_syslog(get_class($this)."::update_total", LOG_DEBUG);
     
    @@ -4823,6 +4935,7 @@ class FactureLigne extends CommonInvoiceLine
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns situation_percent of the previous line.
     	 * Warning: If invoice is a replacement invoice, this->fk_prev_id is id of the replaced line.
    @@ -4833,6 +4946,7 @@ class FactureLigne extends CommonInvoiceLine
     	 */
     	function get_prev_progress($invoiceid, $include_credit_note=true)
     	{
    +        // phpcs:enable
     		if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id == "") {
     			return 0;
     		} else {
    diff --git a/htdocs/compta/facture/class/facturestats.class.php b/htdocs/compta/facture/class/facturestats.class.php
    index 434fab6f373..1201c429a2a 100644
    --- a/htdocs/compta/facture/class/facturestats.class.php
    +++ b/htdocs/compta/facture/class/facturestats.class.php
    @@ -35,7 +35,11 @@ class FactureStats extends Stats
         var $socid;
         var $userid;
     
    -    public $table_element;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element;
    +	
         var $from;
         var $field;
         var $where;
    @@ -220,7 +224,5 @@ class FactureStats extends Stats
     
     		return $this->_getAllByProduct($sql);
     	}
    -
    -
     }
     
    diff --git a/htdocs/compta/facture/class/paymentterm.class.php b/htdocs/compta/facture/class/paymentterm.class.php
    index 3697a61672b..a3168db40d2 100644
    --- a/htdocs/compta/facture/class/paymentterm.class.php
    +++ b/htdocs/compta/facture/class/paymentterm.class.php
    @@ -28,23 +28,38 @@
      */
     class PaymentTerm // extends CommonObject
     {
    -	var $db;							//!< To store db handler
    -	var $error;							//!< To return error code (or message)
    -	var $errors=array();				//!< To return several error codes (or messages)
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
     	//public  $element='c_payment_term';			//!< Id that identify managed objects
     	//public  $table_element='c_payment_term';	//!< Name of table without prefix where object is stored
    -	var $context =array();
    +	public $context =array();
     
    -    var $id;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $code;
    -	var $sortorder;
    -	var $active;
    -	var $libelle;
    -	var $libelle_facture;
    -	var $type_cdr;
    -	var $nbjour;
    -	var $decalage;
    +	public $code;
    +	public $sortorder;
    +	public $active;
    +	public $libelle;
    +	public $libelle_facture;
    +	public $type_cdr;
    +	public $nbjour;
    +	public $decalage;
     
     
     
    @@ -120,18 +135,17 @@ class PaymentTerm // extends CommonObject
             {
                 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."c_payment_term");
     
    -			if (! $notrigger)
    -			{
    -	            // Uncomment this and change MYOBJECT to your own tag if you
    -	            // want this action call a trigger.
    +	        // Uncomment this and change MYOBJECT to your own tag if you
    +	        // want this action call a trigger.
    +			//if (! $notrigger) {
     
    -	            //// Call triggers
    -	            //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -	            //$interface=new Interfaces($this->db);
    -	            //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
    -	            //if ($result < 0) { $error++; $this->errors=$interface->errors; }
    -	            //// End call triggers
    -			}
    +	        //    // Call triggers
    +	        //    include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    +	        //    $interface=new Interfaces($this->db);
    +	        //    $result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
    +	        //    if ($result < 0) { $error++; $this->errors=$interface->errors; }
    +	        //    // End call triggers
    +			//}
             }
     
             // Commit or rollback
    @@ -197,8 +211,6 @@ class PaymentTerm // extends CommonObject
     				$this->type_cdr = $obj->type_cdr;
     				$this->nbjour = $obj->nbjour;
     				$this->decalage = $obj->decalage;
    -
    -
                 }
                 $this->db->free($resql);
     
    @@ -296,21 +308,16 @@ class PaymentTerm // extends CommonObject
     		$resql = $this->db->query($sql);
     		if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
     
    -		if (! $error)
    -		{
    -			if (! $notrigger)
    -			{
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action call a trigger.
    -
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action call a trigger.
    +		//if (! $error && ! $notrigger) {
     				// Call triggers
     				//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
     				//$interface=new Interfaces($this->db);
     				//$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
     				//if ($result < 0) { $error++; $this->errors=$interface->errors; }
     				// End call triggers
    -			}
    -		}
    +		//}
     
     		// Commit or rollback
     		if ($error)
    @@ -352,21 +359,16 @@ class PaymentTerm // extends CommonObject
     		$resql = $this->db->query($sql);
         	if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
     
    -		if (! $error)
    -		{
    -			if (! $notrigger)
    -			{
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -		        // want this action call a trigger.
    -
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action call a trigger.
    +		//if (! $error && ! $notrigger) {
     		        //// Call triggers
     		        //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
     		        //$interface=new Interfaces($this->db);
     		        //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
     		        //if ($result < 0) { $error++; $this->errors=$interface->errors; }
     		        //// End call triggers
    -			}
    -		}
    +		//}
     
             // Commit or rollback
     		if ($error)
    @@ -424,12 +426,9 @@ class PaymentTerm // extends CommonObject
     			$error++;
     		}
     
    -		if (! $error)
    -		{
    -
    -
    -
    -		}
    +		//if (! $error)
    +		//{
    +		//}
     
     		unset($this->context['createfromclone']);
     
    @@ -467,5 +466,4 @@ class PaymentTerm // extends CommonObject
     		$this->nbjour='';
     		$this->decalage='';
     	}
    -
     }
    diff --git a/htdocs/compta/facture/contact.php b/htdocs/compta/facture/contact.php
    index af872a174ca..948056fe404 100644
    --- a/htdocs/compta/facture/contact.php
    +++ b/htdocs/compta/facture/contact.php
    @@ -206,7 +206,6 @@ if ($id > 0 || ! empty($ref))
     		    $res=@include dol_buildpath($reldir.'/contacts.tpl.php');
     		    if ($res) break;
     		}
    -
     	}
     	else
     	{
    @@ -215,6 +214,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/facture/document.php b/htdocs/compta/facture/document.php
    index 828c77f1178..0ce8ad7eb92 100644
    --- a/htdocs/compta/facture/document.php
    +++ b/htdocs/compta/facture/document.php
    @@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     if (! empty($conf->projet->enabled)) {
    -	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
    +	include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
     // Load translation files required by the page
    @@ -78,7 +78,7 @@ if ($object->fetch($id))
      * Actions
      */
     
    -include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
     
     
     /*
    @@ -104,7 +104,7 @@ if ($id > 0 || ! empty($ref))
     
         	$totalpaye = $object->getSommePaiement();
     
    -		// Construit liste des fichiers
    +		// Build file list
     		$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     		$totalsize=0;
     		foreach($filearray as $key => $file)
    @@ -191,6 +191,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php
    index fb70da42665..d9ce0137f04 100644
    --- a/htdocs/compta/facture/fiche-rec.php
    +++ b/htdocs/compta/facture/fiche-rec.php
    @@ -1,14 +1,14 @@
     <?php
    -/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
    - * Copyright (C) 2013      Juanjo Menent	    <jmenent@2byte.es>
    - * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
    - * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2015      Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2016      Meziane Sof		<virtualsof@yahoo.fr>
    - * Copyright (C) 2017       Frédéric France         <frederic.france@netlogic.fr>
    +/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
    + * Copyright (C) 2012       Cedric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2015       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2016       Meziane Sof             <virtualsof@yahoo.fr>
    + * Copyright (C) 2017-2018  Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -35,8 +35,8 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
     require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     if (! empty($conf->projet->enabled)) {
    -	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
    -	//require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
    +	include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
    +	//include_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
     }
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
    @@ -263,7 +263,6 @@ if (empty($reshook))
     	if ($action == 'setconditions' && $user->rights->facture->creer)
     	{
     		$result=$object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
    -
     	}
     	// Set mode
     	elseif ($action == 'setmode' && $user->rights->facture->creer)
    @@ -546,7 +545,7 @@ if (empty($reshook))
     			}
     			elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
     			{
    -				require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
    +				include_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
     
     				$prodcustprice = new Productcustomerprice($db);
     
    @@ -629,12 +628,10 @@ if (empty($reshook))
     					$tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0);
     				$tmptxt .= ')';
     				$desc = dol_concatdesc($desc, $tmptxt);
    -
     			}
     
     			$type = $prod->type;
     			$fk_unit = $prod->fk_unit;
    -
     		}
     		else
     		{
    @@ -664,7 +661,7 @@ if (empty($reshook))
     		if ($tva_npr)
     			$info_bits |= 0x01;
     
    -		if (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))
    +		if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min))))
     		{
     			$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
     			setEventMessages($mesg, null, 'errors');
    @@ -744,7 +741,7 @@ if (empty($reshook))
     		}
     	}
     
    -	elseif ($action == 'updateligne' && $user->rights->facture->creer && ! GETPOST('cancel','alpha'))
    +	elseif ($action == 'updateline' && $user->rights->facture->creer && ! GETPOST('cancel','alpha'))
     	{
     		if (! $object->fetch($id) > 0)	dol_print_error($db);
     		$object->fetch_thirdparty();
    @@ -831,7 +828,7 @@ if (empty($reshook))
     			$label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
     
     			// Check price is not lower than minimum (check is done only for standard or replacement invoices)
    -			if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT) && $price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min))))
     			{
     				setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
     				$error ++;
    @@ -1113,7 +1110,7 @@ if ($action == 'create')
     		// Date next run
     		print "<tr><td>".$langs->trans('NextDateToExecution')."</td><td>";
     		$date_next_execution = isset($date_next_execution) ? $date_next_execution : (GETPOST('remonth') ? dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')) : -1);
    -		print $form->select_date($date_next_execution, '', 1, 1, '', "add", 1, 1, 1);
    +		print $form->selectDate($date_next_execution, '', 1, 1, '', "add", 1, 1);
     		print "</td></tr>";
     
     		// Number max of generation
    @@ -1626,7 +1623,7 @@ else
     		// Lines
     		print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOST('lineid')) . '" method="POST">
             	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
    -        	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
    +        	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
             	<input type="hidden" name="mode" value="">
             	<input type="hidden" name="id" value="' . $object->id . '">
             	';
    @@ -1730,10 +1727,9 @@ else
     
     
     		print '</div></div>';
    -
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/info.php b/htdocs/compta/facture/info.php
    index 8964b85203b..aff7cb362a8 100644
    --- a/htdocs/compta/facture/info.php
    +++ b/htdocs/compta/facture/info.php
    @@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
     if (! empty($conf->projet->enabled)) {
    -	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
    +	include_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
     // Load translation files required by the page
    @@ -122,5 +122,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php
    index b7b985dd73c..c61836e1b1b 100644
    --- a/htdocs/compta/facture/invoicetemplate_list.php
    +++ b/htdocs/compta/facture/invoicetemplate_list.php
    @@ -190,7 +190,6 @@ if (empty($reshook))
         $permtodelete = $user->rights->mymodule->delete;
         $uploaddir = $conf->mymodule->dir_output;
         include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';*/
    -
     }
     
     
    @@ -709,6 +708,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
    index 8e4ddc2a3eb..553c6c9028a 100644
    --- a/htdocs/compta/facture/list.php
    +++ b/htdocs/compta/facture/list.php
    @@ -148,29 +148,29 @@ if (empty($user->socid)) $fieldstosearchall["f.note_private"]="NotePrivate";
     
     $checkedtypetiers=0;
     $arrayfields=array(
    -	'f.facnumber'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
    -	'f.ref_client'=>array('label'=>$langs->trans("RefCustomer"), 'checked'=>1),
    -	'f.type'=>array('label'=>$langs->trans("Type"), 'checked'=>0),
    -	'f.date'=>array('label'=>$langs->trans("DateInvoice"), 'checked'=>1),
    -	'f.date_lim_reglement'=>array('label'=>$langs->trans("DateDue"), 'checked'=>1),
    -	'p.ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>0, 'enabled'=>(empty($conf->projet->enabled)?0:1)),
    -	's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1),
    -	's.town'=>array('label'=>$langs->trans("Town"), 'checked'=>1),
    -	's.zip'=>array('label'=>$langs->trans("Zip"), 'checked'=>1),
    -	'state.nom'=>array('label'=>$langs->trans("StateShort"), 'checked'=>0),
    -	'country.code_iso'=>array('label'=>$langs->trans("Country"), 'checked'=>0),
    -	'typent.code'=>array('label'=>$langs->trans("ThirdPartyType"), 'checked'=>$checkedtypetiers),
    -	'f.fk_mode_reglement'=>array('label'=>$langs->trans("PaymentMode"), 'checked'=>1),
    -	'f.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1),
    -	'f.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0),
    +	'f.facnumber'=>array('label'=>"Ref", 'checked'=>1),
    +	'f.ref_client'=>array('label'=>"RefCustomer", 'checked'=>1),
    +	'f.type'=>array('label'=>"Type", 'checked'=>0),
    +	'f.date'=>array('label'=>"DateInvoice", 'checked'=>1),
    +	'f.date_lim_reglement'=>array('label'=>"DateDue", 'checked'=>1),
    +	'p.ref'=>array('label'=>"ProjectRef", 'checked'=>0, 'enabled'=>(empty($conf->projet->enabled)?0:1)),
    +	's.nom'=>array('label'=>"ThirdParty", 'checked'=>1),
    +	's.town'=>array('label'=>"Town", 'checked'=>1),
    +	's.zip'=>array('label'=>"Zip", 'checked'=>1),
    +	'state.nom'=>array('label'=>"StateShort", 'checked'=>0),
    +	'country.code_iso'=>array('label'=>"Country", 'checked'=>0),
    +	'typent.code'=>array('label'=>"ThirdPartyType", 'checked'=>$checkedtypetiers),
    +	'f.fk_mode_reglement'=>array('label'=>"PaymentMode", 'checked'=>1),
    +	'f.total_ht'=>array('label'=>"AmountHT", 'checked'=>1),
    +	'f.total_vat'=>array('label'=>"AmountVAT", 'checked'=>0),
     	'f.total_localtax1'=>array('label'=>$langs->transcountry("AmountLT1", $mysoc->country_code), 'checked'=>0, 'enabled'=>($mysoc->localtax1_assuj=="1")),
     	'f.total_localtax2'=>array('label'=>$langs->transcountry("AmountLT2", $mysoc->country_code), 'checked'=>0, 'enabled'=>($mysoc->localtax2_assuj=="1")),
    -	'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0),
    -	'dynamount_payed'=>array('label'=>$langs->trans("Received"), 'checked'=>0),
    -	'rtp'=>array('label'=>$langs->trans("Rest"), 'checked'=>0),
    -	'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
    -	'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
    -	'f.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
    +	'f.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0),
    +	'dynamount_payed'=>array('label'=>"Received", 'checked'=>0),
    +	'rtp'=>array('label'=>"Rest", 'checked'=>0),
    +	'f.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
    +	'f.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500),
    +	'f.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000),
     );
     // Extra fields
     if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
    @@ -230,7 +230,6 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter','a
     	$toselect='';
     	$search_array_options=array();
     	$search_categ_cus=0;
    -
     }
     
     if (empty($reshook))
    @@ -270,7 +269,6 @@ if ($massaction == 'withdrawrequest')
     				$totalcreditnotes = $objecttmp->getSumCreditNotesUsed();
     				$totaldeposits = $objecttmp->getSumDepositsUsed();
     				$objecttmp->resteapayer = price2num($objecttmp->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits,'MT');
    -				$listofbills[] = $objecttmp;
     				if($objecttmp->paye || $objecttmp->resteapayer==0){
     					$error++;
     					setEventMessages($objecttmp->ref.' '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors');
    @@ -302,18 +300,20 @@ if ($massaction == 'withdrawrequest')
     
     				if ($numprlv>0){
     					$error++;
    -					setEventMessages($objecttmp->ref.' '.$langs->trans("RequestAlreadyDone"), $objecttmp->errors, 'errors');
    +					setEventMessages($objecttmp->ref.' '.$langs->trans("RequestAlreadyDone"), $objecttmp->errors, 'warnings');
     				}
    -				if (!empty($objecttmp->mode_reglement_code ) && $objecttmp->mode_reglement_code != 'PRE'){
    +				else if (!empty($objecttmp->mode_reglement_code ) && $objecttmp->mode_reglement_code != 'PRE'){
     					$error++;
     					setEventMessages($objecttmp->ref.' '.$langs->trans("BadPaymentMethod"), $objecttmp->errors, 'errors');
     				}
    -
    +				else {
    +					$listofbills[] = $objecttmp;    // $listofbills will only contains invoices with good payment method and no request already done
    +				}
     			}
     		}
     
    -		//Massive withdraw request
    -		if(!empty($listofbills) && empty($error))
    +		//Massive withdraw request for request with no errors
    +		if(!empty($listofbills))
     		{
     			$nbwithdrawrequestok=0;
     			foreach($listofbills as $aBill)
    @@ -338,7 +338,6 @@ if ($massaction == 'withdrawrequest')
     			}
     		}
     	}
    -
     }
     
     
    @@ -420,22 +419,14 @@ if ($filtre)
     }
     if ($search_ref) $sql .= natural_search('f.facnumber', $search_ref);
     if ($search_refcustomer) $sql .= natural_search('f.ref_client', $search_refcustomer);
    -if ($search_type != '' && $search_type >= 0)
    -{
    -	if ($search_type == '0') $sql.=" AND f.type = 0";  // standard
    -	if ($search_type == '1') $sql.=" AND f.type = 1";  // replacement
    -	if ($search_type == '2') $sql.=" AND f.type = 2";  // credit note
    -	if ($search_type == '3') $sql.=" AND f.type = 3";  // deposit
    -	if ($search_type == '4') $sql.=" AND f.type = 4";  // proforma
    -	if ($search_type == '5') $sql.=" AND f.type = 5";  // situation
    -}
    +if ($search_type != '' && $search_type != '-1') $sql.=" AND f.type IN (".$db->escape($search_type).")";
     if ($search_project) $sql .= natural_search('p.ref', $search_project);
     if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
     if ($search_town)  $sql.= natural_search('s.town', $search_town);
     if ($search_zip)   $sql.= natural_search("s.zip",$search_zip);
     if ($search_state) $sql.= natural_search("state.nom",$search_state);
    -if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')';
    -if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')';
    +if ($search_country) $sql .= " AND s.fk_pays IN (".$db->escape($search_country).')';
    +if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$db->escape($search_type_thirdparty).')';
     if ($search_company) $sql .= natural_search('s.nom', $search_company);
     if ($search_montant_ht != '') $sql.= natural_search('f.total', $search_montant_ht, 1);
     if ($search_montant_vat != '') $sql.= natural_search('f.tva', $search_montant_vat, 1);
    @@ -910,7 +901,7 @@ if ($resql)
     
     	$projectstatic=new Project($db);
     	$discount = new DiscountAbsolute($db);
    -	
    +
     	if ($num > 0)
     	{
     		$i=0;
    @@ -920,9 +911,13 @@ if ($resql)
     			$obj = $db->fetch_object($resql);
     
     			$datelimit=$db->jdate($obj->datelimite);
    +
     			$facturestatic->id=$obj->id;
     			$facturestatic->ref=$obj->ref;
     			$facturestatic->type=$obj->type;
    +            $facturestatic->total_ht=$obj->total_ht;
    +            $facturestatic->total_tva=$obj->total_vat;
    +            $facturestatic->total_ttc=$obj->total_ttc;
     			$facturestatic->statut=$obj->fk_statut;
     			$facturestatic->total_ttc=$obj->total_ttc;
                 $facturestatic->paye=$obj->paye;
    @@ -960,12 +955,10 @@ if ($resql)
     
     				print '<table class="nobordernopadding"><tr class="nocellnopadd">';
     
    -				print '<td class="nobordernopadding nowrap">';
    +				print '<td class="nobordernopadding nowraponall">';
     				print $facturestatic->getNomUrl(1,'',200,0,'',0,1);
     				print empty($obj->increment)?'':' ('.$obj->increment.')';
    -				print '</td>';
     
    -				print '<td style="min-width: 20px" class="nobordernopadding nowrap">';
     				$filename=dol_sanitizeFileName($obj->ref);
     				$filedir=$conf->facture->dir_output . '/' . dol_sanitizeFileName($obj->ref);
     				$urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->id;
    @@ -1075,11 +1068,20 @@ if ($resql)
     			if (! empty($arrayfields['typent.code']['checked']))
     			{
     				print '<td align="center">';
    -				if (count($typenArray)==0) $typenArray = $formcompany->typent_array(1);
    +				if (! is_array($typenArray) || count($typenArray)==0) $typenArray = $formcompany->typent_array(1);
     				print $typenArray[$obj->typent_code];
     				print '</td>';
     				if (! $i) $totalarray['nbfield']++;
     			}
    +			// Staff
    +			if (! empty($arrayfields['staff.code']['checked']))
    +			{
    +				print '<td align="center">';
    +				if (! is_array($staffArray) || count($staffArray)==0) $staffArray = $formcompany->effectif_array(1);
    +				print $staffArray[$obj->staff_code];
    +				print '</td>';
    +				if (! $i) $totalarray['nbfield']++;
    +			}
     
     			// Payment mode
     			if (! empty($arrayfields['f.fk_mode_reglement']['checked']))
    @@ -1224,7 +1226,6 @@ if ($resql)
     			   else print '<td></td>';
     			}
     			print '</tr>';
    -
     		}
     	}
     
    @@ -1257,5 +1258,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/facture/note.php b/htdocs/compta/facture/note.php
    index 58fc26030b7..c46d3ed690e 100644
    --- a/htdocs/compta/facture/note.php
    +++ b/htdocs/compta/facture/note.php
    @@ -142,7 +142,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php
    index ecde973bd3b..d7766268989 100644
    --- a/htdocs/compta/facture/prelevement.php
    +++ b/htdocs/compta/facture/prelevement.php
    @@ -696,6 +696,6 @@ if ($object->id > 0)
     	print '</div>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php
    index 0416e04f7b0..cbf147a8dff 100644
    --- a/htdocs/compta/facture/stats/index.php
    +++ b/htdocs/compta/facture/stats/index.php
    @@ -280,6 +280,7 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
     	print '<br><br>';
     //}
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -323,7 +324,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    -
    +print '</div>';
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     
    @@ -347,7 +348,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php
    index ea43c270b5f..692849d2fa6 100644
    --- a/htdocs/compta/index.php
    +++ b/htdocs/compta/index.php
    @@ -162,7 +162,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire)
     
     	if ( $resql )
     	{
    -		$var = false;
     		$num = $db->num_rows($resql);
     
     		print '<table class="noborder" width="100%">';
    @@ -205,7 +204,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire)
     				print '</tr>';
     				$tot_ttc+=$obj->total_ttc;
     				$i++;
    -
     			}
     
     			print '<tr class="liste_total"><td align="left">'.$langs->trans("Total").'</td>';
    @@ -350,7 +348,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire)
     	$resql = $db->query($sql);
     	if ($resql)
     	{
    -		$var=false;
     		$num = $db->num_rows($resql);
     		$i = 0;
     
    @@ -473,7 +470,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture-
     	$resql=$db->query($sql);
     	if ($resql)
     	{
    -		$var=false;
     		$num = $db->num_rows($resql);
     
     		print '<table class="noborder" width="100%">';
    @@ -520,7 +516,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture-
     				$total_ttc +=  $obj->total_ttc;
     				$totalam +=  $obj->am;
     				$i++;
    -				$var = !$var;
     			}
     		}
     		else
    @@ -600,7 +595,6 @@ if (! empty($conf->don->enabled) && $user->rights->societe->lire)
     
     				$i++;
     			}
    -
     		}
     		else
     		{
    @@ -793,7 +787,6 @@ if (! empty($conf->facture->enabled) && ! empty($conf->commande->enabled) && $us
     				//print "x".$tot_ttc."z".$obj->tot_fttc;
     				$tot_tobill += ($obj->total_ttc-$obj->tot_fttc);
     				$i++;
    -
     			}
     
     			print '<tr class="liste_total"><td colspan="2">'.$langs->trans("Total").' &nbsp; <font style="font-weight: normal">('.$langs->trans("RemainderToBill").': '.price($tot_tobill).')</font> </td>';
    @@ -1069,7 +1062,7 @@ if ($resql)
     		$obj = $db->fetch_object($resql);
     
     
    -		print "<tr ".$bc[$var]."><td>".dol_print_date($db->jdate($obj->da),"day")."</td>";
    +		print '<tr class="oddeven"><td>'.dol_print_date($db->jdate($obj->da),"day").'</td>';
     		print '<td><a href="action/card.php">'.$obj->libelle.' '.$obj->label.'</a></td></tr>';
     		$i++;
     	}
    @@ -1080,7 +1073,6 @@ if ($resql)
     
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/journal/purchasesjournal.php b/htdocs/compta/journal/purchasesjournal.php
    index 2bc754ccf11..2d43d48d778 100644
    --- a/htdocs/compta/journal/purchasesjournal.php
    +++ b/htdocs/compta/journal/purchasesjournal.php
    @@ -1,10 +1,11 @@
     <?php
    -/* Copyright (C) 2007-2010	Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010	Jean Heimburger		<jean@tiaris.info>
    - * Copyright (C) 2011-2014	Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2011-2012	Alexandre spangaro	<aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2013		Marcos García		<marcosgdf@gmail.com>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011-2014  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2011-2012  Alexandre spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2013       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -80,7 +81,8 @@ $date_end=dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
     
     if (empty($date_start) || empty($date_end)) // We define date_start and date_end
     {
    -	$date_start=dol_get_first_day($pastmonthyear,$pastmonth,false); $date_end=dol_get_last_day($pastmonthyear,$pastmonth,false);
    +    $date_start=dol_get_first_day($pastmonthyear,$pastmonth,false);
    +    $date_end=dol_get_last_day($pastmonthyear,$pastmonth,false);
     }
     
     $name=$langs->trans("PurchasesJournal");
    @@ -90,7 +92,7 @@ $builddate=dol_now();
     $description=$langs->trans("DescPurchasesJournal").'<br>';
     if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $description.= $langs->trans("DepositsAreNotIncluded");
     else  $description.= $langs->trans("DepositsAreIncluded");
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     
     report_header($name,'',$period,$periodlink,$description,$builddate,$exportlink);
     
    @@ -251,8 +253,6 @@ foreach ($tabfac as $key => $val)
     
     print "</table>";
     
    -
     // End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/journal/sellsjournal.php b/htdocs/compta/journal/sellsjournal.php
    index 24b36cf76c0..3b4be22a81d 100644
    --- a/htdocs/compta/journal/sellsjournal.php
    +++ b/htdocs/compta/journal/sellsjournal.php
    @@ -1,12 +1,13 @@
     <?php
    -/* Copyright (C) 2007-2010	Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010	Jean Heimburger		<jean@tiaris.info>
    - * Copyright (C) 2011-2014	Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2011-2012  Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2013		Marcos García		<marcosgdf@gmail.com>
    - * Copyright (C) 2014       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011-2014  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2011-2012  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2012       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2013       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -93,7 +94,7 @@ $builddate=dol_now();
     $description=$langs->trans("DescSellsJournal").'<br>';
     if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $description.= $langs->trans("DepositsAreNotIncluded");
     else  $description.= $langs->trans("DepositsAreIncluded");
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     report_header($name,'',$period,$periodlink,$description,$builddate,$exportlink);
     
     $p = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
    @@ -282,7 +283,6 @@ foreach ($tabfac as $key => $val)
     
     print "</table>";
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/localtax/card.php b/htdocs/compta/localtax/card.php
    index e8a84fcc9e1..222423b7c67 100644
    --- a/htdocs/compta/localtax/card.php
    +++ b/htdocs/compta/localtax/card.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2011-2014      Juanjo Menent <jmenent@2byte.es>
    - * Copyright (C) 2015			Marcos García <marcosgdf@gmail.com>
    +/* Copyright (C) 2011-2014  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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,11 +173,11 @@ if ($action == 'create')
     
         print "<tr>";
         print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("DatePayment").'</td><td>';
    -    print $form->select_date($datep,"datep",'','','','add',1,1);
    +    print $form->selectDate($datep, "datep", '', '', '', 'add', 1, 1);
         print '</td></tr>';
     
         print '<tr><td class="fieldrequired">'.$form->textwithpicto($langs->trans("PeriodEndDate"), $langs->trans("LastDayTaxIsRelatedTo")).'</td><td>';
    -    print $form->select_date($datev,"datev",'','','','add',1,1);
    +    print $form->selectDate($datev, "datev", '', '', '', 'add', 1, 1);
         print '</td></tr>';
     
     	// Label
    @@ -299,6 +300,6 @@ if ($id)
     	print "</div>";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    -
    diff --git a/htdocs/compta/localtax/class/localtax.class.php b/htdocs/compta/localtax/class/localtax.class.php
    index a75de537724..49c95c26c2e 100644
    --- a/htdocs/compta/localtax/class/localtax.class.php
    +++ b/htdocs/compta/localtax/class/localtax.class.php
    @@ -29,19 +29,46 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Localtax extends CommonObject
     {
    -	public $element='localtax';			//!< Id that identify managed objects
    -	public $table_element='localtax';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='localtax';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='localtax';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='payment';
     
    -	var $ltt;
    -	var $tms;
    -	var $datep;
    -	var $datev;
    -	var $amount;
    -	var $label;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    +	public $ltt;
    +	public $tms;
    +	public $datep;
    +	public $datev;
    +	public $amount;
    +
    +	/**
    +     * @var string local tax
    +     */
    +    public $label;
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_modif;
     
         /**
     	 *	Constructor
    @@ -331,6 +358,7 @@ class Localtax extends CommonObject
             return $solde;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Total de la localtax des factures emises par la societe.
          *
    @@ -339,6 +367,7 @@ class Localtax extends CommonObject
          */
         function localtax_sum_collectee($year = 0)
         {
    +        // phpcs:enable
             $sql = "SELECT sum(f.localtax) as amount";
             $sql .= " FROM ".MAIN_DB_PREFIX."facture as f WHERE f.paye = 1";
             if ($year)
    @@ -369,6 +398,7 @@ class Localtax extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	localtax payed
          *
    @@ -377,6 +407,7 @@ class Localtax extends CommonObject
          */
         function localtax_sum_payee($year = 0)
         {
    +        // phpcs:enable
     
             $sql = "SELECT sum(f.total_localtax) as total_localtax";
             $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
    @@ -409,6 +440,7 @@ class Localtax extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	localtax payed
          *  Total de la localtax payed
    @@ -418,6 +450,7 @@ class Localtax extends CommonObject
          */
         function localtax_sum_reglee($year = 0)
         {
    +        // phpcs:enable
     
             $sql = "SELECT sum(f.amount) as amount";
             $sql .= " FROM ".MAIN_DB_PREFIX."localtax as f";
    @@ -563,6 +596,7 @@ class Localtax extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Update the link betwen localtax payment and the line into llx_bank
          *
    @@ -571,6 +605,7 @@ class Localtax extends CommonObject
          */
     	function update_fk_bank($id)
     	{
    +        // phpcs:enable
     		$sql = 'UPDATE '.MAIN_DB_PREFIX.'localtax SET fk_bank = '.$id;
     		$sql.= ' WHERE rowid = '.$this->id;
     		$result = $this->db->query($sql);
    @@ -622,18 +657,19 @@ class Localtax extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoi le libelle d'un statut donne
     	 *
     	 * @param   int		$status     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  		    Libelle du statut
    +	 * @return	string              Libelle du statut
     	 */
    -	function LibStatut($status,$mode=0)
    -	{
    -		global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
    -
    -		return '';
    -	}
    +    function LibStatut($status, $mode=0)
    +    {
    +        // phpcs:enable
    +        global $langs;  // TODO Renvoyer le libelle anglais et faire traduction a affichage
     
    +        return '';
    +    }
     }
    diff --git a/htdocs/compta/localtax/clients.php b/htdocs/compta/localtax/clients.php
    index 9502ff46d2d..ff89a95414e 100644
    --- a/htdocs/compta/localtax/clients.php
    +++ b/htdocs/compta/localtax/clients.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2011-2014	Juanjo Menent 		<jmenent@2byte.es>
    - * Copyright (C) 2014	    Ferran Marcet       <fmarcet@2byte.es>
    +/* Copyright (C) 2011-2014	Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2014	    Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -117,7 +118,7 @@ if ($calc==0 || $calc==1)	// Calculate on invoice for goods and services
     {
         $calcmode=$calc==0?$langs->trans("CalcModeLT".$local):$langs->trans("CalcModeLT".$local."Rec");
         $calcmode.='<br>('.$langs->trans("TaxModuleSetupToModifyRulesLT",DOL_URL_ROOT.'/admin/company.php').')';
    -    $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +    $period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
         if (! empty($conf->global->MAIN_MODULE_COMPTABILITE)) $description.='<br>'.$langs->trans("WarningDepositsNotIncluded");
         $description.=$fsearch;
         $description.='<br>('.$langs->trans("TaxModuleSetupToModifyRulesLT",DOL_URL_ROOT.'/admin/company.php').')';
    @@ -134,7 +135,7 @@ if ($calc==2) 	// Invoice for goods, payment for services
     {
         $calcmode=$langs->trans("CalcModeLT2Debt");
         $calcmode.='<br>('.$langs->trans("TaxModuleSetupToModifyRulesLT",DOL_URL_ROOT.'/admin/company.php').')';
    -    $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +    $period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
         if (! empty($conf->global->MAIN_MODULE_COMPTABILITE)) $description.='<br>'.$langs->trans("WarningDepositsNotIncluded");
         $description.=$fsearch;
         $description.='<br>('.$langs->trans("TaxModuleSetupToModifyRulesLT",DOL_URL_ROOT.'/admin/company.php').')';
    @@ -298,7 +299,6 @@ if($calc ==0 || $calc == 1){
     		print '</tr>';
     
     		print '</table>';
    -
     	}
     	else
     	{
    @@ -321,9 +321,9 @@ if($calc ==0){
     	print '<td class="liste_total" colspan="4">'.$langs->trans("TotalToPay").($q?', '.$langs->trans("Quadri").' '.$q:'').'</td>';
     	print '<td class="liste_total nowrap" align="right"><b>'.price(price2num($diff,'MT'))."</b></td>\n";
     	print "</tr>\n";
    -
     }
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/localtax/index.php b/htdocs/compta/localtax/index.php
    index c62034ee65c..1e2c26c0c62 100644
    --- a/htdocs/compta/localtax/index.php
    +++ b/htdocs/compta/localtax/index.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2011-2014 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2014      Ferran Marcet        <fmarcet@2byte.es>
    - * Copyright (C) 2018      Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2011-2014  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2014       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -223,7 +224,7 @@ $calcmode.= '('.$langs->trans("TaxModuleSetupToModifyRulesLT",DOL_URL_ROOT.'/adm
     
     //if (! empty($conf->global->MAIN_MODULE_ACCOUNTING)) $description.='<br>'.$langs->trans("ThisIsAnEstimatedValue");
     
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     
     $builddate=dol_now();
     
    @@ -587,5 +588,6 @@ pt($db, $sql, $langs->trans("Month"));
     
     print '</div></div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/localtax/list.php b/htdocs/compta/localtax/list.php
    index 0e32a249f17..37ead35433c 100644
    --- a/htdocs/compta/localtax/list.php
    +++ b/htdocs/compta/localtax/list.php
    @@ -103,5 +103,6 @@ else
         dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/localtax/quadri_detail.php b/htdocs/compta/localtax/quadri_detail.php
    index 31729693f37..e49f42bb14f 100644
    --- a/htdocs/compta/localtax/quadri_detail.php
    +++ b/htdocs/compta/localtax/quadri_detail.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2006-2007 Yannick Warnier      <ywarnier@beeznest.org>
      * Copyright (C) 2014-2016 Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -132,18 +133,22 @@ if ($modetax == 1) $calcmode=$langs->trans('OptionVATDebitOption');
     if ($modetax == 2) $calcmode=$langs->trans('OptionPaymentForProductAndServices');
     $calcmode.='<br>('.$langs->trans("TaxModuleSetupToModifyRules",DOL_URL_ROOT.'/admin/taxes.php').')';
     // Set period
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    -$prevyear=$year_start; $prevquarter=$q;
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
    +$prevyear=$year_start;
    +$prevquarter=$q;
     if ($prevquarter > 1) {
     	$prevquarter--;
     } else {
    -	$prevquarter=4; $prevyear--;
    +    $prevquarter=4;
    +    $prevyear--;
     }
    -$nextyear=$year_start; $nextquarter=$q;
    +$nextyear=$year_start;
    +$nextquarter=$q;
     if ($nextquarter < 4) {
     	$nextquarter++;
     } else {
    -	$nextquarter=1; $nextyear++;
    +    $nextquarter=1;
    +    $nextyear++;
     }
     $description.=$fsearch;
     $builddate=dol_now();
    @@ -209,7 +214,7 @@ if (! is_array($x_coll) || ! is_array($x_paye))
     	$langs->load("errors");
     	if ($x_coll == -1)
     		print '<tr><td colspan="'.$columns.'">'.$langs->trans("ErrorNoAccountancyModuleLoaded").'</td></tr>';
    -	else if ($x_coll == -2)
    +	elseif ($x_coll == -2)
     		print '<tr><td colspan="'.$columns.'">'.$langs->trans("FeatureNotYetAvailable").'</td></tr>';
     	else
     		print '<tr><td colspan="'.$columns.'">'.$langs->trans("Error").'</td></tr>';
    @@ -640,5 +645,6 @@ else
     }
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
    index c2ce95dd827..94cd53b5424 100644
    --- a/htdocs/compta/paiement.php
    +++ b/htdocs/compta/paiement.php
    @@ -1,13 +1,14 @@
     <?php
    -/* Copyright (C) 2001-2006 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2017 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
    - * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
    - * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
    - * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2014      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) 2014      Teddy Andreotti       <125155@supinfo.com>
    - * Copyright (C) 2015      Juanjo Menent		 <jmenent@2byte.es>
    +/* Copyright (C) 2001-2006  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2007       Franky Van Liedekerke   <franky.van.liedekerke@telenet.be>
    + * Copyright (C) 2012       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2014       Teddy Andreotti         <125155@supinfo.com>
    + * Copyright (C) 2015       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -467,7 +468,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
             print '<tr><td><span class="fieldrequired">'.$langs->trans('Date').'</span></td><td>';
             $datepayment = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
             $datepayment= ($datepayment == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE)?-1:'') : $datepayment);
    -        $form->select_date($datepayment,'','','',0,"add_paiement",1,1,0,0,'','',$facture->date);
    +        print $form->selectDate($datepayment, '', '', '', 0, "add_paiement", 1, 1, 0, '', '', $facture->date);
             print '</td></tr>';
     
             // Payment mode
    @@ -525,7 +526,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
              */
     
             $sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ttc, f.type,';
    -        $sql.= ' f.datef as df, f.fk_soc as socid';
    +        $sql.= ' f.datef as df, f.fk_soc as socid, f.date_lim_reglement as dlr';
             $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
     		$sql.= ' WHERE f.entity IN ('.getEntity('facture', $conf->entity).')';
             $sql.= ' AND (f.fk_soc = '.$facture->socid;
    @@ -577,6 +578,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                     print '<tr class="liste_titre">';
                     print '<td>'.$arraytitle.'</td>';
                     print '<td align="center">'.$langs->trans('Date').'</td>';
    +                print '<td align="center">'.$langs->trans('DateMaxPayment').'</td>';
                     if (!empty($conf->multicurrency->enabled)) print '<td>'.$langs->trans('Currency').'</td>';
                     if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
                     if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$multicurrencyalreadypayedlabel.'</td>';
    @@ -628,7 +630,25 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     
                         // Date
                         print '<td align="center">'.dol_print_date($db->jdate($objp->df),'day')."</td>\n";
    -
    +                    
    +                    // Date Max Payment
    +                    if ($objp->dlr > 0 )
    +                    {
    +                        print '<td align="center">';
    +                        print dol_print_date($db->jdate($objp->dlr), 'day');
    +                        
    +                        if ($invoice->hasDelay())
    +                        {
    +                            print img_warning($langs->trans('Late'));
    +                        }
    +                        
    +                        print '</td>';
    +                    }
    +                    else
    +                    {
    +                        print '<td align="center"><b>--</b></td>';
    +                    }
    +                    
                         // Currency
                         if (!empty($conf->multicurrency->enabled)) print '<td align="center">'.$objp->multicurrency_code."</td>\n";
     
    diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php
    index 656d6c673f2..1475cfd6e45 100644
    --- a/htdocs/compta/paiement/card.php
    +++ b/htdocs/compta/paiement/card.php
    @@ -197,7 +197,6 @@ dol_fiche_head($head, 'payment', $langs->trans("PaymentCustomerInvoice"), -1, 'p
     if ($action == 'delete')
     {
     	print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete','',0,2);
    -
     }
     
     /*
    @@ -207,7 +206,6 @@ if ($action == 'valide')
     {
     	$facid = $_GET['facid'];
     	print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide','',0,2);
    -
     }
     
     $linkback = '<a href="' . DOL_URL_ROOT . '/compta/paiement/list.php">' . $langs->trans("BackToList") . '</a>';
    @@ -450,6 +448,6 @@ if ($user->societe_id == 0 && $action == '')
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php
    index 69f3bd102df..9f42ef9b16c 100644
    --- a/htdocs/compta/paiement/cheque/card.php
    +++ b/htdocs/compta/paiement/cheque/card.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2011-2016	Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2013 		Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2015-2016	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -273,7 +274,7 @@ else if ($action == 'remove_file' && $user->rights->banque->cheque)
     {
     	if ($object->fetch($id) > 0)
     	{
    -		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    +		include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
     		$langs->load("other");
     
    @@ -339,7 +340,6 @@ else
     	if ($action == 'delete')
     	{
     		print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans("DeleteCheckReceipt"), $langs->trans("ConfirmDeleteCheckReceipt"), 'confirm_delete','','',1);
    -
     	}
     
     	/*
    @@ -348,7 +348,6 @@ else
     	if ($action == 'valide')
     	{
     		print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans("ValidateCheckReceipt"), $langs->trans("ConfirmValidateCheckReceipt"), 'confirm_valide','','',1);
    -
     	}
     
     	/*
    @@ -386,7 +385,7 @@ if ($action == 'new')
     	//print '<tr><td width="30%">'.$langs->trans('Date').'</td><td width="70%">'.dol_print_date($now,'day').'</td></tr>';
     	// Filter
     	print '<tr><td class="titlefieldcreate">'.$langs->trans("DateChequeReceived").'</td><td>';
    -	print $form->select_date($filterdate,'fd',0,0,1,'',1,1,1);
    +	print $form->selectDate($filterdate, 'fd', 0, 0, 1, '', 1, 1);
     	print '</td></tr>';
         print '<tr><td>'.$langs->trans("BankAccount").'</td><td>';
         $form->select_comptes($filteraccountid,'accountid',0,'courant <> 2',1);
    @@ -552,7 +551,6 @@ if ($action == 'new')
     		print '</div><br>';
     		print '</form>';
     	}
    -
     }
     else
     {
    @@ -586,7 +584,7 @@ else
             print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
             print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
             print '<input type="hidden" name="action" value="setdate">';
    -        $form->select_date($object->date_bordereau,'datecreate_','','','',"setdate");
    +        print $form->selectDate($object->date_bordereau, 'datecreate_', '', '', '', "setdate");
             print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
             print '</form>';
         }
    @@ -786,7 +784,6 @@ if ($user->societe_id == 0 && ! empty($object->id) && $object->statut == 0 && $u
     if ($user->societe_id == 0 && ! empty($object->id) && $user->rights->banque->cheque)
     {
     	print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete&amp;sortfield='.$sortfield.'&amp;sortorder='.$sortorder.'">'.$langs->trans('Delete').'</a>';
    -
     }
     print '</div>';
     
    @@ -806,8 +803,6 @@ if ($action != 'new')
     	}
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php
    index 528b01477a6..d190beffae2 100644
    --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php
    +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php
    @@ -33,14 +33,25 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
      */
     class RemiseCheque extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='chequereceipt';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='bordereau_cheque';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'payment';
     
    -	var $num;
    -	var $intitule;
    +	public $num;
    +	public $intitule;
     	//! Numero d'erreur Plage 1024-1279
    -	var $errno;
    +	public $errno;
     
     	public $amount;
     	public $date_bordereau;
    @@ -48,6 +59,10 @@ class RemiseCheque extends CommonObject
     	public $account_label;
     	public $author_id;
     	public $nbcheque;
    +
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
     
     	/**
    @@ -106,7 +121,6 @@ class RemiseCheque extends CommonObject
     				{
     					$this->ref         = $obj->ref;
     				}
    -
     			}
     			$this->db->free($resql);
     
    @@ -137,6 +151,8 @@ class RemiseCheque extends CommonObject
     
     		$now=dol_now();
     
    +		dol_syslog("RemiseCheque::Create start", LOG_DEBUG);
    +
     		$this->db->begin();
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bordereau_cheque (";
    @@ -163,7 +179,6 @@ class RemiseCheque extends CommonObject
     		$sql.= ", ''";
     		$sql.= ")";
     
    -		dol_syslog("RemiseCheque::Create", LOG_DEBUG);
     		$resql = $this->db->query($sql);
     		if ( $resql )
     		{
    @@ -180,7 +195,6 @@ class RemiseCheque extends CommonObject
     				$sql.= " SET ref='(PROV".$this->id.")'";
     				$sql.= " WHERE rowid=".$this->id."";
     
    -				dol_syslog("RemiseCheque::Create", LOG_DEBUG);
     				$resql = $this->db->query($sql);
     				if (! $resql)
     				{
    @@ -227,13 +241,12 @@ class RemiseCheque extends CommonObject
     						if($linetoremise==$lineid) $checkremise=true;
     					}
     
    -					if($checkremise==true)
    +					if ($checkremise)
     					{
     						$sql = "UPDATE ".MAIN_DB_PREFIX."bank";
     						$sql.= " SET fk_bordereau = ".$this->id;
     						$sql.= " WHERE rowid = ".$lineid;
     
    -						dol_syslog("RemiseCheque::Create", LOG_DEBUG);
     						$resql = $this->db->query($sql);
     						if (!$resql)
     						{
    @@ -269,11 +282,13 @@ class RemiseCheque extends CommonObject
             if (! $this->errno)
             {
                 $this->db->commit();
    +            dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
                 return $this->id;
             }
             else
             {
                 $this->db->rollback();
    +            dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
                 return $this->errno;
             }
     	}
    @@ -480,6 +495,7 @@ class RemiseCheque extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -488,6 +504,7 @@ class RemiseCheque extends CommonObject
     	 */
     	function load_board($user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
    @@ -533,6 +550,7 @@ class RemiseCheque extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb de tableau de bord
     	 *
    @@ -540,6 +558,7 @@ class RemiseCheque extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $user;
     
     		if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
    @@ -593,8 +612,8 @@ class RemiseCheque extends CommonObject
     		$file = "pdf_".$model.".class.php";
     		if (file_exists($dir.$file))
     		{
    -			require_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php';
    -			require_once $dir.$file;
    +			include_once DOL_DOCUMENT_ROOT .'/compta/bank/class/account.class.php';
    +			include_once $dir.$file;
     
     			$classname='BordereauCheque'.ucfirst($model);
     			$docmodel = new $classname($this->db);
    @@ -847,13 +866,15 @@ class RemiseCheque extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Charge les proprietes ref_previous et ref_next
     	 *
    -	 *	@return     int   <0 if KO, 0 if OK
    +	 *  @return     int   <0 if KO, 0 if OK
     	 */
     	function load_previous_next_id()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$this->errno = 0;
    @@ -888,6 +909,7 @@ class RemiseCheque extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *      Set the creation date
          *
    @@ -897,6 +919,7 @@ class RemiseCheque extends CommonObject
          */
         function set_date($user, $date)
         {
    +        // phpcs:enable
             if ($user->rights->banque->cheque)
             {
                 $sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
    @@ -922,6 +945,7 @@ class RemiseCheque extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Set the ref of bordereau
     	 *
    @@ -931,6 +955,7 @@ class RemiseCheque extends CommonObject
     	 */
     	function set_number($user, $ref)
     	{
    +        // phpcs:enable
     		if ($user->rights->banque->cheque)
     		{
     			$sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
    @@ -1044,6 +1069,7 @@ class RemiseCheque extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return label of a status
     	 *
    @@ -1053,6 +1079,7 @@ class RemiseCheque extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
     		$langs->load('compta');
     		if ($mode == 0)
    @@ -1060,37 +1087,36 @@ class RemiseCheque extends CommonObject
     			if ($status == 0) return $langs->trans('ToValidate');
     			if ($status == 1) return $langs->trans('Validated');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 0) return $langs->trans('ToValidate');
     			if ($status == 1) return $langs->trans('Validated');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut0').' '.$langs->trans('ToValidate');
     			if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut0');
     			if ($status == 1) return img_picto($langs->trans('Validated'),'statut4');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 0) return img_picto($langs->trans('ToValidate'),'statut0').' '.$langs->trans('ToValidate');
     			if ($status == 1) return img_picto($langs->trans('Validated'),'statut4').' '.$langs->trans('Validated');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut0');
     			if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 0) return $langs->trans('ToValidate').' '.img_picto($langs->trans('ToValidate'),'statut0');
     			if ($status == 1) return $langs->trans('Validated').' '.img_picto($langs->trans('Validated'),'statut4');
     		}
     		return $langs->trans('Unknown');
     	}
    -
     }
    diff --git a/htdocs/compta/paiement/cheque/index.php b/htdocs/compta/paiement/cheque/index.php
    index 826a4333147..c3cf1634557 100644
    --- a/htdocs/compta/paiement/cheque/index.php
    +++ b/htdocs/compta/paiement/cheque/index.php
    @@ -24,7 +24,7 @@
      *		\brief      Home page for cheque receipts
      */
     
    -require('../../../main.inc.php');
    +require '../../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
    @@ -151,6 +151,6 @@ else
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/paiement/cheque/list.php b/htdocs/compta/paiement/cheque/list.php
    index 800f40b9694..2f0c6592694 100644
    --- a/htdocs/compta/paiement/cheque/list.php
    +++ b/htdocs/compta/paiement/cheque/list.php
    @@ -25,7 +25,7 @@
      *   \brief      Page list of cheque deposits
      */
     
    -require('../../../main.inc.php');
    +require '../../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
    @@ -250,6 +250,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/paiement/class/cpaiement.class.php b/htdocs/compta/paiement/class/cpaiement.class.php
    index 59f13023b24..26d4ea0510e 100644
    --- a/htdocs/compta/paiement/class/cpaiement.class.php
    +++ b/htdocs/compta/paiement/class/cpaiement.class.php
    @@ -34,15 +34,12 @@ class Cpaiement
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'cpaiement';
    +	
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'c_paiement';
     
    -
    -	/**
    -	 */
    -
     	public $code;
     	public $libelle;
     	public $type;
    @@ -50,9 +47,6 @@ class Cpaiement
     	public $accountancy_code;
     	public $module;
     
    -	/**
    -	 */
    -
     
     	/**
     	 * Constructor
    @@ -141,15 +135,15 @@ class Cpaiement
     		if (!$error) {
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     
    -			if (!$notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action to call a trigger.
    +			// Uncomment this and change MYOBJECT to your own tag if you
    +			// want this action to call a trigger.
    +			//if (!$notrigger) {
     
    -				//// Call triggers
    -				//$result=$this->call_trigger('MYOBJECT_CREATE',$user);
    -				//if ($result < 0) $error++;
    -				//// End call triggers
    -			}
    +			//  // Call triggers
    +			//  $result=$this->call_trigger('MYOBJECT_CREATE',$user);
    +			//  if ($result < 0) $error++;
    +			//  // End call triggers
    +			//}
     		}
     
     		// Commit or rollback
    @@ -206,8 +200,6 @@ class Cpaiement
     				$this->active = $obj->active;
     				$this->accountancy_code = $obj->accountancy_code;
     				$this->module = $obj->module;
    -
    -
     			}
     			$this->db->free($resql);
     
    @@ -284,15 +276,15 @@ class Cpaiement
     			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
     		}
     
    -		if (!$error && !$notrigger) {
    -			// Uncomment this and change MYOBJECT to your own tag if you
    -			// want this action calls a trigger.
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action calls a trigger.
    +		//if (!$error && !$notrigger) {
     
    -			//// Call triggers
    -			//$result=$this->call_trigger('MYOBJECT_MODIFY',$user);
    -			//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    -			//// End call triggers
    -		}
    +		//  // Call triggers
    +		//  $result=$this->call_trigger('MYOBJECT_MODIFY',$user);
    +		//  if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    +		//  // End call triggers
    +		//}
     
     		// Commit or rollback
     		if ($error) {
    @@ -322,17 +314,15 @@ class Cpaiement
     
     		$this->db->begin();
     
    -		if (!$error) {
    -			if (!$notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action calls a trigger.
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action calls a trigger.
    +		//if (!$error && !$notrigger) {
     
    -				//// Call triggers
    -				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
    -				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    -				//// End call triggers
    -			}
    -		}
    +		//  // Call triggers
    +		//  $result=$this->call_trigger('MYOBJECT_DELETE',$user);
    +		//  if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    +		//  // End call triggers
    +		//}
     
     		if (!$error) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
    @@ -375,8 +365,5 @@ class Cpaiement
     		$this->active = '';
     		$this->accountancy_code = '';
     		$this->module = '';
    -
    -
     	}
    -
     }
    diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
    index 539c70f591b..18dabbcf980 100644
    --- a/htdocs/compta/paiement/class/paiement.class.php
    +++ b/htdocs/compta/paiement/class/paiement.class.php
    @@ -1,12 +1,14 @@
     <?php
    -/* Copyright (C) 2002-2004 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2010 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C)      2005 Marc Barilley / Ocebo <marc@ocebo.com>
    +/* Copyright (C) 2002-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
      * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
      * Copyright (C) 2014      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2014      Marcos García 		 <marcosgdf@gmail.com>
      * Copyright (C) 2015      Juanjo Menent		 <jmenent@2byte.es>
      * Copyright (C) 2018      Ferran Marcet		 <fmarcet@2byte.es>
    + * Copyright (C) 2018      Thibault FOUCART		 <support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -36,36 +38,105 @@ require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php';
      */
     class Paiement extends CommonObject
     {
    -    public $element='payment';
    -    public $table_element='paiement';
    -    public $picto = 'payment';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='payment';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='paiement';
    +
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'payment';
    +
    +	public $facid;
    +	public $datepaye;
     
    -	var $facid;
    -	var $datepaye;
     	/**
     	 * @deprecated
     	 * @see amount, amounts
     	 */
    -    var $total;
    +    public $total;
    +
     	/**
     	 * @deprecated
     	 * @see amount, amounts
     	 */
    -	var $montant;
    -	var $amount;            // Total amount of payment
    -	var $amounts=array();   // Array of amounts
    -	var $multicurrency_amounts=array();   // Array of amounts
    -	var $author;
    -	var $paiementid;	// Type de paiement. Stocke dans fk_paiement
    +	public $montant;
    +
    +	public $amount;            // Total amount of payment
    +	public $amounts=array();   // Array of amounts
    +	public $multicurrency_amounts=array();   // Array of amounts
    +	public $author;
    +	public $paiementid;	// Type de paiement. Stocke dans fk_paiement
     	// de llx_paiement qui est lie aux types de
    -	//paiement de llx_c_paiement
    -	var $num_paiement;	// Numero du CHQ, VIR, etc...
    -	var $num_payment;	// Numero du CHQ, VIR, etc...
    -	var $bank_account;	// Id compte bancaire du paiement
    -	var $bank_line;     // Id de la ligne d'ecriture bancaire
    +    //paiement de llx_c_paiement
    +
    +    /**
    +     * @var string type libelle
    +     */
    +    public $type_libelle;
    +
    +    /**
    +     * @var string type code
    +     */
    +    public $type_code;
    +
    +    /**
    +     * @var string Numero du CHQ, VIR, etc...
    +     * @deprecated
    +     * @see num_payment
    +     */
    +    public $numero;
    +
    +    /**
    +     * @var string Numero du CHQ, VIR, etc...
    +     * @deprecated
    +     * @see num_payment
    +     */
    +    public $num_paiement;
    +
    +    /**
    +     * @var string Numero du CHQ, VIR, etc...
    +     */
    +    public $num_payment;
    +
    +    /**
    +     * @var string Id of external payment mode
    +     */
    +    public $ext_payment_id;
    +
    +    /**
    +     * @var string Name of external payment mode
    +     */
    +    public $ext_payment_site;
    +
    +    /**
    +     * @var int bank account id of payment
    +     * @deprecated
    +     */
    +    public $bank_account;
    +
    +    /**
    +     * @var int bank account id of payment
    +     */
    +    public $fk_account;
    +
    +    /**
    +     * @var int id of payment line in bank account
    +     */
    +    public $bank_line;
    +
     	// fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
    -	// fk_paiement dans llx_paiement_facture est le rowid du paiement
    -    var $fk_paiement;    // Type of paiment
    +    // fk_paiement dans llx_paiement_facture est le rowid du paiement
    +    /**
    +     * @var int payment id
    +     */
    +    public $fk_paiement;    // Type of payment
     
     
     	/**
    @@ -73,7 +144,7 @@ class Paiement extends CommonObject
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		$this->db = $db;
     	}
    @@ -86,9 +157,9 @@ class Paiement extends CommonObject
     	 *    @param	int		$fk_bank	Id of bank line associated to payment
     	 *    @return   int		            <0 if KO, 0 if not found, >0 if OK
     	 */
    -	function fetch($id, $ref='', $fk_bank='')
    +	public function fetch($id, $ref='', $fk_bank='')
     	{
    -		$sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.fk_bank,';
    +		$sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank,';
     		$sql.= ' c.code as type_code, c.libelle as type_libelle,';
     		$sql.= ' p.num_paiement as num_payment, p.note,';
     		$sql.= ' b.fk_account';
    @@ -121,6 +192,8 @@ class Paiement extends CommonObject
     				$this->type_libelle   = $obj->type_libelle;
     				$this->type_code      = $obj->type_code;
     				$this->statut         = $obj->statut;
    +                $this->ext_payment_id = $obj->ext_payment_id;
    +                $this->ext_payment_site = $obj->ext_payment_site;
     
     				$this->bank_account   = $obj->fk_account; // deprecated
     				$this->fk_account     = $obj->fk_account;
    @@ -215,8 +288,8 @@ class Paiement extends CommonObject
     		}
     		$note = ($this->note_public?$this->note_public:$this->note);
     
    -		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, fk_user_creat)";
    -		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', ".$user->id.")";
    +		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
    +		$sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($this->num_paiement)."', '".$this->db->escape($note)."', ".($this->ext_payment_id?"'".$this->db->escape($this->ext_payment_id)."'":"null").", ".($this->ext_payment_site?"'".$this->db->escape($this->ext_payment_site)."'":"null").", ".$user->id.")";
     
     		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
     		$resql = $this->db->query($sql);
    @@ -545,7 +618,7 @@ class Paiement extends CommonObject
     
             	$this->fk_account=$accountid;
     
    -        	require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
    +        	include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
                 dol_syslog("$user->id,$mode,$label,$this->fk_account,$emetteur_nom,$emetteur_banque");
     
    @@ -694,6 +767,7 @@ class Paiement extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Mise a jour du lien entre le paiement et la ligne generee dans llx_bank
     	 *
    @@ -702,6 +776,7 @@ class Paiement extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' set fk_bank = '.$id_bank;
     		$sql.= ' WHERE rowid = '.$this->id;
     
    @@ -719,6 +794,7 @@ class Paiement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Updates the payment date
          *
    @@ -727,6 +803,7 @@ class Paiement extends CommonObject
          */
         function update_date($date)
         {
    +        // phpcs:enable
             if (!empty($date) && $this->statut!=1)
             {
                 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
    @@ -750,6 +827,7 @@ class Paiement extends CommonObject
             return -1; //no date given or already validated
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Updates the payment number
          *
    @@ -758,6 +836,7 @@ class Paiement extends CommonObject
          */
         function update_num($num)
         {
    +        // phpcs:enable
         	if(!empty($num) && $this->statut!=1)
             {
                 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
    @@ -1064,7 +1143,7 @@ class Paiement extends CommonObject
                 $arraybill = $this->getBillsArray();
                 if (is_array($arraybill) && count($arraybill) > 0)
                 {
    -            	require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    +            	include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
                 	$facturestatic=new Facture($this->db);
                 	foreach ($arraybill as $billid)
                 	{
    @@ -1112,6 +1191,7 @@ class Paiement extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoi le libelle d'un statut donne
     	 *
    @@ -1121,6 +1201,7 @@ class Paiement extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
     
     		$langs->load('compta');
    @@ -1162,15 +1243,17 @@ class Paiement extends CommonObject
     		return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *    	Load the third party of object, from id into this->thirdparty
    +	 *  Load the third party of object, from id into this->thirdparty
     	 *
    -	 *		@param		int		$force_thirdparty_id	Force thirdparty id
    -	 *		@return		int								<0 if KO, >0 if OK
    +	 *	@param		int		$force_thirdparty_id	Force thirdparty id
    +	 *	@return		int								<0 if KO, >0 if OK
     	 */
     	function fetch_thirdparty($force_thirdparty_id=0)
     	{
    -		require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
    +        // phpcs:enable
    +		include_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
     
     		if (empty($force_thirdparty_id))
     		{
    diff --git a/htdocs/compta/paiement/index.php b/htdocs/compta/paiement/index.php
    index 7f1597b5afc..5bcda011615 100644
    --- a/htdocs/compta/paiement/index.php
    +++ b/htdocs/compta/paiement/index.php
    @@ -31,5 +31,6 @@ llxHeader();
     
     print load_fiche_titre("Payments");
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/paiement/info.php b/htdocs/compta/paiement/info.php
    index 9f55761dba0..86e45508b2c 100644
    --- a/htdocs/compta/paiement/info.php
    +++ b/htdocs/compta/paiement/info.php
    @@ -76,5 +76,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php
    index 064ca877c3f..5b5124b2b80 100644
    --- a/htdocs/compta/paiement/list.php
    +++ b/htdocs/compta/paiement/list.php
    @@ -371,5 +371,6 @@ else
         dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php
    index 3e6427f6ac2..c2c63aea84d 100644
    --- a/htdocs/compta/paiement/rapport.php
    +++ b/htdocs/compta/paiement/rapport.php
    @@ -166,6 +166,6 @@ if ($year)
         }
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/paiement/tovalidate.php b/htdocs/compta/paiement/tovalidate.php
    index e60f65f924e..9fea9afa5df 100644
    --- a/htdocs/compta/paiement/tovalidate.php
    +++ b/htdocs/compta/paiement/tovalidate.php
    @@ -139,5 +139,6 @@ if ($resql)
         print "</table>";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/paiement_charge.php b/htdocs/compta/paiement_charge.php
    index fba8723d818..38cee6b8434 100644
    --- a/htdocs/compta/paiement_charge.php
    +++ b/htdocs/compta/paiement_charge.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2016      Frédéric France      <frederic.france@free.fr>
    +/* Copyright (C) 2004-2014  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2016-2018  Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -17,9 +17,9 @@
      */
     
     /**
    - *	    \file       htdocs/compta/paiement_charge.php
    - *		\ingroup    tax
    - *		\brief      Page to add payment of a tax
    + *      \file       htdocs/compta/paiement_charge.php
    + *      \ingroup    tax
    + *      \brief      Page to add payment of a tax
      */
     
     require '../main.inc.php';
    @@ -147,7 +147,6 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm=='yes
                 }
             }
     	}
    -
     }
     
     
    @@ -226,7 +225,7 @@ if ($action == 'create')
     	print '<tr><td class="fieldrequired">'.$langs->trans("Date").'</td><td>';
     	$datepaye = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
     	$datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaye):0;
    -	$form->select_date($datepayment,'','','','',"add_payment",1,1);
    +	print $form->selectDate($datepayment, '', '', '', '', "add_payment", 1, 1);
     	print "</td>";
     	print '</tr>';
     
    diff --git a/htdocs/compta/payment_sc/card.php b/htdocs/compta/payment_sc/card.php
    index b395016aeed..12cd2a0aa0e 100644
    --- a/htdocs/compta/payment_sc/card.php
    +++ b/htdocs/compta/payment_sc/card.php
    @@ -74,7 +74,8 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->tax->char
     	}
     }
     
    -// Create payment
    +// Validate social contribution
    +/*
     if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->tax->charges->creer)
     {
     	$db->begin();
    @@ -111,6 +112,7 @@ if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->tax->char
     		$db->rollback();
     	}
     }
    +*/
     
     
     /*
    @@ -144,18 +146,19 @@ dol_fiche_head($head, $hselected, $langs->trans("PaymentSocialContribution"), -1
     if ($action == 'delete')
     {
     	print $form->formconfirm('card.php?id='.$object->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete','',0,2);
    -
     }
     
     /*
      * Validation confirmation of payment
      */
    +/*
     if ($action == 'valide')
     {
     	$facid = $_GET['facid'];
     	print $form->formconfirm('card.php?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide','',0,2);
     
     }
    +*/
     
     
     $linkback = '<a href="' . DOL_URL_ROOT . '/compta/sociales/payments.php">' . $langs->trans("BackToList") . '</a>';
    @@ -323,8 +326,6 @@ if ($action == '')
     
     print '</div>';
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/prelevement/bons.php b/htdocs/compta/prelevement/bons.php
    index 0cbaa9ce55e..a6d1f480a06 100644
    --- a/htdocs/compta/prelevement/bons.php
    +++ b/htdocs/compta/prelevement/bons.php
    @@ -24,7 +24,7 @@
      * 	\brief      Page liste des bons de prelevements
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
    @@ -183,7 +183,6 @@ else
       dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php
    index 343a45472b6..60e471d712d 100644
    --- a/htdocs/compta/prelevement/card.php
    +++ b/htdocs/compta/prelevement/card.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2005      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2005-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2010-2016 Juanjo Menent 		<jmenent@2byte.es>
    +/* Copyright (C) 2005       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2005-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2010-2016  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -23,22 +24,18 @@
      *	\brief      Card of a direct debit
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/prelevement.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array('banks', 'categories'));
    +$langs->loadLangs(array('banks', 'categories','bills','withdrawals'));
     
     if (!$user->rights->prelevement->bons->lire)
     accessforbidden();
     
    -$langs->load("bills");
    -$langs->load("withdrawals");
    -
    -
     // Security check
     if ($user->societe_id > 0) accessforbidden();
     
    @@ -244,7 +241,7 @@ if ($id > 0 || $ref)
     		print '<tr class="liste_titre">';
     		print '<td colspan="3">'.$langs->trans("NotifyTransmision").'</td></tr>';
     		print '<tr class="oddeven"><td>'.$langs->trans("TransData").'</td><td>';
    -		print $form->select_date('','','','','',"userfile",1,1);
    +		print $form->selectDate('', '', '', '', '', "userfile", 1, 1);
     		print '</td></tr>';
     		print '<tr class="oddeven"><td>'.$langs->trans("TransMetod").'</td><td>';
     		print $form->selectarray("methode",$object->methodes_trans);
    @@ -268,7 +265,7 @@ if ($id > 0 || $ref)
     		print '<tr class="liste_titre">';
     		print '<td colspan="3">'.$langs->trans("NotifyCredit").'</td></tr>';
     		print '<tr class="oddeven"><td>'.$langs->trans('CreditDate').'</td><td>';
    -		print $form->select_date('','','','','',"infocredit",1,1);
    +		print $form->selectDate('', '', '', '', '', "infocredit", 1, 1);
     		print '</td></tr>';
     		print '</table>';
     		print '<br>'.$langs->trans("ThisWillAlsoAddPaymentOnInvoice");
    @@ -419,6 +416,6 @@ if ($id > 0 || $ref)
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php
    index 245b25be3b6..9d2b828b3eb 100644
    --- a/htdocs/compta/prelevement/class/bonprelevement.class.php
    +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php
    @@ -39,29 +39,40 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
      */
     class BonPrelevement extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='widthdraw';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='prelevement_bons';
    -	public $picto = 'payment';
     
    -	var $date_echeance;
    -	var $raison_sociale;
    -	var $reference_remise;
    -	var $emetteur_code_guichet;
    -	var $emetteur_numero_compte;
    -	var $emetteur_code_banque;
    -	var $emetteur_number_key;
    +    /**
    +     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +     */
    +    public $picto = 'payment';
     
    -	var $emetteur_iban;
    -	var $emetteur_bic;
    -	var $emetteur_ics;
    +	public $date_echeance;
    +	public $raison_sociale;
    +	public $reference_remise;
    +	public $emetteur_code_guichet;
    +	public $emetteur_numero_compte;
    +	public $emetteur_code_banque;
    +	public $emetteur_number_key;
     
    -	var $total;
    -	var $_fetched;
    -	var $statut;    // 0-Wait, 1-Trans, 2-Done
    -	var $labelstatut=array();
    +	public $emetteur_iban;
    +	public $emetteur_bic;
    +	public $emetteur_ics;
     
    -	var $invoice_in_error=array();
    -	var $thirdparty_in_error=array();
    +	public $total;
    +	public $fetched;
    +	public $statut;    // 0-Wait, 1-Trans, 2-Done
    +	public $labelstatut=array();
    +
    +	public $invoice_in_error=array();
    +	public $thirdparty_in_error=array();
     
     
     	/**
    @@ -98,9 +109,10 @@ class BonPrelevement extends CommonObject
     
     		$this->methodes_trans[0] = "Internet";
     
    -		$this->_fetched = 0;
    +		$this->fetched = 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Add invoice to withdrawal
     	 *
    @@ -116,6 +128,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function AddFacture($facture_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key)
     	{
    +        // phpcs:enable
     		$result = 0;
     		$line_id = 0;
     
    @@ -156,7 +169,6 @@ class BonPrelevement extends CommonObject
     		}
     
     		return $result;
    -
     	}
     
     	/**
    @@ -235,7 +247,6 @@ class BonPrelevement extends CommonObject
     				dol_syslog(get_class($this)."::addline Error -2");
     				$result = -2;
     			}
    -
     		}
     
     		return $result;
    @@ -304,7 +315,7 @@ class BonPrelevement extends CommonObject
     
     				$this->statut             = $obj->statut;
     
    -				$this->_fetched = 1;
    +				$this->fetched = 1;
     
     				return 1;
     			}
    @@ -320,6 +331,7 @@ class BonPrelevement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set credite and set status of linked invoices. Still used ??
     	 *
    @@ -327,6 +339,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function set_credite()
     	{
    +        // phpcs:enable
     		global $user,$conf;
     
     		$error = 0;
    @@ -397,6 +410,7 @@ class BonPrelevement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set direct debit order to "credited" status.
     	 *
    @@ -406,11 +420,12 @@ class BonPrelevement extends CommonObject
     	 */
     	function set_infocredit($user, $date)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$error = 0;
     
    -		if ($this->_fetched == 1)
    +		if ($this->fetched == 1)
     		{
     			if ($date >= $this->date_trans)
     			{
    @@ -499,7 +514,6 @@ class BonPrelevement extends CommonObject
     							dol_syslog(get_class($this)."::set_infocredit Update lines Error");
     							$error++;
     						}
    -
     					}
     					else
     					{
    @@ -543,6 +557,7 @@ class BonPrelevement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set withdrawal to transmited status
     	 *
    @@ -553,6 +568,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function set_infotrans($user, $date, $method)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$error = 0;
    @@ -667,6 +683,7 @@ class BonPrelevement extends CommonObject
     		return $arr;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Returns amount of withdrawal
     	 *
    @@ -674,6 +691,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function SommeAPrelever()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sql = "SELECT sum(pfd.amount) as nb";
    @@ -704,6 +722,7 @@ class BonPrelevement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Get number of invoices to withdrawal
     	 *	TODO delete params banque and agence when not necesary
    @@ -714,6 +733,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function NbFactureAPrelever($banque=0,$agence=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sql = "SELECT count(f.rowid) as nb";
    @@ -745,6 +765,7 @@ class BonPrelevement extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a withdraw
     	 *  TODO delete params banque and agence when not necesary
    @@ -758,20 +779,21 @@ class BonPrelevement extends CommonObject
     	 */
     	function Create($banque=0, $agence=0, $mode='real', $format='ALL',$executiondate='')
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		dol_syslog(__METHOD__."::Bank=".$banque." Office=".$agence." mode=".$mode." format=".$format, LOG_DEBUG);
     
    -		require_once (DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    -		require_once (DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    +		require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
    +		require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
     
     		if (empty($format)) return 'ErrorBadParametersForDirectDebitFileCreate';
     
     		$error = 0;
     
     		$datetimeprev = time();
    -                //Choice the date of the execution direct debit
    -                if(!empty($executiondate)) $datetimeprev = $executiondate;
    +        //Choice the date of the execution direct debit
    +        if(!empty($executiondate)) $datetimeprev = $executiondate;
     
     		$month = strftime("%m", $datetimeprev);
     		$year = strftime("%Y", $datetimeprev);
    @@ -1034,10 +1056,8 @@ class BonPrelevement extends CommonObject
     							$error++;
     							dol_syslog(__METHOD__."::Update Orders::Error=".$this->db->error(), LOG_ERR);
     						}
    -
     					}
     				}
    -
     			}
     
     			if (!$error)
    @@ -1180,6 +1200,7 @@ class BonPrelevement extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Delete a notification def by id
     	 *
    @@ -1188,6 +1209,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function DeleteNotificationById($rowid)
     	{
    +        // phpcs:enable
     		$result = 0;
     
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."notify_def";
    @@ -1203,6 +1225,7 @@ class BonPrelevement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Delete a notification
     	 *
    @@ -1212,6 +1235,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function DeleteNotification($user, $action)
     	{
    +        // phpcs:enable
     		$result = 0;
     
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."notify_def";
    @@ -1227,6 +1251,7 @@ class BonPrelevement extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Add a notification
     	 *
    @@ -1237,6 +1262,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function AddNotification($db, $user, $action)
     	{
    +        // phpcs:enable
     		$result = 0;
     
     		if ($this->DeleteNotification($user, $action) == 0)
    @@ -1449,10 +1475,10 @@ class BonPrelevement extends CommonObject
     		if (! empty($conf->global->MAIN_UMASK))
     		@chmod($this->file, octdec($conf->global->MAIN_UMASK));
     		return $result;
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Write recipient of request (customer)
     	 *
    @@ -1469,6 +1495,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $facnumber, $facid, $rib_dom='')
     	{
    +        // phpcs:enable
     		fputs($this->file, "06");
     		fputs($this->file, "08"); // Prelevement ordinaire
     
    @@ -1539,6 +1566,7 @@ class BonPrelevement extends CommonObject
     		return $pre.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Write recipient of request (customer)
     	 *
    @@ -1562,6 +1590,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_facnumber, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum)
     	{
    +        // phpcs:enable
     		$CrLf = "\n";
     		$Rowing = sprintf("%06d", $row_idfac);
     
    @@ -1575,7 +1604,8 @@ class BonPrelevement extends CommonObject
     		$XML_DEBITOR ='';
     		$XML_DEBITOR .='			<DrctDbtTxInf>'.$CrLf;
     		$XML_DEBITOR .='				<PmtId>'.$CrLf;
    -		$XML_DEBITOR .='					<EndToEndId>'.('AS-'.dol_trunc($row_facnumber,20).'-'.$Rowing).'</EndToEndId>'.$CrLf;          // ISO20022 states that EndToEndId has a MaxLength of 35 characters
    +	//	$XML_DEBITOR .='					<EndToEndId>'.('AS-'.dol_trunc($row_facnumber,20).'-'.$Rowing).'</EndToEndId>'.$CrLf;          // ISO20022 states that EndToEndId has a MaxLength of 35 characters
    +		$XML_DEBITOR .='					<EndToEndId>'.(($conf->global->END_TO_END != "" ) ? $conf->global->END_TO_END : ('AS-'.dol_trunc($row_facnumber,20)).'-'.$Rowing).'</EndToEndId>'.$CrLf;          // ISO20022 states that EndToEndId has a MaxLength of 35 characters
     		$XML_DEBITOR .='				</PmtId>'.$CrLf;
     		$XML_DEBITOR .='				<InstdAmt Ccy="EUR">'.round($row_somme, 2).'</InstdAmt>'.$CrLf;
     		$XML_DEBITOR .='				<DrctDbtTx>'.$CrLf;
    @@ -1607,13 +1637,15 @@ class BonPrelevement extends CommonObject
     		$XML_DEBITOR .='				</DbtrAcct>'.$CrLf;
     		$XML_DEBITOR .='				<RmtInf>'.$CrLf;
     	//	$XML_DEBITOR .='					<Ustrd>'.($row_facnumber.'/'.$Rowing.'/'.$Rum).'</Ustrd>'.$CrLf;
    -		$XML_DEBITOR .='					<Ustrd>'.dol_trunc($row_facnumber, 135).'</Ustrd>'.$CrLf;        // 140 max
    +	//	$XML_DEBITOR .='					<Ustrd>'.dol_trunc($row_facnumber, 135).'</Ustrd>'.$CrLf;        // 140 max
    +		$XML_DEBITOR .='					<Ustrd>'.(($conf->global->USTRD != "" ) ? $conf->global->USTRD : dol_trunc($row_facnumber, 135) ).'</Ustrd>'.$CrLf;        // 140 max
     		$XML_DEBITOR .='				</RmtInf>'.$CrLf;
     		$XML_DEBITOR .='			</DrctDbtTxInf>'.$CrLf;
     		return $XML_DEBITOR;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Write sender of request (me)
     	 *
    @@ -1621,6 +1653,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function EnregEmetteur()
     	{
    +        // phpcs:enable
     		fputs($this->file, "03");
     		fputs($this->file, "08"); // Prelevement ordinaire
     
    @@ -1677,9 +1710,9 @@ class BonPrelevement extends CommonObject
     		fputs($this->file, substr("                                        ",0,5));
     
     		fputs($this->file, "\n");
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Write sender of request (me).
     	 *  Note: The tag PmtInf is opened here but closed into caller
    @@ -1694,6 +1727,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf='\n', $format='FRST')
     	{
    +        // phpcs:enable
     		// SEPA INITIALISATION
     		global $conf;
     
    @@ -1801,6 +1835,7 @@ class BonPrelevement extends CommonObject
     		return $XML_SEPA_INFO;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Write end
     	 *
    @@ -1809,6 +1844,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function EnregTotal($total)
     	{
    +        // phpcs:enable
     		fputs($this->file, "08");
     		fputs($this->file, "08"); // Prelevement ordinaire
     
    @@ -1873,6 +1909,7 @@ class BonPrelevement extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return status label for a status
     	 *
    @@ -1882,6 +1919,7 @@ class BonPrelevement extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		if (empty($this->labelstatut))
     		{
     			global $langs;
    @@ -1891,45 +1929,39 @@ class BonPrelevement extends CommonObject
     			$this->labelstatut[2]=$langs->trans("StatusCredited");
     		}
     
    -		if ($mode == 0)
    +		if ($mode == 0 || $mode == 1)
     		{
     			return $this->labelstatut[$statut];
     		}
    -		if ($mode == 1)
    -		{
    -			return $this->labelstatut[$statut];
    -		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($this->labelstatut[$statut],'statut1').' '.$this->labelstatut[$statut];
     			if ($statut==1) return img_picto($this->labelstatut[$statut],'statut3').' '.$this->labelstatut[$statut];
     			if ($statut==2) return img_picto($this->labelstatut[$statut],'statut6').' '.$this->labelstatut[$statut];
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0) return img_picto($this->labelstatut[$statut],'statut1');
     			if ($statut==1) return img_picto($this->labelstatut[$statut],'statut3');
     			if ($statut==2) return img_picto($this->labelstatut[$statut],'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0) return img_picto($this->labelstatut[$statut],'statut1').' '.$this->labelstatut[$statut];
     			if ($statut==1) return img_picto($this->labelstatut[$statut],'statut3').' '.$this->labelstatut[$statut];
     			if ($statut==2) return img_picto($this->labelstatut[$statut],'statut6').' '.$this->labelstatut[$statut];
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut==0) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut1');
     			if ($statut==1) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut3');
     			if ($statut==2) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut6');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($statut==0) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut1');
     			if ($statut==1) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut3');
     			if ($statut==2) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut6');
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/compta/prelevement/class/ligneprelevement.class.php b/htdocs/compta/prelevement/class/ligneprelevement.class.php
    index fa8545c4ea2..d8434caefd8 100644
    --- a/htdocs/compta/prelevement/class/ligneprelevement.class.php
    +++ b/htdocs/compta/prelevement/class/ligneprelevement.class.php
    @@ -31,8 +31,15 @@
      */
     class LignePrelevement
     {
    -	var $id;
    -	var $db;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $statuts = array();
     
    @@ -121,6 +128,7 @@ class LignePrelevement
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return status label for a status
     	 *
    @@ -130,25 +138,26 @@ class LignePrelevement
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]);   // Waiting
     			if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);   // Credited
     			if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut8').' '.$langs->trans($this->statuts[$statut]);   // Refused
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut1');
     			if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut6');
     			if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut8');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut1');
     			if ($statut==2) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut6');
    @@ -173,4 +182,3 @@ class LignePrelevement
     		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
     	}
     }
    -
    diff --git a/htdocs/compta/prelevement/class/rejetprelevement.class.php b/htdocs/compta/prelevement/class/rejetprelevement.class.php
    index 87de138e63a..ebe76a6aab3 100644
    --- a/htdocs/compta/prelevement/class/rejetprelevement.class.php
    +++ b/htdocs/compta/prelevement/class/rejetprelevement.class.php
    @@ -30,8 +30,15 @@
      */
     class RejetPrelevement
     {
    -	var $id;
    -	var $db;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
     	/**
    @@ -62,7 +69,6 @@ class RejetPrelevement
     
         	$this->facturer[0]=$langs->trans("NoInvoiceRefused");
     		$this->facturer[1]=$langs->trans("InvoiceRefused");
    -
     	}
     
     	/**
    @@ -169,7 +175,6 @@ class RejetPrelevement
     					$error++;
     					dol_syslog("RejetPrelevement::Create Error payment validation");
     				}
    -
     			}
     			//Tag invoice as unpaid
     			dol_syslog("RejetPrelevement::Create set_unpaid fac ".$fac->ref);
    @@ -191,9 +196,9 @@ class RejetPrelevement
     			dol_syslog("RejetPrelevement::Create Rollback");
     			$this->db->rollback();
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Send email to all users that has asked the withdraw request
     	 *
    @@ -202,6 +207,7 @@ class RejetPrelevement
     	 */
     	function _send_email($fac)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$userid = 0;
    @@ -320,7 +326,6 @@ class RejetPrelevement
     		}
     
     		return $arr;
    -
     	}
     
     	/**
    @@ -364,6 +369,4 @@ class RejetPrelevement
     			return -2;
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php
    index 9cc2cf77867..dff5ab39f3d 100644
    --- a/htdocs/compta/prelevement/create.php
    +++ b/htdocs/compta/prelevement/create.php
    @@ -1,9 +1,10 @@
     <?php
    -/* Copyright (C) 2005      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2010-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2010-2012 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2018      Nicolas ZABOURI      <info@inovea-conseil.com>
    +/* Copyright (C) 2005       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2010-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2010-2012  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Nicolas ZABOURI         <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -25,7 +26,7 @@
      *	\brief      Prelevement creation page
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
    @@ -45,7 +46,7 @@ $result = restrictedArea($user, 'prelevement', '', '', 'bons');
     $action = GETPOST('action','alpha');
     $mode = GETPOST('mode','alpha')?GETPOST('mode','alpha'):'real';
     $format = GETPOST('format','aZ09');
    -$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
     $page = GETPOST("page",'int');
     if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
     $offset = $limit * $page;
    @@ -153,14 +154,13 @@ print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">'
     if ($nb) {
         if ($pricetowithdraw) {
             print $langs->trans('ExecutionDate').' ';
    -        print $form->select_date();
    +        print $form->selectDate();
             if ($mysoc->isInEEC()) {
                 print '<select name="format"><option value="FRST">'.$langs->trans('SEPAFRST').'</option><option value="RCUR">'.$langs->trans('SEPARCUR').'</option></select>';
                 print '<input class="butAction" type="submit" value="' . $langs->trans("CreateForSepa") . '"/>';
             } else {
                 print '<a class="butAction"  type="submit" href="create.php?action=create&format=ALL">' . $langs->trans("CreateAll") . "</a>\n";
     		}
    -
     		}
     		else
     		{
    @@ -348,5 +348,6 @@ else
     }
     */
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php
    index d20f92cb188..10c390ed5bd 100644
    --- a/htdocs/compta/prelevement/demandes.php
    +++ b/htdocs/compta/prelevement/demandes.php
    @@ -24,7 +24,7 @@
      *  \brief      Page to list withdraw requests
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/modules/modPrelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
    @@ -167,5 +167,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php
    index 2eabd64873d..a53db70544b 100644
    --- a/htdocs/compta/prelevement/factures.php
    +++ b/htdocs/compta/prelevement/factures.php
    @@ -24,7 +24,7 @@
      *     \brief      Page liste des factures prelevees
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/prelevement.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/rejetprelevement.class.php';
    @@ -134,7 +134,6 @@ if ($prev_id > 0 || $ref)
     		print '</div>';
     
     		dol_fiche_end();
    -
         }
       	else
         {
    @@ -296,7 +295,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php
    index 113153bc896..7cb862389d7 100644
    --- a/htdocs/compta/prelevement/fiche-rejet.php
    +++ b/htdocs/compta/prelevement/fiche-rejet.php
    @@ -24,7 +24,7 @@
      *		\brief      Withdraw reject
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/prelevement.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/rejetprelevement.class.php';
    @@ -135,7 +135,6 @@ if ($prev_id > 0 || $ref)
     		print '</div>';
     
     		dol_fiche_end();
    -
         }
       	else
         {
    @@ -245,5 +244,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php
    index c126212f17c..731bc1dc81d 100644
    --- a/htdocs/compta/prelevement/fiche-stat.php
    +++ b/htdocs/compta/prelevement/fiche-stat.php
    @@ -23,7 +23,7 @@
      *	\brief      Prelevement statistics
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/prelevement.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
    @@ -132,7 +132,6 @@ if ($prev_id > 0 || $ref)
     		print '</div>';
     
     		dol_fiche_end();
    -
     	}
     	else
     	{
    @@ -193,5 +192,6 @@ if ($prev_id > 0 || $ref)
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/prelevement/index.php b/htdocs/compta/prelevement/index.php
    index de99b56eb19..673b83d15aa 100644
    --- a/htdocs/compta/prelevement/index.php
    +++ b/htdocs/compta/prelevement/index.php
    @@ -26,7 +26,7 @@
      */
     
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
    @@ -221,6 +221,6 @@ else
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/prelevement/ligne.php b/htdocs/compta/prelevement/ligne.php
    index 721cf62bcd7..30cc21ae977 100644
    --- a/htdocs/compta/prelevement/ligne.php
    +++ b/htdocs/compta/prelevement/ligne.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2005      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2005-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2010-2013 Juanjo Menent        <jmenent@2byte.es>
    +/* Copyright (C) 2005       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2005-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2010-2013  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -24,7 +25,7 @@
      *	\brief      card of withdraw line
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/rejetprelevement.class.php';
    @@ -88,7 +89,6 @@ if ($action == 'confirm_rejet')
     				header("Location: ligne.php?id=".$id);
     				exit;
     			}
    -
     		}
     		else
     		{
    @@ -196,7 +196,7 @@ if ($id)
     		//Date
     		print '<tr><td class="fieldrequired valid">'.$langs->trans("RefusedData").'</td>';
     		print '<td colspan="2" class="valid">';
    -		print $form->select_date('','','','','',"confirm_rejet");
    +		print $form->selectDate('', '', '', '', '', "confirm_rejet");
     		print '</td></tr>';
     
     		//Reason
    @@ -334,6 +334,6 @@ if ($id)
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/prelevement/list.php b/htdocs/compta/prelevement/list.php
    index 8d657f00221..ead1bfff08f 100644
    --- a/htdocs/compta/prelevement/list.php
    +++ b/htdocs/compta/prelevement/list.php
    @@ -24,7 +24,7 @@
      *      \brief      Page liste des prelevements
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
    @@ -213,5 +213,6 @@ else
         dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/prelevement/rejets.php b/htdocs/compta/prelevement/rejets.php
    index c8812bba1a9..5c38b29954e 100644
    --- a/htdocs/compta/prelevement/rejets.php
    +++ b/htdocs/compta/prelevement/rejets.php
    @@ -24,7 +24,7 @@
      *      \brief      Reject page
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/rejetprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
    @@ -120,5 +120,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/prelevement/stats.php b/htdocs/compta/prelevement/stats.php
    index 20d213e820b..ab233a61be3 100644
    --- a/htdocs/compta/prelevement/stats.php
    +++ b/htdocs/compta/prelevement/stats.php
    @@ -24,7 +24,7 @@
      *      \brief      Page with statistics on withdrawals
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
    @@ -225,7 +225,7 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
    diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php
    index c9e32b9a97f..4d643536388 100644
    --- a/htdocs/compta/resultat/clientfourn.php
    +++ b/htdocs/compta/resultat/clientfourn.php
    @@ -1,12 +1,13 @@
     <?php
    -/* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2012      Cédric Salvador      <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2012-2014 Raphaël Dourseanud   <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) 2014-2106 Ferran Marcet        <fmarcet@2byte.es>
    - * Copyright (C) 2014	   Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2014	   Florian Henry        <florian.henry@open-concept.pro>
    +/* Copyright (C) 2002-2006  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2012-2014  Raphaël Dourseanud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2014-2106  Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2014       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2014       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -161,7 +162,7 @@ if ($modecompta=="CREANCES-DETTES")
     	$calcmode=$langs->trans("CalcModeDebt");
         $calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?date_startyear='.$tmps['year'].'&date_startmonth='.$tmps['mon'].'&date_startday='.$tmps['mday'].'&date_endyear='.$tmpe['year'].'&date_endmonth='.$tmpe['mon'].'&date_endday='.$tmpe['mday'].'&modecompta=RECETTES-DEPENSES">','</a>').')';
         if (! empty($conf->accounting->enabled)) $calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?date_startyear='.$tmps['year'].'&date_startmonth='.$tmps['mon'].'&date_startday='.$tmps['mday'].'&date_endyear='.$tmpe['year'].'&date_endmonth='.$tmpe['mon'].'&date_endday='.$tmpe['mday'].'&modecompta=BOOKKEEPING">','</a>').')';
    -    $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +    $period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']-1)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']+1)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
         $description=$langs->trans("RulesResultDue");
     	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $description.= $langs->trans("DepositsAreNotIncluded");
    @@ -175,9 +176,8 @@ elseif ($modecompta=="RECETTES-DEPENSES")
     	$calcmode=$langs->trans("CalcModeEngagement");
         $calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?date_startyear='.$tmps['year'].'&date_startmonth='.$tmps['mon'].'&date_startday='.$tmps['mday'].'&date_endyear='.$tmpe['year'].'&date_endmonth='.$tmpe['mon'].'&date_endday='.$tmpe['mday'].'&modecompta=CREANCES-DETTES">','</a>').')';
         if (! empty($conf->accounting->enabled)) $calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?date_startyear='.$tmps['year'].'&date_startmonth='.$tmps['mon'].'&date_startday='.$tmps['mday'].'&date_endyear='.$tmpe['year'].'&date_endmonth='.$tmpe['mon'].'&date_endday='.$tmpe['mday'].'&modecompta=BOOKKEEPING">','</a>').')';
    -    //$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',1,1,0,'',1,0,1);
    -    $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    -	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']-1)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']+1)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
    +    $period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
    +    $periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']-1)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']+1)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
         $description=$langs->trans("RulesResultInOut");
         $builddate=dol_now();
         //$exportlink=$langs->trans("NotYetAvailable");
    @@ -188,8 +188,7 @@ elseif ($modecompta=="BOOKKEEPING")
     	$calcmode=$langs->trans("CalcModeBookkeeping");
         $calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?date_startyear='.$tmps['year'].'&date_startmonth='.$tmps['mon'].'&date_startday='.$tmps['mday'].'&date_endyear='.$tmpe['year'].'&date_endmonth='.$tmpe['mon'].'&date_endday='.$tmpe['mday'].'&modecompta=RECETTES-DEPENSES">','</a>').')';
     	$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?date_startyear='.$tmps['year'].'&date_startmonth='.$tmps['mon'].'&date_startday='.$tmps['mday'].'&date_endyear='.$tmpe['year'].'&date_endmonth='.$tmpe['mon'].'&date_endday='.$tmpe['mday'].'&modecompta=CREANCES-DETTES">','</a>').')';
    -	//$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',1,1,0,'',1,0,1);
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$arraylist=array('no'=>$langs->trans("No"), 'yes'=>$langs->trans("AccountWithNonZeroValues"), 'all'=>$langs->trans("All"));
     	$period.=' &nbsp; &nbsp; '.$langs->trans("DetailByAccount").' '. $form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']-1)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($tmps['year']+1)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
    @@ -1210,6 +1209,6 @@ if ($mysoc->tva_assuj != 'franchise')	// Assujetti
     print "</table>";
     print '<br>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/resultat/index.php b/htdocs/compta/resultat/index.php
    index fbbc7a36eef..1e2719eac81 100644
    --- a/htdocs/compta/resultat/index.php
    +++ b/htdocs/compta/resultat/index.php
    @@ -1,10 +1,11 @@
     <?php
    -/* Copyright (C) 2003      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2014-2016 Ferran Marcet        <fmarcet@2byte.es>
    - * Copyright (C) 2014	   Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2014	   Florian Henry        <florian.henry@open-concept.pro>
    +/* Copyright (C) 2003       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2014-2016  Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2014       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2014       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -124,7 +125,7 @@ if ($modecompta == 'CREANCES-DETTES')
     	$calcmode=$langs->trans("CalcModeDebt");
     	$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=RECETTES-DEPENSES">','</a>').')';
     	if (! empty($conf->accounting->enabled)) $calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=BOOKKEEPING">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear-2)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
     	$description=$langs->trans("RulesAmountWithTaxIncluded");
     	$description.='<br>'.$langs->trans("RulesResultDue");
    @@ -138,7 +139,7 @@ else if ($modecompta=="RECETTES-DEPENSES") {
     	$calcmode=$langs->trans("CalcModeEngagement");
     	$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=CREANCES-DETTES">','</a>').')';
     	if (! empty($conf->accounting->enabled)) $calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=BOOKKEEPING">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear-2)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
     	$description=$langs->trans("RulesAmountWithTaxIncluded");
     	$description.='<br>'.$langs->trans("RulesResultInOut");
    @@ -151,7 +152,7 @@ else if ($modecompta=="BOOKKEEPING")
     	$calcmode=$langs->trans("CalcModeBookkeeping");
     	$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=RECETTES-DEPENSES">','</a>').')';
     	$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=CREANCES-DETTES">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear-2)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
     	$description=$langs->trans("RulesAmountOnInOutBookkeepingRecord");
     	$description.=' ('.$langs->trans("SeePageForSetup", DOL_URL_ROOT.'/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin', $langs->transnoentitiesnoconv("Accountancy").' / '.$langs->transnoentitiesnoconv("Setup").' / '.$langs->trans("Chartofaccounts")).')';
    @@ -687,7 +688,6 @@ if (! empty($conf->expensereport->enabled) && ($modecompta == 'CREANCES-DETTES'
     		$column='p.date_valid';
     		if (! empty($date_start) && ! empty($date_end))
     			$sql.= " AND ".$column." >= '".$db->idate($date_start)."' AND ".$column." <= '".$db->idate($date_end)."'";
    -
     	} elseif ($modecompta == 'RECETTES-DEPENSES') {
     		$sql = "SELECT date_format(pe.datep,'%Y-%m') as dm, sum(p.total_ht) as amount_ht,sum(p.total_ttc) as amount_ttc";
     		$sql.= " FROM ".MAIN_DB_PREFIX."expensereport as p";
    @@ -720,7 +720,6 @@ if (! empty($conf->expensereport->enabled) && ($modecompta == 'CREANCES-DETTES'
     
     				if (! isset($decaiss_ttc[$obj->dm])) $decaiss_ttc[$obj->dm]=0;
     				$decaiss_ttc[$obj->dm] += $obj->amount_ttc;
    -
     			}
     		}
     	}
    @@ -728,7 +727,6 @@ if (! empty($conf->expensereport->enabled) && ($modecompta == 'CREANCES-DETTES'
     	{
     		dol_print_error($db);
     	}
    -
     }
     elseif ($modecompta == 'BOOKKEEPING') {
     	// Nothing from this table
    @@ -1009,5 +1007,6 @@ print "</tr>\n";
     print "</table>";
     print '</div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php
    index 23c7e91b989..c4a6e2ec755 100644
    --- a/htdocs/compta/resultat/result.php
    +++ b/htdocs/compta/resultat/result.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2016-2017		Jamal Elbaz			<jamelbaz@gmail.com>
    - * Copyright (C) 2016 	    	Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2018 	    	Laurent Destailleur <eldy@destailleur.fr>
    +/* Copyright (C) 2016-2017  Jamal Elbaz             <jamelbaz@gmail.com>
    + * Copyright (C) 2016       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Laurent Destailleur     <eldy@destailleur.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -171,7 +172,7 @@ if ($modecompta=="CREANCES-DETTES")
     	$calcmode=$langs->trans("CalcModeDebt");
     	$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$start_year.(GETPOST("month")>0?'&month='.GETPOST("month"):'').'&modecompta=RECETTES-DEPENSES">','</a>').')';
     	if (! empty($conf->accounting->enabled)) $calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$start_year.'&modecompta=BOOKKEEPING">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	//$periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
     	$description=$langs->trans("RulesResultDue");
     	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $description.= $langs->trans("DepositsAreNotIncluded");
    @@ -179,25 +180,24 @@ if ($modecompta=="CREANCES-DETTES")
     	$builddate=dol_now();
     	//$exportlink=$langs->trans("NotYetAvailable");
     }
    -else if ($modecompta=="RECETTES-DEPENSES") {
    +elseif ($modecompta=="RECETTES-DEPENSES") {
     	$name=$langs->trans("AnnualByAccountInputOutputMode");
     	$calcmode=$langs->trans("CalcModeEngagement");
     	$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.(GETPOST("month")>0?'&month='.GETPOST("month"):'').'&modecompta=CREANCES-DETTES">','</a>').')';
     	if (! empty($conf->accounting->enabled)) $calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=BOOKKEEPING">','</a>').')';
    -	//$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',1,1,0,'',1,0,1);
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	//$periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
     	$description=$langs->trans("RulesResultInOut");
     	$builddate=dol_now();
     	//$exportlink=$langs->trans("NotYetAvailable");
     }
    -else if ($modecompta=="BOOKKEEPING")
    +elseif ($modecompta=="BOOKKEEPING")
     {
     	$name = $langs->trans("ReportInOut").', '.$langs->trans("ByPersonalizedAccountGroups");
     	$calcmode=$langs->trans("CalcModeBookkeeping");
     	//$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=CREANCES-DETTES">','</a>').')';
     	//$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=RECETTES-DEPENSES">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$arraylist=array('no'=>$langs->trans("No"), 'yes'=>$langs->trans("AccountWithNonZeroValues"), 'all'=>$langs->trans("All"));
     	$period.=' &nbsp; &nbsp; '.$langs->trans("DetailByAccount").' '. $form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0);
     	$periodlink = $textprevyear . $textnextyear ;
    @@ -247,12 +247,12 @@ if ($modecompta == 'CREANCES-DETTES')
     	//if (! empty($date_start) && ! empty($date_end))
     	//	$sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
     }
    -else if ($modecompta=="RECETTES-DEPENSES")
    +elseif ($modecompta=="RECETTES-DEPENSES")
     {
     	//if (! empty($date_start) && ! empty($date_end))
     	//	$sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
     }
    -else if ($modecompta=="BOOKKEEPING")
    +elseif ($modecompta=="BOOKKEEPING")
     {
     
     	// Get array of all report groups that are active
    @@ -537,5 +537,6 @@ else if ($modecompta=="BOOKKEEPING")
     print "</table>";
     print '</div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php
    index c4a2406e6d0..f50d940a51a 100644
    --- a/htdocs/compta/salaries/card.php
    +++ b/htdocs/compta/salaries/card.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2011-2017 Alexandre Spangaro   <aspangaro@zendsi.com>
    +/* Copyright (C) 2011-2018 Alexandre Spangaro   <aspangaro@zendsi.com>
      * Copyright (C) 2014      Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2015      Jean-François Ferry  <jfefe@aternatik.fr>
      * Copyright (C) 2015      Charlie BENKE        <charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -29,12 +30,20 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/salaries/class/paymentsalary.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/salaries.lib.php';
    +if (! empty($conf->projet->enabled))
    +{
    +	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
    +}
     
     // Load translation files required by the page
     $langs->loadLangs(array("compta","banks","bills","users","salaries","hrm"));
    +if (! empty($conf->projet->enabled))	$langs->load("projects");
     
     $id=GETPOST("id",'int');
     $action=GETPOST('action','aZ09');
    +$cancel= GETPOST('cancel', 'aZ09');
    +$projectid = (GETPOST('projectid','int') ? GETPOST('projectid', 'int') : GETPOST('fk_project','int'));
     
     // Security check
     $socid = GETPOST("socid","int");
    @@ -52,20 +61,27 @@ $hookmanager->initHooks(array('salarycard','globalcard'));
      * Actions
      */
     
    -if ($_POST["cancel"] == $langs->trans("Cancel"))
    +if ($cancel)
     {
     	header("Location: index.php");
     	exit;
     }
     
    -if ($action == 'add' && $_POST["cancel"] <> $langs->trans("Cancel"))
    +// Link to a project
    +if ($action == 'classin' && $user->rights->banque->modifier)
    +{
    +	$object->fetch($id);
    +	$object->setProject(GETPOST('projectid'));
    +}
    +
    +if ($action == 'add' && empty($cancel))
     {
     	$error=0;
     
    -	$datep=dol_mktime(12,0,0, $_POST["datepmonth"], $_POST["datepday"], $_POST["datepyear"]);
    -	$datev=dol_mktime(12,0,0, $_POST["datevmonth"], $_POST["datevday"], $_POST["datevyear"]);
    -	$datesp=dol_mktime(12,0,0, $_POST["datespmonth"], $_POST["datespday"], $_POST["datespyear"]);
    -	$dateep=dol_mktime(12,0,0, $_POST["dateepmonth"], $_POST["dateepday"], $_POST["dateepyear"]);
    +	$datep=dol_mktime(12,0,0, GETPOST("datepmonth",'int'), GETPOST("datepday",'int'), GETPOST("datepyear",'int'));
    +	$datev=dol_mktime(12,0,0, GETPOST("datevmonth",'int'), GETPOST("datevday",'int'), GETPOST("datevyear",'int'));
    +	$datesp=dol_mktime(12,0,0, GETPOST("datespmonth",'int'), GETPOST("datespday",'int'), GETPOST("datespyear",'int'));
    +	$dateep=dol_mktime(12,0,0, GETPOST("dateepmonth",'int'), GETPOST("dateepday",'int'), GETPOST("dateepyear",'int'));
     	if (empty($datev)) $datev=$datep;
     
     	$type_payment = dol_getIdFromCode($db, GETPOST("paymenttype", 'alpha'), 'c_paiement', 'code', 'id', 1);
    @@ -82,6 +98,7 @@ if ($action == 'add' && $_POST["cancel"] <> $langs->trans("Cancel"))
     	$object->type_payment=($type_payment > 0 ? $type_payment : 0);
     	$object->num_payment=GETPOST("num_payment");
     	$object->fk_user_author=$user->id;
    +	$object->fk_project= GETPOST('fk_project','int');
     
     	// Set user current salary as ref salaray for the payment
     	$fuser=new User($db);
    @@ -187,6 +204,7 @@ if ($action == 'delete')
     llxHeader("",$langs->trans("SalaryPayment"));
     
     $form = new Form($db);
    +if (! empty($conf->projet->enabled)) $formproject = new FormProjets($db);
     
     if ($id)
     {
    @@ -238,13 +256,13 @@ if ($action == 'create')
     	// Date payment
     	print '<tr><td>';
     	print fieldLabel('DatePayment','datep',1).'</td><td>';
    -	print $form->select_date((empty($datep)?-1:$datep),"datep",'','','','add',1,1);
    +	print $form->selectDate((empty($datep)?-1:$datep), "datep", '', '', '', 'add', 1, 1);
     	print '</td></tr>';
     
     	// Date value for bank
     	print '<tr><td>';
     	print fieldLabel('DateValue','datev',0).'</td><td>';
    -	print $form->select_date((empty($datev)?-1:$datev),"datev",'','','','add',1,1);
    +	print $form->selectDate((empty($datev)?-1:$datev), "datev", '', '', '', 'add', 1, 1);
     	print '</td></tr>';
     
     	// Employee
    @@ -263,13 +281,13 @@ if ($action == 'create')
     	// Date start period
     	print '<tr><td>';
     	print fieldLabel('DateStartPeriod','datesp',1).'</td><td>';
    -	print $form->select_date($datesp,"datesp",'','','','add');
    +	print $form->selectDate($datesp, "datesp", '', '', '', 'add');
     	print '</td></tr>';
     
     	// Date end period
     	print '<tr><td>';
     	print fieldLabel('DateEndPeriod','dateep',1).'</td><td>';
    -	print $form->select_date($dateep,"dateep",'','','','add');
    +	print $form->selectDate($dateep, "dateep", '', '', '', 'add');
     	print '</td></tr>';
     
     	// Amount
    @@ -278,6 +296,18 @@ if ($action == 'create')
     	print '<input name="amount" id="amount" class="minwidth100" value="'.GETPOST("amount").'">';
     	print '</td></tr>';
     
    +	// Project
    +	if (! empty($conf->projet->enabled))
    +	{
    +		$formproject=new FormProjets($db);
    +
    +		print '<tr><td>'.$langs->trans("Project").'</td><td>';
    +
    +		$numproject=$formproject->select_projects(-1, $projectid,'fk_project',0,0,1,1);
    +
    +		print '</td></tr>';
    +	}
    +
     	// Bank
     	if (! empty($conf->banque->enabled))
     	{
    @@ -335,14 +365,46 @@ if ($id)
     
     	dol_fiche_head($head, 'card', $langs->trans("SalaryPayment"), -1, 'payment');
     
    -    $linkback = '<a href="'.DOL_URL_ROOT.'/compta/salaries/index.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
    +	$linkback = '<a href="'.DOL_URL_ROOT.'/compta/salaries/index.php'.(! empty($socid)?'?socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
     
     	$morehtmlref='<div class="refidno">';
     
    +	// Employee
     	$userstatic=new User($db);
     	$userstatic->fetch($object->fk_user);
    -
     	$morehtmlref.=$langs->trans('Employee') . ' : ' . $userstatic->getNomUrl(1);
    +
    +	// Project
    +	if (! empty($conf->projet->enabled))
    +	{
    +		$morehtmlref.='<br>'.$langs->trans('Project') . ' ';
    +		if ($user->rights->salaries->write)
    +		{
    +			if ($action != 'classify')
    +				$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
    +				if ($action == 'classify') {
    +					//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
    +					$morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
    +					$morehtmlref.='<input type="hidden" name="action" value="classin">';
    +					$morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +					$morehtmlref.=$formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
    +					$morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    +					$morehtmlref.='</form>';
    +				} else {
    +					$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
    +				}
    +		} else {
    +			if (! empty($object->fk_project)) {
    +				$proj = new Project($db);
    +				$proj->fetch($object->fk_project);
    +				$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
    +				$morehtmlref.=$proj->ref;
    +				$morehtmlref.='</a>';
    +			} else {
    +				$morehtmlref.='';
    +			}
    +		}
    +	}
     	$morehtmlref.='</div>';
     
     	dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', '');
    @@ -425,8 +487,6 @@ if ($id)
     	print "</div>";
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/salaries/class/paymentsalary.class.php b/htdocs/compta/salaries/class/paymentsalary.class.php
    index 3a3f34b85b4..0be0f4f3694 100644
    --- a/htdocs/compta/salaries/class/paymentsalary.class.php
    +++ b/htdocs/compta/salaries/class/paymentsalary.class.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2011-2015 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>
    +/* Copyright (C) 2011-2018 Alexandre Spangaro   <aspangaro@zendsi.com>
    + * Copyright (C) 2014      Juanjo Menent        <jmenent@2byte.es>
      *
      * 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
    @@ -17,9 +17,9 @@
      */
     
     /**
    - *      \file       htdocs/compta/salaries/class/paymentsalary.class.php
    - *      \ingroup    salaries
    - *      \brief		Class for salaries module payment
    + *  \file       htdocs/compta/salaries/class/paymentsalary.class.php
    + *  \ingroup    salaries
    + *  \brief      Class for salaries module payment
      */
     
     // Put here all includes required by your class file
    @@ -31,22 +31,61 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class PaymentSalary extends CommonObject
     {
    -	public $element='payment_salary';			//!< Id that identify managed objects
    -	public $table_element='payment_salary';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='payment_salary';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='payment_salary';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='payment';
     
     	public $tms;
    +
    +	/**
    +	 * @var int User ID
    +	 */
     	public $fk_user;
    +
     	public $datep;
     	public $datev;
     	public $amount;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_project;
    +
     	public $type_payment;
     	public $num_payment;
    -	public $label;
    +
    +	/**
    +     * @var string salary payments label
    +     */
    +    public $label;
    +
     	public $datesp;
     	public $dateep;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
     
     
    @@ -60,7 +99,6 @@ class PaymentSalary extends CommonObject
     		$this->db = $db;
     		$this->element = 'payment_salary';
     		$this->table_element = 'payment_salary';
    -		return 1;
     	}
     
     	/**
    @@ -102,6 +140,7 @@ class PaymentSalary extends CommonObject
     		$sql.= " datep='".$this->db->idate($this->datep)."',";
     		$sql.= " datev='".$this->db->idate($this->datev)."',";
     		$sql.= " amount=".price2num($this->amount).",";
    +		$sql.= " fk_projet='".$this->db->escape($this->fk_project)."',";
     		$sql.= " fk_typepayment=".$this->fk_typepayment."',";
     		$sql.= " num_payment='".$this->db->escape($this->num_payment)."',";
     		$sql.= " label='".$this->db->escape($this->label)."',";
    @@ -161,6 +200,7 @@ class PaymentSalary extends CommonObject
     		$sql.= " s.datep,";
     		$sql.= " s.datev,";
     		$sql.= " s.amount,";
    +		$sql.= " s.fk_projet as fk_project,";
     		$sql.= " s.fk_typepayment,";
     		$sql.= " s.num_payment,";
     		$sql.= " s.label,";
    @@ -186,25 +226,26 @@ class PaymentSalary extends CommonObject
     			{
     				$obj = $this->db->fetch_object($resql);
     
    -				$this->id    = $obj->rowid;
    -				$this->ref   = $obj->rowid;
    -				$this->tms   = $this->db->jdate($obj->tms);
    -				$this->fk_user = $obj->fk_user;
    -				$this->datep = $this->db->jdate($obj->datep);
    -				$this->datev = $this->db->jdate($obj->datev);
    -				$this->amount = $obj->amount;
    -				$this->type_payement = $obj->fk_typepayment;
    -				$this->num_payment = $obj->num_payment;
    -				$this->label = $obj->label;
    -				$this->datesp = $this->db->jdate($obj->datesp);
    -				$this->dateep = $this->db->jdate($obj->dateep);
    -				$this->note  = $obj->note;
    -				$this->fk_bank = $obj->fk_bank;
    -				$this->fk_user_author = $obj->fk_user_author;
    -				$this->fk_user_modif = $obj->fk_user_modif;
    -				$this->fk_account = $obj->fk_account;
    -				$this->fk_type = $obj->fk_type;
    -				$this->rappro  = $obj->rappro;
    +				$this->id				= $obj->rowid;
    +				$this->ref				= $obj->rowid;
    +				$this->tms				= $this->db->jdate($obj->tms);
    +				$this->fk_user			= $obj->fk_user;
    +				$this->datep			= $this->db->jdate($obj->datep);
    +				$this->datev			= $this->db->jdate($obj->datev);
    +				$this->amount			= $obj->amount;
    +				$this->fk_project		= $obj->fk_project;
    +				$this->type_payement	= $obj->fk_typepayment;
    +				$this->num_payment		= $obj->num_payment;
    +				$this->label			= $obj->label;
    +				$this->datesp			= $this->db->jdate($obj->datesp);
    +				$this->dateep			= $this->db->jdate($obj->dateep);
    +				$this->note				= $obj->note;
    +				$this->fk_bank			= $obj->fk_bank;
    +				$this->fk_user_author	= $obj->fk_user_author;
    +				$this->fk_user_modif	= $obj->fk_user_modif;
    +				$this->fk_account		= $obj->fk_account;
    +				$this->fk_type			= $obj->fk_type;
    +				$this->rappro			= $obj->rappro;
     			}
     			$this->db->free($resql);
     
    @@ -276,12 +317,12 @@ class PaymentSalary extends CommonObject
     		$this->fk_user_modif='';
     	}
     
    -    /**
    -     *  Create in database
    -     *
    -     *  @param      User	$user       User that create
    -     *  @return     int      			<0 if KO, >0 if OK
    -     */
    +	/**
    +	 *  Create in database
    +	 *
    +	 *  @param      User	$user       User that create
    +	 *  @return     int      			<0 if KO, >0 if OK
    +	 */
     	function create($user)
     	{
     		global $conf,$langs;
    @@ -331,6 +372,7 @@ class PaymentSalary extends CommonObject
     		$sql.= ", datep";
     		$sql.= ", datev";
     		$sql.= ", amount";
    +		$sql.= ", fk_projet";
     		$sql.= ", salary";
     		$sql.= ", fk_typepayment";
     		$sql.= ", num_payment";
    @@ -348,6 +390,7 @@ class PaymentSalary extends CommonObject
     		$sql.= ", '".$this->db->idate($this->datep)."'";
     		$sql.= ", '".$this->db->idate($this->datev)."'";
     		$sql.= ", ".$this->amount;
    +		$sql.= ", ".($this->fk_project > 0? $this->fk_project : 0);
     		$sql.= ", ".($this->salary > 0 ? $this->salary : "null");
     		$sql.= ", ".$this->db->escape($this->type_payment);
     		$sql.= ", '".$this->db->escape($this->num_payment)."'";
    @@ -444,7 +487,6 @@ class PaymentSalary extends CommonObject
     	            $result=$this->call_trigger('PAYMENT_SALARY_CREATE',$user);
     	            if ($result < 0) $error++;
     	            // End call triggers
    -
     			}
     			else $error++;
     
    @@ -467,6 +509,7 @@ class PaymentSalary extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update link between payment salary and line generate into llx_bank
     	 *
    @@ -475,6 +518,7 @@ class PaymentSalary extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = 'UPDATE '.MAIN_DB_PREFIX.'payment_salary SET fk_bank = '.$id_bank;
     		$sql.= ' WHERE rowid = '.$this->id;
     		$result = $this->db->query($sql);
    @@ -502,13 +546,11 @@ class PaymentSalary extends CommonObject
     		global $langs;
     
     		$result='';
    -        $label=$langs->trans("ShowSalaryPayment").': '.$this->ref;
    +		$label=$langs->trans("ShowSalaryPayment").': '.$this->ref;
     
    -        $linkstart = '<a href="'.DOL_URL_ROOT.'/compta/salaries/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
    +		$linkstart = '<a href="'.DOL_URL_ROOT.'/compta/salaries/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
     		$linkend='</a>';
     
    -		$picto='payment';
    -
     		$result .= $linkstart;
     		if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1);
     		if ($withpicto != 2) $result.= $this->ref;
    @@ -566,6 +608,7 @@ class PaymentSalary extends CommonObject
     	    return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoi le libelle d'un statut donne
     	 *
    @@ -575,6 +618,7 @@ class PaymentSalary extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     	    global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
     
     	    $langs->load('compta');
    @@ -615,5 +659,4 @@ class PaymentSalary extends CommonObject
     	    }*/
     	    return '';
     	}
    -
     }
    diff --git a/htdocs/compta/salaries/class/salariesstats.class.php b/htdocs/compta/salaries/class/salariesstats.class.php
    index 647dc27f4a5..82a8d094148 100644
    --- a/htdocs/compta/salaries/class/salariesstats.class.php
    +++ b/htdocs/compta/salaries/class/salariesstats.class.php
    @@ -29,6 +29,9 @@ include_once DOL_DOCUMENT_ROOT . '/compta/salaries/class/paymentsalary.class.php
      */
     class SalariesStats extends Stats
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element;
     
     	var $socid;
    diff --git a/htdocs/compta/salaries/document.php b/htdocs/compta/salaries/document.php
    index 49d283522ee..1059c765df3 100644
    --- a/htdocs/compta/salaries/document.php
    +++ b/htdocs/compta/salaries/document.php
    @@ -91,7 +91,7 @@ if ($object->id)
     
     	dol_fiche_head($head, 'documents',  $langs->trans("SalaryPayment"), -1, 'payment');
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -127,13 +127,12 @@ if ($object->id)
     	$permission = $user->rights->salaries->write;
     	$param = '&id=' . $object->id;
     	include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/salaries/index.php b/htdocs/compta/salaries/index.php
    index 73f50b57564..a8a0b82e7d9 100644
    --- a/htdocs/compta/salaries/index.php
    +++ b/htdocs/compta/salaries/index.php
    @@ -294,6 +294,6 @@ else
         dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/salaries/info.php b/htdocs/compta/salaries/info.php
    index 467abe3618c..d2f02f3dc8f 100644
    --- a/htdocs/compta/salaries/info.php
    +++ b/htdocs/compta/salaries/info.php
    @@ -79,6 +79,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/salaries/stats/index.php b/htdocs/compta/salaries/stats/index.php
    index 090629ba97d..edb48edc303 100644
    --- a/htdocs/compta/salaries/stats/index.php
    +++ b/htdocs/compta/salaries/stats/index.php
    @@ -214,6 +214,7 @@ print '</table>';
     print '</form>';
     print '<br><br>';
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="border" width="100%">';
     print '<tr>';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -247,6 +248,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    @@ -271,7 +273,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php
    index 4fc9eb00bcd..4ffa1a2829f 100644
    --- a/htdocs/compta/sociales/card.php
    +++ b/htdocs/compta/sociales/card.php
    @@ -1,8 +1,8 @@
     <?php
    -/* Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2013 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2016      Frédéric France      <frederic.france@free.fr>
    - * Copyright (C) 2017      Alexandre Spangaro   <aspangaro@zendsi.com>
    +/* Copyright (C) 2004-2016 Laurent Destailleur      <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2013 Regis Houssin            <regis.houssin@capnetworks.com>
    + * Copyright (C) 2016-2018 Frédéric France          <frederic.france@netlogic.fr>
    + * Copyright (C) 2017      Alexandre Spangaro       <aspangaro@zendsi.com>
      *
      * 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
    @@ -32,11 +32,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     if (! empty($conf->projet->enabled))
     {
    -	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    -	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
    +	include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +	include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
     }
     if (! empty($conf->accounting->enabled)) {
    -	require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
    +	include_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
     }
     
     // Load translation files required by the page
    @@ -332,7 +332,7 @@ if ($action == 'create')
     	print $form->textwithpicto($langs->trans("PeriodEndDate"), $langs->trans("LastDayTaxIsRelatedTo"));
     	print '</td>';
        	print '<td>';
    -	print $form->select_date(! empty($dateperiod)?$dateperiod:'-1', 'period', 0, 0, 0, 'charge', 1);
    +	print $form->selectDate(! empty($dateperiod)?$dateperiod:'-1', 'period', 0, 0, 0, 'charge', 1);
     	print '</td>';
     	print '</tr>';
     
    @@ -342,7 +342,7 @@ if ($action == 'create')
     	print $langs->trans("DateDue");
     	print '</td>';
     	print '<td>';
    -	print $form->select_date(! empty($dateech)?$dateech:'-1', 'ech', 0, 0, 0, 'charge', 1);
    +	print $form->selectDate(! empty($dateech)?$dateech:'-1', 'ech', 0, 0, 0, 'charge', 1);
     	print '</td>';
     	print "</tr>\n";
     
    @@ -502,7 +502,7 @@ if ($id > 0)
     		print "<td>";
     		if ($action == 'edit')
     		{
    -			print $form->select_date($object->periode, 'period', 0, 0, 0, 'charge', 1);
    +			print $form->selectDate($object->periode, 'period', 0, 0, 0, 'charge', 1);
     		}
     		else
     		{
    @@ -514,10 +514,9 @@ if ($id > 0)
     		if ($action == 'edit')
     		{
     			print '<tr><td>'.$langs->trans("DateDue")."</td><td>";
    -			print $form->select_date($object->date_ech, 'ech', 0, 0, 0, 'charge', 1);
    +			print $form->selectDate($object->date_ech, 'ech', 0, 0, 0, 'charge', 1);
     			print "</td></tr>";
    -		}
    -		else {
    +		} else {
     			print "<tr><td>".$langs->trans("DateDue")."</td><td>".dol_print_date($object->date_ech,'day')."</td></tr>";
     		}
     
    @@ -750,7 +749,6 @@ if ($id > 0)
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/sociales/class/cchargesociales.class.php b/htdocs/compta/sociales/class/cchargesociales.class.php
    index a44b820c8ea..710bea7def2 100644
    --- a/htdocs/compta/sociales/class/cchargesociales.class.php
    +++ b/htdocs/compta/sociales/class/cchargesociales.class.php
    @@ -25,7 +25,7 @@
      */
     
     // Put here all includes required by your class file
    -require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
    +//require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
     //require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     //require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
     
    @@ -38,25 +38,25 @@ class Cchargesociales
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'cchargesociales';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'c_chargesociales';
     
    -	/**
    -	 */
    -	
     	public $libelle;
     	public $deductible;
     	public $active;
     	public $code;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_pays;
    +
     	public $module;
     	public $accountancy_code;
     
    -	/**
    -	 */
    -	
     
     	/**
     	 * Constructor
    @@ -82,38 +82,25 @@ class Cchargesociales
     
     		$error = 0;
     
    -		// Clean parameters
    -		
    -		if (isset($this->libelle)) {
    -			 $this->libelle = trim($this->libelle);
    -		}
    -		if (isset($this->deductible)) {
    -			 $this->deductible = trim($this->deductible);
    -		}
    -		if (isset($this->active)) {
    -			 $this->active = trim($this->active);
    -		}
    -		if (isset($this->code)) {
    -			 $this->code = trim($this->code);
    -		}
    -		if (isset($this->fk_pays)) {
    -			 $this->fk_pays = trim($this->fk_pays);
    -		}
    -		if (isset($this->module)) {
    -			 $this->module = trim($this->module);
    -		}
    -		if (isset($this->accountancy_code)) {
    -			 $this->accountancy_code = trim($this->accountancy_code);
    -		}
    -
    -		
    +        // Clean parameters
    +        $this->trimParameters(
    +            array(
    +                'libelle',
    +                'deductible',
    +                'active',
    +                'code',
    +                'fk_pays',
    +                'module',
    +                'accountancy_code',
    +            )
    +        );
     
     		// Check parameters
     		// Put here code to add control on parameters values
     
     		// Insert request
     		$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '(';
    -		
    +
     		$sql.= 'libelle,';
     		$sql.= 'deductible,';
     		$sql.= 'active,';
    @@ -122,9 +109,9 @@ class Cchargesociales
     		$sql.= 'module';
     		$sql.= 'accountancy_code';
     
    -		
    +
     		$sql .= ') VALUES (';
    -		
    +
     		$sql .= ' '.(! isset($this->libelle)?'NULL':"'".$this->db->escape($this->libelle)."'").',';
     		$sql .= ' '.(! isset($this->deductible)?'NULL':$this->deductible).',';
     		$sql .= ' '.(! isset($this->active)?'NULL':$this->active).',';
    @@ -133,7 +120,7 @@ class Cchargesociales
     		$sql .= ' '.(! isset($this->module)?'NULL':"'".$this->db->escape($this->module)."'").',';
     		$sql .= ' '.(! isset($this->accountancy_code)?'NULL':"'".$this->db->escape($this->accountancy_code)."'");
     
    -		
    +
     		$sql .= ')';
     
     		$this->db->begin();
    @@ -148,7 +135,7 @@ class Cchargesociales
     		if (!$error) {
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     
    -			if (!$notrigger) {
    +			//if (!$notrigger) {
     				// Uncomment this and change MYOBJECT to your own tag if you
     				// want this action to call a trigger.
     
    @@ -156,7 +143,7 @@ class Cchargesociales
     				//$result=$this->call_trigger('MYOBJECT_CREATE',$user);
     				//if ($result < 0) $error++;
     				//// End call triggers
    -			}
    +			//}
     		}
     
     		// Commit or rollback
    @@ -206,7 +193,7 @@ class Cchargesociales
     				$obj = $this->db->fetch_object($resql);
     
     				$this->id = $obj->id;
    -				
    +
     				$this->libelle = $obj->libelle;
     				$this->deductible = $obj->deductible;
     				$this->active = $obj->active;
    @@ -214,8 +201,6 @@ class Cchargesociales
     				$this->fk_pays = $obj->fk_pays;
     				$this->module = $obj->module;
     				$this->accountancy_code = $obj->accountancy_code;
    -
    -				
     			}
     			$this->db->free($resql);
     
    @@ -247,30 +232,19 @@ class Cchargesociales
     		dol_syslog(__METHOD__, LOG_DEBUG);
     
     		// Clean parameters
    -		
    -		if (isset($this->libelle)) {
    -			 $this->libelle = trim($this->libelle);
    -		}
    -		if (isset($this->deductible)) {
    -			 $this->deductible = trim($this->deductible);
    -		}
    -		if (isset($this->active)) {
    -			 $this->active = trim($this->active);
    -		}
    -		if (isset($this->code)) {
    -			 $this->code = trim($this->code);
    -		}
    -		if (isset($this->fk_pays)) {
    -			 $this->fk_pays = trim($this->fk_pays);
    -		}
    -		if (isset($this->module)) {
    -			 $this->module = trim($this->module);
    -		}
    -		if (isset($this->accountancy_code)) {
    -			 $this->accountancy_code = trim($this->accountancy_code);
    -		}
     
    -		
    +        $this->trimParameters(
    +            array(
    +                'libelle',
    +                'deductible',
    +                'active',
    +                'code',
    +                'fk_pays',
    +                'module',
    +                'accountancy_code',
    +            )
    +        );
    +
     
     		// Check parameters
     		// Put here code to add a control on parameters values
    @@ -295,7 +269,7 @@ class Cchargesociales
     			dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
     		}
     
    -		if (!$error && !$notrigger) {
    +		//if (!$error && !$notrigger) {
     			// Uncomment this and change MYOBJECT to your own tag if you
     			// want this action calls a trigger.
     
    @@ -303,7 +277,7 @@ class Cchargesociales
     			//$result=$this->call_trigger('MYOBJECT_MODIFY',$user);
     			//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
     			//// End call triggers
    -		}
    +		//}
     
     		// Commit or rollback
     		if ($error) {
    @@ -333,8 +307,8 @@ class Cchargesociales
     
     		$this->db->begin();
     
    -		if (!$error) {
    -			if (!$notrigger) {
    +		//if (!$error) {
    +			//if (!$notrigger) {
     				// Uncomment this and change MYOBJECT to your own tag if you
     				// want this action calls a trigger.
     
    @@ -342,8 +316,8 @@ class Cchargesociales
     				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
     				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
     				//// End call triggers
    -			}
    -		}
    +			//}
    +		//}
     
     		if (!$error) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
    @@ -454,7 +428,7 @@ class Cchargesociales
     		$result.= $link . $this->ref . $linkend;
     		return $result;
     	}
    -	
    +
     	/**
     	 *  Retourne le libelle du status d'un user (actif, inactif)
     	 *
    @@ -466,6 +440,7 @@ class Cchargesociales
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un status donne
     	 *
    @@ -475,42 +450,42 @@ class Cchargesociales
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
    -			$prefix='';
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
     	}
    -	
    -	
    +
    +
     	/**
     	 * Initialise object with example values
     	 * Id must be 0 if object instance is a specimen
    @@ -520,7 +495,7 @@ class Cchargesociales
     	public function initAsSpecimen()
     	{
     		$this->id = 0;
    -		
    +
     		$this->libelle = '';
     		$this->deductible = '';
     		$this->active = '';
    @@ -528,8 +503,21 @@ class Cchargesociales
     		$this->fk_pays = '';
     		$this->module = '';
     		$this->accountancy_code = '';
    -
    -		
     	}
     
    +    /**
    +     * Trim object parameters
    +     * @param string[] $parameters array of parameters to trim
    +     *
    +     * @return void
    +     */
    +    private function trimParameters($parameters)
    +    {
    +        if (!is_array($parameters)) return;
    +        foreach ($parameters as $parameter) {
    +            if (isset($this->$parameter)) {
    +                $this->$parameter = trim($this->$parameter);
    +            }
    +        }
    +    }
     }
    diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php
    index 65e6085a650..cca5a4d7dd2 100644
    --- a/htdocs/compta/sociales/class/chargesociales.class.php
    +++ b/htdocs/compta/sociales/class/chargesociales.class.php
    @@ -32,9 +32,21 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class ChargeSociales extends CommonObject
     {
    -    public $element='chargesociales';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='chargesociales';
    +
         public $table='chargesociales';
    -    public $table_element='chargesociales';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='chargesociales';
    +
    +    /**
    +     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +     */
         public $picto = 'bill';
     
         /**
    @@ -42,18 +54,26 @@ class ChargeSociales extends CommonObject
          */
         protected $table_ref_field = 'ref';
     
    -    var $date_ech;
    -    var $lib;
    -    var $type;
    -    var $type_libelle;
    -    var $amount;
    -    var $paye;
    -    var $periode;
    -    var $date_creation;
    -    var $date_modification;
    -    var $date_validation;
    -    var $fk_account;
    -	var $fk_project;
    +    public $date_ech;
    +    public $lib;
    +    public $type;
    +    public $type_libelle;
    +    public $amount;
    +    public $paye;
    +    public $periode;
    +    public $date_creation;
    +    public $date_modification;
    +    public $date_validation;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_account;
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_project;
     
     
         /**
    @@ -64,7 +84,6 @@ class ChargeSociales extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
         /**
    @@ -280,7 +299,6 @@ class ChargeSociales extends CommonObject
                 $this->db->rollback();
                 return -1;
             }
    -
         }
     
     
    @@ -350,7 +368,6 @@ class ChargeSociales extends CommonObject
                 {
                     return 0;
                 }
    -
             }
             else
             {
    @@ -359,6 +376,7 @@ class ChargeSociales extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Tag social contribution as payed completely
          *
    @@ -367,6 +385,7 @@ class ChargeSociales extends CommonObject
          */
         function set_paid($user)
         {
    +        // phpcs:enable
             $sql = "UPDATE ".MAIN_DB_PREFIX."chargesociales SET";
             $sql.= " paye = 1";
             $sql.= " WHERE rowid = ".$this->id;
    @@ -374,6 +393,8 @@ class ChargeSociales extends CommonObject
             if ($return) return 1;
             else return -1;
         }
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Remove tag payed on social contribution
          *
    @@ -382,6 +403,7 @@ class ChargeSociales extends CommonObject
          */
         function set_unpaid($user)
         {
    +        // phpcs:enable
             $sql = "UPDATE ".MAIN_DB_PREFIX."chargesociales SET";
             $sql.= " paye = 0";
             $sql.= " WHERE rowid = ".$this->id;
    @@ -402,6 +424,7 @@ class ChargeSociales extends CommonObject
             return $this->LibStatut($this->paye,$mode,$alreadypaid);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Renvoi le libelle d'un statut donne
          *
    @@ -412,52 +435,49 @@ class ChargeSociales extends CommonObject
          */
         function LibStatut($statut,$mode=0,$alreadypaid=-1)
         {
    +        // phpcs:enable
             global $langs;
    -        $langs->load('customers');
    -        $langs->load('bills');
     
    -        if ($mode == 0)
    +        // Load translation files required by the page
    +        $langs->loadLangs(array("customers","bills"));
    +
    +        if ($mode == 0 || $mode == 1)
             {
                 if ($statut ==  0) return $langs->trans("Unpaid");
                 if ($statut ==  1) return $langs->trans("Paid");
             }
    -        if ($mode == 1)
    -        {
    -            if ($statut ==  0) return $langs->trans("Unpaid");
    -            if ($statut ==  1) return $langs->trans("Paid");
    -        }
    -        if ($mode == 2)
    +        elseif ($mode == 2)
             {
                 if ($statut ==  0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1').' '.$langs->trans("Unpaid");
                 if ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted");
                 if ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid");
             }
    -        if ($mode == 3)
    +        elseif ($mode == 3)
             {
                 if ($statut ==  0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1');
                 if ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3');
                 if ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6');
             }
    -        if ($mode == 4)
    +        elseif ($mode == 4)
             {
                 if ($statut ==  0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1').' '.$langs->trans("Unpaid");
                 if ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted");
                 if ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid");
             }
    -        if ($mode == 5)
    +        elseif ($mode == 5)
             {
                 if ($statut ==  0 && $alreadypaid <= 0) return $langs->trans("Unpaid").' '.img_picto($langs->trans("Unpaid"), 'statut1');
                 if ($statut ==  0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3');
                 if ($statut ==  1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6');
             }
    -        if ($mode == 6)
    +        elseif ($mode == 6)
             {
                 if ($statut ==  0 && $alreadypaid <= 0) return $langs->trans("Unpaid").' '.img_picto($langs->trans("Unpaid"), 'statut1');
                 if ($statut ==  0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3');
                 if ($statut ==  1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6');
             }
     
    -        return "Error, mode/status not found";
    +        else return "Error, mode/status not found";
         }
     
     
    @@ -606,7 +626,6 @@ class ChargeSociales extends CommonObject
                 }
     
                 $this->db->free($result);
    -
             }
             else
             {
    @@ -637,4 +656,3 @@ class ChargeSociales extends CommonObject
             $this->type_libelle = 'Social contribution label';
         }
     }
    -
    diff --git a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
    index ba9c671f755..d3c265150d4 100644
    --- a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
    +++ b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php
    @@ -31,26 +31,60 @@ require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'
      */
     class PaymentSocialContribution extends CommonObject
     {
    -	public $element='paiementcharge';			//!< Id that identify managed objects
    -	public $table_element='paiementcharge';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='paiementcharge';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='paiementcharge';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'payment';
     
    -	var $fk_charge;
    -	var $datec='';
    -	var $tms='';
    -	var $datep='';
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_charge;
    +
    +	public $datec='';
    +	public $tms='';
    +	public $datep='';
    +
     	/**
     	 * @deprecated
     	 * @see amount
     	 */
    -	var $total;
    -    var $amount;            // Total amount of payment
    -    var $amounts=array();   // Array of amounts
    -	var $fk_typepaiement;
    -	var $num_paiement;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    +	public $total;
    +
    +    public $amount;            // Total amount of payment
    +    public $amounts=array();   // Array of amounts
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_typepaiement;
    +
    +	public $num_paiement;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_modif;
     
     	/**
     	 *	Constructor
    @@ -161,7 +195,6 @@ class PaymentSocialContribution extends CommonObject
     			{
     				$error++;
     			}
    -
     		}
     
     		$result = $this->call_trigger('PAYMENTSOCIALCONTRIBUTION_CREATE',$user);
    @@ -493,8 +526,6 @@ class PaymentSocialContribution extends CommonObject
     		$this->fk_bank='';
     		$this->fk_user_creat='';
     		$this->fk_user_modif='';
    -
    -
     	}
     
     
    @@ -518,7 +549,7 @@ class PaymentSocialContribution extends CommonObject
     
             if (! empty($conf->banque->enabled))
             {
    -            require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
    +            include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
                 $acc = new Account($this->db);
                 $acc->fetch($accountid);
    @@ -594,6 +625,7 @@ class PaymentSocialContribution extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Mise a jour du lien entre le paiement de  charge et la ligne dans llx_bank generee
     	 *
    @@ -602,6 +634,7 @@ class PaymentSocialContribution extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = "UPDATE ".MAIN_DB_PREFIX."paiementcharge SET fk_bank = ".$id_bank." WHERE rowid = ".$this->id;
     
     		dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG);
    @@ -629,6 +662,7 @@ class PaymentSocialContribution extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoi le libelle d'un statut donne
     	 *
    @@ -638,6 +672,7 @@ class PaymentSocialContribution extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
     
     		$langs->load('compta');
    @@ -708,5 +743,3 @@ class PaymentSocialContribution extends CommonObject
     		return $result;
     	}
     }
    -
    -
    diff --git a/htdocs/compta/sociales/document.php b/htdocs/compta/sociales/document.php
    index 490dbf3a1fe..b2f73768e96 100644
    --- a/htdocs/compta/sociales/document.php
    +++ b/htdocs/compta/sociales/document.php
    @@ -35,8 +35,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     if (! empty($conf->projet->enabled))
     {
    -    require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    -    require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
    +    include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +    include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
     }
     
     // Load translation files required by the page
    @@ -76,7 +76,7 @@ $modulepart='tax';
      * Actions
      */
     
    -include_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/actions_linkedfiles.inc.php';
     
     if ($action == 'setlib' && $user->rights->tax->charges->creer)
     {
    @@ -136,7 +136,7 @@ if ($object->id)
     	print '<div class="fichecenter">';
     	print '<div class="underbanner clearboth"></div>';
     
    -    // Construit liste des fichiers
    +    // Build file list
         $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
         $totalsize=0;
         foreach($filearray as $key => $file)
    @@ -168,7 +168,6 @@ else
         print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/sociales/index.php b/htdocs/compta/sociales/index.php
    index bd323c972fe..6a0250804f1 100644
    --- a/htdocs/compta/sociales/index.php
    +++ b/htdocs/compta/sociales/index.php
    @@ -304,5 +304,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/sociales/info.php b/htdocs/compta/sociales/info.php
    index 1827c1597f8..bd21db108c1 100644
    --- a/htdocs/compta/sociales/info.php
    +++ b/htdocs/compta/sociales/info.php
    @@ -27,8 +27,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     if (! empty($conf->projet->enabled))
     {
    -    require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    -    require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
    +    include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +    include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
     }
     
     // Load translation files required by the page
    @@ -115,6 +115,6 @@ print '</td></tr></table>';
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/sociales/payments.php b/htdocs/compta/sociales/payments.php
    index b31ea8e4d2f..48b2698c762 100644
    --- a/htdocs/compta/sociales/payments.php
    +++ b/htdocs/compta/sociales/payments.php
    @@ -480,7 +480,6 @@ if (! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read))
     
     print '</form>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/stats/byratecountry.php b/htdocs/compta/stats/byratecountry.php
    index 2c43db42d13..99d6bb8b49d 100644
    --- a/htdocs/compta/stats/byratecountry.php
    +++ b/htdocs/compta/stats/byratecountry.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2018        Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2018       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -152,7 +153,7 @@ if ($modetax == 1) $calcmode=$langs->trans('OptionVATDebitOption');
     if ($modetax == 2) $calcmode=$langs->trans('OptionPaymentForProductAndServices');
     $calcmode.='<br>('.$langs->trans("TaxModuleSetupToModifyRules",DOL_URL_ROOT.'/admin/taxes.php').')';
     // Set period
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     $prevyear=$year_start; $prevquarter=$q;
     if ($prevquarter > 1) {
     	$prevquarter--;
    @@ -230,7 +231,7 @@ else if ($modecompta=="BOOKKEEPINGCOLLECTED")
     
     
     }
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
     else $periodlink = '';
     
    @@ -321,7 +322,6 @@ if ($resql) {
     	}
     	print '<td align="right" width="6%"><b>' . price($totalpermonth['total']) . '</b></td>';
     	print '</tr>';
    -
     } else {
     	print $db->lasterror(); // Show last sql error
     }
    @@ -405,7 +405,6 @@ if ($resql2) {
     	print $db->lasterror(); // Show last sql error
     }
     print "</table>\n";
    -
     } else {
     	// $modecompta != 'CREANCES-DETTES'
     	// "Calculation of part of each product for accountancy in this mode is not possible. When a partial payment (for example 5 euros) is done on an
    @@ -414,7 +413,6 @@ print "</table>\n";
     	print '<br>'.$langs->trans("TurnoverPerSaleTaxRateInCommitmentAccountingNotRelevant") . '<br>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
    index 5d28ab3e077..e7a3d4da480 100644
    --- a/htdocs/compta/stats/cabyprodserv.php
    +++ b/htdocs/compta/stats/cabyprodserv.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2013      Antoine Iauch	   <aiauch@gpcsolutions.fr>
    - * Copyright (C) 2013-2016 Laurent Destailleur <eldy@users.sourceforge.net>
    - * Copyright (C) 2015      Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    +/* Copyright (C) 2013       Antoine Iauch	        <aiauch@gpcsolutions.fr>
    + * Copyright (C) 2013-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -199,7 +200,7 @@ else if ($modecompta=="BOOKKEEPINGCOLLECTED")
     
     }
     
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
     else $periodlink = '';
     
    @@ -461,5 +462,6 @@ if ($modecompta == 'CREANCES-DETTES')
     	print '<br>'.$langs->trans("TurnoverPerProductInCommitmentAccountingNotRelevant") . '<br>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/compta/stats/cabyuser.php b/htdocs/compta/stats/cabyuser.php
    index ccb286c1420..4f49b9492ff 100644
    --- a/htdocs/compta/stats/cabyuser.php
    +++ b/htdocs/compta/stats/cabyuser.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013      Antoine Iauch        <aiauch@gpcsolutions.fr>
    +/* Copyright (C) 2001-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Antoine Iauch           <aiauch@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -177,7 +178,7 @@ else if ($modecompta=="BOOKKEEPINGCOLLECTED")
     
     
     }
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
     else $periodlink = '';
     
    @@ -465,7 +466,6 @@ print "</table>";
     print '</div>';
     print '</form>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php
    index 8e00dfe5fbe..fb53989fe74 100644
    --- a/htdocs/compta/stats/casoc.php
    +++ b/htdocs/compta/stats/casoc.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2007       Franky Van Liedekerke   <franky.van.liedekerke@telenet.be>
      * Copyright (C) 2013       Antoine Iauch           <aiauch@gpcsolutions.fr>
      * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -203,7 +204,7 @@ else if ($modecompta=="BOOKKEEPINGCOLLECTED")
     
     
     }
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year_start+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
     else $periodlink = '';
     
    @@ -312,7 +313,6 @@ if ($result) {
     	        $catotal_ht+=$obj->amount;
     	        $catotal+=$obj->amount_ttc;
     	        $i++;
    -
     	}
     } else {
     	dol_print_error($db);
    @@ -646,6 +646,6 @@ print "</div>";
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php
    index c255d236664..c5ceccdad61 100644
    --- a/htdocs/compta/stats/index.php
    +++ b/htdocs/compta/stats/index.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2017	   Olivier Geffroy      <jeff@jeffinfo.com>
    +/* Copyright (C) 2001-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2017       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -119,7 +120,7 @@ if ($modecompta=="CREANCES-DETTES")
     	$calcmode=$langs->trans("CalcModeDebt");
     	//$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=RECETTES-DEPENSES">','</a>').')';
     	$calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=BOOKKEEPING">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear-2)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
     	$description=$langs->trans("RulesCADue");
     	if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $description.= $langs->trans("DepositsAreNotIncluded");
    @@ -133,7 +134,7 @@ else if ($modecompta=="RECETTES-DEPENSES")
     	$calcmode=$langs->trans("CalcModeEngagement");
     	//$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=CREANCES-DETTES">','</a>').')';
     	//$calcmode.='<br>('.$langs->trans("SeeReportInBookkeepingMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=BOOKKEEPINGCOLLECTED">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear-2)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
     	$description=$langs->trans("RulesCAIn");
     	$description.= $langs->trans("DepositsAreIncluded");
    @@ -146,7 +147,7 @@ else if ($modecompta=="BOOKKEEPING")
     	$calcmode=$langs->trans("CalcModeBookkeeping");
     	$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=CREANCES-DETTES">','</a>').')';
     	//$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=RECETTES-DEPENSES">','</a>').')';
    -	$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +	$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     	$periodlink=($year_start?"<a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear-2)."&modecompta=".$modecompta."'>".img_previous()."</a> <a href='".$_SERVER["PHP_SELF"]."?year=".($year_start+$nbofyear)."&modecompta=".$modecompta."'>".img_next()."</a>":"");
     	$description=$langs->trans("RulesCATotalSaleJournal");
     	$builddate=dol_now();
    @@ -629,6 +630,6 @@ print '</div>';
     
      */
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/compta/tva/card.php b/htdocs/compta/tva/card.php
    index 4480682b091..69483d84be0 100644
    --- a/htdocs/compta/tva/card.php
    +++ b/htdocs/compta/tva/card.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2013 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2015-2017 Alexandre Spangaro   <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -255,11 +256,11 @@ if ($action == 'create')
     
         print "<tr>";
         print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("DatePayment").'</td><td>';
    -    print $form->select_date($datep,"datep",'','','','add',1,1);
    +    print $form->selectDate($datep, "datep", '', '', '', 'add', 1, 1);
         print '</td></tr>';
     
         print '<tr><td class="fieldrequired">'.$form->textwithpicto($langs->trans("PeriodEndDate"), $langs->trans("LastDayTaxIsRelatedTo")).'</td><td>';
    -    print $form->select_date($datev,"datev",'','','','add',1,1);
    +    print $form->selectDate($datev, "datev", '', '', '', 'add', 1, 1);
         print '</td></tr>';
     
     	// Label
    diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php
    index af330910cdf..33d48de8bfc 100644
    --- a/htdocs/compta/tva/class/tva.class.php
    +++ b/htdocs/compta/tva/class/tva.class.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2011-2017 Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2018      Philippe Grand       <philippe.grand@atoo-net.com>
    +/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2008  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2011-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Philippe Grand          <philippe.grand@atoo-net.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -33,20 +34,47 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Tva extends CommonObject
     {
    -	public $element='tva';			//!< Id that identify managed objects
    -	public $table_element='tva';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='tva';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='tva';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto='payment';
     
    -	var $tms;
    -	var $datep;
    -	var $datev;
    -	var $amount;
    -	var $type_payment;
    -	var $num_payment;
    -	var $label;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    +	public $tms;
    +	public $datep;
    +	public $datev;
    +	public $amount;
    +	public $type_payment;
    +	public $num_payment;
    +
    +	/**
    +     * @var string label
    +     */
    +    public $label;
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_modif;
     
         /**
     	 *	Constructor
    @@ -76,9 +104,9 @@ class Tva extends CommonObject
     		$this->amount=trim($this->amount);
     		$this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_creat=trim($this->fk_user_creat);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_creat = (int) $this->fk_user_creat;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
     		// Put here code to add control on parameters values
    @@ -155,9 +183,9 @@ class Tva extends CommonObject
     		$this->amount=trim($this->amount);
     		$this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_creat=trim($this->fk_user_creat);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_creat = (int) $this->fk_user_creat;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
     		// Put here code to add control on parameters values
    @@ -350,14 +378,16 @@ class Tva extends CommonObject
             return $solde;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Total of the VAT from invoices emitted by the thirdparty.
          *
          *	@param	int		$year		Year
    -     *	@return	double				Amount
    +     *  @return	double				Amount
          */
         function tva_sum_collectee($year = 0)
         {
    +        // phpcs:enable
     
             $sql = "SELECT sum(f.tva) as amount";
             $sql .= " FROM ".MAIN_DB_PREFIX."facture as f WHERE f.paye = 1";
    @@ -389,6 +419,7 @@ class Tva extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	VAT payed
          *
    @@ -397,6 +428,7 @@ class Tva extends CommonObject
          */
         function tva_sum_payee($year = 0)
         {
    +        // phpcs:enable
     
             $sql = "SELECT sum(f.total_tva) as total_tva";
             $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
    @@ -429,6 +461,7 @@ class Tva extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Total of the VAT payed
          *
    @@ -437,6 +470,7 @@ class Tva extends CommonObject
          */
         function tva_sum_reglee($year = 0)
         {
    +        // phpcs:enable
     
             $sql = "SELECT sum(f.amount) as amount";
             $sql .= " FROM ".MAIN_DB_PREFIX."tva as f";
    @@ -486,9 +520,9 @@ class Tva extends CommonObject
             $this->amount=price2num(trim($this->amount));
             $this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_creat=trim($this->fk_user_creat);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_creat = (int) $this->fk_user_creat;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     		if (empty($this->datec)) $this->datec = dol_now();
     
             // Check parameters
    @@ -620,6 +654,7 @@ class Tva extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *  Update link between payment tva and line generate into llx_bank
          *
    @@ -628,8 +663,9 @@ class Tva extends CommonObject
          */
     	function update_fk_bank($id_bank)
     	{
    -		$sql = 'UPDATE '.MAIN_DB_PREFIX.'tva SET fk_bank = '.$id_bank;
    -		$sql.= ' WHERE rowid = '.$this->id;
    +        // phpcs:enable
    +		$sql = 'UPDATE '.MAIN_DB_PREFIX.'tva SET fk_bank = '.(int) $id_bank;
    +		$sql.= ' WHERE rowid = '.(int) $this->id;
     		$result = $this->db->query($sql);
     		if ($result)
     		{
    @@ -734,7 +770,7 @@ class Tva extends CommonObject
     	{
     		$sql = "SELECT t.rowid, t.tms, t.fk_user_modif, t.datec, t.fk_user_creat";
     		$sql.= " FROM ".MAIN_DB_PREFIX."tva as t";
    -		$sql.= " WHERE t.rowid = ".$id;
    +		$sql.= " WHERE t.rowid = ".(int) $id;
     
     		dol_syslog(get_class($this)."::info", LOG_DEBUG);
     		$result=$this->db->query($sql);
    @@ -764,7 +800,6 @@ class Tva extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -783,6 +818,7 @@ class Tva extends CommonObject
     	    return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoi le libelle d'un statut donne
     	 *
    @@ -790,10 +826,11 @@ class Tva extends CommonObject
     	 * @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 du statut
     	 */
    -	function LibStatut($status,$mode=0)
    -	{
    -	    global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
    +    function LibStatut($status,$mode=0)
    +    {
    +        // phpcs:enable
    +        global $langs;	// TODO Renvoyer le libelle anglais et faire traduction a affichage
     
    -	    return '';
    -	}
    +        return '';
    +    }
     }
    diff --git a/htdocs/compta/tva/clients.php b/htdocs/compta/tva/clients.php
    index ae95d71ca9c..74a08d0d142 100644
    --- a/htdocs/compta/tva/clients.php
    +++ b/htdocs/compta/tva/clients.php
    @@ -3,7 +3,8 @@
      * Copyright (C) 2004      Eric Seigne          <eric.seigne@ryxeo.com>
      * Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2006      Yannick Warnier      <ywarnier@beeznest.org>
    - * Copyright (C) 2014	   Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2014       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -136,18 +137,22 @@ if ($modetax == 1) $calcmode=$langs->trans('OptionVATDebitOption');
     if ($modetax == 2) $calcmode=$langs->trans('OptionPaymentForProductAndServices');
     $calcmode.='<br>('.$langs->trans("TaxModuleSetupToModifyRules",DOL_URL_ROOT.'/admin/taxes.php').')';
     // Set period
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    -$prevyear=$year_start; $prevquarter=$q;
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
    +$prevyear=$year_start;
    +$prevquarter=$q;
     if ($prevquarter > 1) {
     	$prevquarter--;
     } else {
    -	$prevquarter=4; $prevyear--;
    +    $prevquarter=4;
    +    $prevyear--;
     }
    -$nextyear=$year_start; $nextquarter=$q;
    +$nextyear=$year_start;
    +$nextquarter=$q;
     if ($nextquarter < 4) {
     	$nextquarter++;
     } else {
    -	$nextquarter=1; $nextyear++;
    +    $nextquarter=1;
    +    $nextyear++;
     }
     $builddate=dol_now();
     
    diff --git a/htdocs/compta/tva/document.php b/htdocs/compta/tva/document.php
    index b83cad80bdd..790058c20a9 100644
    --- a/htdocs/compta/tva/document.php
    +++ b/htdocs/compta/tva/document.php
    @@ -122,7 +122,7 @@ if ($object->id)
     	print '<div class="fichecenter">';
     	print '<div class="underbanner clearboth"></div>';
     
    -    // Construit liste des fichiers
    +    // Build file list
         $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
         $totalsize=0;
         foreach($filearray as $key => $file)
    diff --git a/htdocs/compta/tva/index.php b/htdocs/compta/tva/index.php
    index 7c4912411f6..8e4fccf4168 100644
    --- a/htdocs/compta/tva/index.php
    +++ b/htdocs/compta/tva/index.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2014      Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -217,7 +218,7 @@ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
     }
     if (! empty($conf->global->MAIN_MODULE_ACCOUNTING)) $description.='<br>'.$langs->trans("ThisIsAnEstimatedValue");
     
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     
     $builddate=dol_now();
     
    diff --git a/htdocs/compta/tva/quadri_detail.php b/htdocs/compta/tva/quadri_detail.php
    index e2c7cc5d793..ff3e3ce127d 100644
    --- a/htdocs/compta/tva/quadri_detail.php
    +++ b/htdocs/compta/tva/quadri_detail.php
    @@ -1,9 +1,10 @@
     <?php
    -/* Copyright (C) 2001-2003        Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004             Eric Seigne          <eric.seigne@ryxeo.com>
    - * Copyright (C) 2004-2013        Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2006-2007, 2015  Yannick Warnier      <ywarnier@beeznest.org>
    - * Copyright (C) 2014	          Ferran Marcet        <fmarcet@2byte.es>
    +/* Copyright (C) 2001-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004       Eric Seigne             <eric.seigne@ryxeo.com>
    + * Copyright (C) 2004-2013  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2006-2015  Yannick Warnier         <ywarnier@beeznest.org>
    + * Copyright (C) 2014       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -135,18 +136,21 @@ if ($modetax == 1) $calcmode=$langs->trans('OptionVATDebitOption');
     if ($modetax == 2) $calcmode=$langs->trans('OptionPaymentForProductAndServices');
     $calcmode.='<br>('.$langs->trans("TaxModuleSetupToModifyRules",DOL_URL_ROOT.'/admin/taxes.php').')';
     // Set period
    -$period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1);
    +$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     $prevyear=$year_start; $prevquarter=$q;
     if ($prevquarter > 1) {
     	$prevquarter--;
     } else {
    -	$prevquarter=4; $prevyear--;
    +    $prevquarter=4;
    +    $prevyear--;
     }
    -$nextyear=$year_start; $nextquarter=$q;
    +$nextyear=$year_start;
    +$nextquarter=$q;
     if ($nextquarter < 4) {
     	$nextquarter++;
     } else {
    -	$nextquarter=1; $nextyear++;
    +    $nextquarter=1;
    +    $nextyear++;
     }
     $description.=$fsearch;
     $builddate=dol_now();
    diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example
    index 7475cf54ddb..886a6171818 100644
    --- a/htdocs/conf/conf.php.example
    +++ b/htdocs/conf/conf.php.example
    @@ -14,7 +14,7 @@
     // dolibarr_main_url_root
     // This parameter defines the root URL of your Dolibarr index.php page without ending "/".
     // It must link to the directory htdocs.
    -// In most cases, this is autodetected but it's still required 
    +// In most cases, this is autodetected but it's still required
     // * to show full url bookmarks for some services (ie: agenda rss export url, ...)
     // * or when using Apache dir aliases (autodetect fails)
     // * or when using nginx (autodetect fails)
    @@ -40,7 +40,7 @@ $dolibarr_main_document_root='';
     // dolibarr_main_url_root_alt
     // This parameter defines the relative sub URLs to add to $dolibarr_main_url_root to
     // forge alternative root directories (used by modules developers).
    -// You can put several values, separated by a coma, but number of entries must match 
    +// You can put several values, separated by a coma, but number of entries must match
     // number of entries into $dolibarr_main_document_root_alt.
     // Examples:
     // $dolibarr_main_url_root_alt='/custom';
    @@ -52,7 +52,7 @@ $dolibarr_main_document_root='';
     // dolibarr_main_document_root_alt
     // This parameter contains absolute alternative root file system directories (used by
     // modules developers).
    -// You can put several values, separated by a coma, but number of entries must match 
    +// You can put several values, separated by a coma, but number of entries must match
     // number of entries into $dolibarr_main_url_root_alt.
     // Examples:
     // $dolibarr_main_document_root_alt='/var/www/dolibarr/htdocs/custom';
    @@ -162,7 +162,7 @@ $dolibarr_main_db_collation='utf8_unicode_ci';
     // Default value: dolibarr
     // Possible values: Any values found in files in htdocs/core/login directory after
     // the "function_" string and before the ".php" string. You can also separate several
    -// values using a ",". In this case, Dolibarr will check login/pass for each value in 
    +// values using a ",". In this case, Dolibarr will check login/pass for each value in
     // order defined into value. However, note that this can't work with all values.
     // Examples:
     // $dolibarr_main_authentication='http';
    @@ -207,10 +207,10 @@ $dolibarr_main_authentication='dolibarr';
     // 0 = No forced redirect
     // 1 = Force redirect to https, until SCRIPT_URI start with https into response
     // 2 = Force redirect to https, until SERVER["HTTPS"] is 'on' into response
    -// 'https://my.domain.com' = Force reditect to https using this domain name. 
    +// 'https://my.domain.com' = Force reditect to https using this domain name.
     // Warning: If you enable this parameter, your web server must be configured to
    -// respond URL with https protocol. 
    -// According to your web server setup, some values may works and other not. Try 
    +// respond URL with https protocol.
    +// According to your web server setup, some values may works and other not. Try
     // different values (1,2 or 'https://my.domain.com') if you experience problems.
     // Default value: 0
     // Possible values: 0, 1, 2 or 'https://my.domain.com'
    diff --git a/htdocs/contact/canvas/actions_contactcard_common.class.php b/htdocs/contact/canvas/actions_contactcard_common.class.php
    index ba96c865d1a..7e413854846 100644
    --- a/htdocs/contact/canvas/actions_contactcard_common.class.php
    +++ b/htdocs/contact/canvas/actions_contactcard_common.class.php
    @@ -27,7 +27,11 @@
      */
     abstract class ActionsContactCardCommon
     {
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
         var $dirmodule;
         var $targetmodule;
         var $canvas;
    @@ -37,10 +41,17 @@ abstract class ActionsContactCardCommon
     	var $tpl = array();
     	//! Object container
     	var $object;
    -	//! Error string
    -	var $error;
    -	//! Error array
    -	var $errors=array();
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
     
     	/**
    @@ -65,7 +76,8 @@ abstract class ActionsContactCardCommon
         	//}
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Set content of ->tpl array, to use into template
          *
          *  @param	string		$action    Type of action
    @@ -74,6 +86,7 @@ abstract class ActionsContactCardCommon
          */
         function assign_values(&$action, $id)
         {
    +        // phpcs:enable
             global $conf, $langs, $user, $canvas;
             global $form, $formcompany, $objsoc;
     
    @@ -254,6 +267,7 @@ abstract class ActionsContactCardCommon
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          *  Assign POST values into object
          *
    @@ -261,31 +275,32 @@ abstract class ActionsContactCardCommon
          */
         private function assign_post()
         {
    +        // phpcs:enable
             global $langs, $mysoc;
     
    -        $this->object->old_name 			= 	$_POST["old_name"];
    -        $this->object->old_firstname 		= 	$_POST["old_firstname"];
    +        $this->object->old_name 		= $_POST["old_name"];
    +        $this->object->old_firstname 	= $_POST["old_firstname"];
     
    -        $this->object->socid				=	$_POST["socid"];
    -        $this->object->lastname				=	$_POST["name"];
    -        $this->object->firstname			= 	$_POST["firstname"];
    -        $this->object->civility_id			= 	$_POST["civility_id"];
    -        $this->object->poste				= 	$_POST["poste"];
    -        $this->object->address				=	$_POST["address"];
    -        $this->object->zip					=	$_POST["zipcode"];
    -        $this->object->town					=	$_POST["town"];
    -        $this->object->fk_departement		=	$_POST["state_id"];
    -        $this->object->country_id			=	$_POST["country_id"]?$_POST["country_id"]:$mysoc->country_id;
    -        $this->object->state_id        		=	$_POST["state_id"];
    -        $this->object->phone_pro			= 	$_POST["phone_pro"];
    -        $this->object->phone_perso			= 	$_POST["phone_perso"];
    -        $this->object->phone_mobile			= 	$_POST["phone_mobile"];
    -        $this->object->fax					=	$_POST["fax"];
    -        $this->object->email				=	$_POST["email"];
    -        $this->object->jabberid				= 	$_POST["jabberid"];
    -        $this->object->priv					= 	$_POST["priv"];
    -        $this->object->note					=	$_POST["note"];
    -        $this->object->canvas				=	$_POST["canvas"];
    +        $this->object->socid			= $_POST["socid"];
    +        $this->object->lastname			= $_POST["name"];
    +        $this->object->firstname		= $_POST["firstname"];
    +        $this->object->civility_id		= $_POST["civility_id"];
    +        $this->object->poste			= $_POST["poste"];
    +        $this->object->address			= $_POST["address"];
    +        $this->object->zip				= $_POST["zipcode"];
    +        $this->object->town				= $_POST["town"];
    +        $this->object->fk_departement	= $_POST["state_id"];
    +        $this->object->country_id		= $_POST["country_id"]?$_POST["country_id"]:$mysoc->country_id;
    +        $this->object->state_id        	= $_POST["state_id"];
    +        $this->object->phone_pro		= $_POST["phone_pro"];
    +        $this->object->phone_perso		= $_POST["phone_perso"];
    +        $this->object->phone_mobile		= $_POST["phone_mobile"];
    +        $this->object->fax				= $_POST["fax"];
    +        $this->object->email			= $_POST["email"];
    +        $this->object->jabberid			= $_POST["jabberid"];
    +        $this->object->priv				= $_POST["priv"];
    +        $this->object->note				= $_POST["note"];
    +        $this->object->canvas			= $_POST["canvas"];
     
             // We set country_id, and country_code label of the chosen country
             if ($this->object->country_id)
    @@ -305,6 +320,4 @@ abstract class ActionsContactCardCommon
                 $this->object->country		=	$langs->trans("Country".$obj->code)?$langs->trans("Country".$obj->code):$obj->label;
             }
         }
    -
     }
    -
    diff --git a/htdocs/contact/canvas/default/actions_contactcard_default.class.php b/htdocs/contact/canvas/default/actions_contactcard_default.class.php
    index bfcb5a21142..5831b943d76 100644
    --- a/htdocs/contact/canvas/default/actions_contactcard_default.class.php
    +++ b/htdocs/contact/canvas/default/actions_contactcard_default.class.php
    @@ -29,8 +29,8 @@ include_once DOL_DOCUMENT_ROOT.'/contact/canvas/actions_contactcard_common.class
      */
     class ActionsContactCardDefault extends ActionsContactCardCommon
     {
    -	/**
    -     *	Constructor
    +    /**
    +     *  Constructor
          *
          *	@param	DoliDB	$db				Handler acces base de donnees
          *	@param	string	$dirmodule		Name of directory of module
    @@ -66,6 +66,7 @@ class ActionsContactCardDefault extends ActionsContactCardCommon
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Assign custom values for canvas
     	 *
    @@ -75,6 +76,7 @@ class ActionsContactCardDefault extends ActionsContactCardCommon
     	 */
     	function assign_values(&$action, $id)
     	{
    +        // phpcs:enable
     		global $limit, $offset, $sortfield, $sortorder;
     		global $conf, $db, $langs, $user;
     		global $form;
    @@ -116,10 +118,10 @@ class ActionsContactCardDefault extends ActionsContactCardCommon
     		{
     	        $this->LoadListDatas($limit, $offset, $sortfield, $sortorder);
     		}
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Fetch datas list and save into ->list_datas
     	 *
    @@ -131,6 +133,7 @@ class ActionsContactCardDefault extends ActionsContactCardCommon
     	 */
     	function LoadListDatas($limit, $offset, $sortfield, $sortorder)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
             //$this->getFieldList();
    @@ -138,4 +141,3 @@ class ActionsContactCardDefault extends ActionsContactCardCommon
             $this->list_datas = array();
     	}
     }
    -
    diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php
    index 52957d25343..a43127c9a32 100644
    --- a/htdocs/contact/card.php
    +++ b/htdocs/contact/card.php
    @@ -1,13 +1,14 @@
     <?php
    -/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2004      Benoit Mortier       <benoit.mortier@opensides.be>
    - * Copyright (C) 2005-2017 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
    - * Copyright (C) 2013      Florian Henry		<florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2016 Alexandre Spangaro 	<aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2014      Juanjo Menent	 	<jmenent@2byte.es>
    - * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
    +/* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
    + * Copyright (C) 2005-2017  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2007       Franky Van Liedekerke   <franky.van.liedekerke@telenet.be>
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2016  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2014       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -185,6 +186,8 @@ if (empty($reshook))
             $object->country_id		= GETPOST("country_id",'int');
             $object->state_id		= GETPOST("state_id",'int');
             $object->skype			= GETPOST("skype",'alpha');
    +        $object->twitter		= GETPOST("twitter",'alpha');
    +        $object->facebook		= GETPOST("facebook",'alpha');
             $object->email			= GETPOST("email",'alpha');
             $object->phone_pro		= GETPOST("phone_pro",'alpha');
             $object->phone_perso	= GETPOST("phone_perso",'alpha');
    @@ -357,6 +360,8 @@ if (empty($reshook))
     
                 $object->email			= GETPOST("email",'alpha');
                 $object->skype			= GETPOST("skype",'alpha');
    +            $object->twitter		= GETPOST("twitter",'alpha');
    +            $object->facebook		= GETPOST("facebook",'alpha');
                 $object->phone_pro		= GETPOST("phone_pro",'alpha');
                 $object->phone_perso	= GETPOST("phone_perso",'alpha');
                 $object->phone_mobile	= GETPOST("phone_mobile",'alpha');
    @@ -657,13 +662,28 @@ else
     
                 // Instant message and no email
                 print '<tr><td><label for="jabberid">'.$langs->trans("IM").'</label></td>';
    -            print '<td colspan="3"><input name="jabberid" id="jabberid" type="text" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOST("jabberid",'alpha')?GETPOST("jabberid",'alpha'):$object->jabberid).'"></td></tr>';
    +            print '<td colspan="3"><input name="jabberid" id="jabberid" type="text" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOSTISSET("jabberid")?GETPOST("jabberid",'alpha'):$object->jabberid).'"></td></tr>';
     
    -            // Skype
    -            if (! empty($conf->skype->enabled))
    +            if (! empty($conf->socialnetworks->enabled))
                 {
    -                print '<tr><td><label for="skype">'.$langs->trans("Skype").'</label></td>';
    -                print '<td colspan="3"><input name="skype" id="skype" type="text" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOST("skype",'alpha')?GETPOST("skype",'alpha'):$object->skype).'"></td></tr>';
    +            	// Skype
    +            	if (! empty($conf->global->SOCIALNETWORKS_SKYPE))
    +            	{
    +            		print '<tr><td><label for="skype">'.fieldLabel('Skype','skype').'</label></td>';
    +            		print '<td colspan="3"><input type="text" name="skype" id="skype" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOSTISSET("skype")?GETPOST("skype",'alpha'):$object->skype).'"></td></tr>';
    +            	}
    +            	// Twitter
    +            	if (! empty($conf->global->SOCIALNETWORKS_TWITTER))
    +            	{
    +            		print '<tr><td><label for="twitter">'.fieldLabel('Twitter','twitter').'</label></td>';
    +            		print '<td colspan="3"><input type="text" name="twitter" id="twitter" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOSTISSET("twitter")?GETPOST("twitter",'alpha'):$object->twitter).'"></td></tr>';
    +            	}
    +            	// Facebook
    +            	if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK))
    +            	{
    +            		print '<tr><td><label for="facebook">'.fieldLabel('Facebook','facebook').'</label></td>';
    +            		print '<td colspan="3"><input type="text" name="facebook" id="facebook" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOSTISSET("facebook")?GETPOST("facebook",'alpha'):$object->facebook).'"></td></tr>';
    +            	}
                 }
     
                 // Visibility
    @@ -704,11 +724,11 @@ else
                 $form=new Form($db);
                 if ($object->birthday)
                 {
    -                print $form->select_date($object->birthday,'birthday',0,0,0,"perso", 1, 0, 1);
    +                print $form->selectDate($object->birthday, 'birthday', 0, 0, 0, "perso", 1, 0);
                 }
                 else
                 {
    -                print $form->select_date('','birthday',0,0,1,"perso", 1, 0, 1);
    +                print $form->selectDate('', 'birthday', 0, 0, 1, "perso", 1, 0);
                 }
                 print '</td>';
     
    @@ -913,11 +933,26 @@ else
     			}
                 print '</tr>';
     
    -            // Skype
    -            if (! empty($conf->skype->enabled))
    +            if (! empty($conf->socialnetworks->enabled))
                 {
    -                print '<tr><td><label for="skype">'.$langs->trans("Skype").'</label></td>';
    -	            print '<td><input name="skype" id="skype" type="text" class="minwidth100" maxlength="80" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
    +            	// Skype
    +            	if (! empty($conf->global->SOCIALNETWORKS_SKYPE))
    +            	{
    +            		print '<tr><td><label for="skype">'.fieldLabel('Skype','skype').'</label></td>';
    +            		print '<td><input type="text" name="skype" id="skype" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOSTISSET("skype")?GETPOST("skype",'alpha'):$object->skype).'"></td></tr>';
    +            	}
    +            	// Twitter
    +            	if (! empty($conf->global->SOCIALNETWORKS_TWITTER))
    +            	{
    +            		print '<tr><td><label for="twitter">'.fieldLabel('Twitter','twitter').'</label></td>';
    +            		print '<td><input type="text" name="twitter" id="twitter" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOSTISSET("twitter")?GETPOST("twitter",'alpha'):$object->twitter).'"></td></tr>';
    +            	}
    +            	// Facebook
    +            	if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK))
    +            	{
    +            		print '<tr><td><label for="facebook">'.fieldLabel('Facebook','facebook').'</label></td>';
    +            		print '<td><input type="text" name="facebook" id="facebook" class="minwidth100" maxlength="80" value="'.dol_escape_htmltag(GETPOST("facebook")?GETPOST("facebook",'alpha'):$object->facebook).'"></td></tr>';
    +            	}
                 }
     
                 // Visibility
    @@ -1078,7 +1113,6 @@ else
                     else $text.=$langs->trans("UserWillBeInternalUser");
                 }
                 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("CreateDolibarrLogin"),$text,"confirm_create_user",$formquestion,'yes');
    -
             }
     
             $linkback = '<a href="'.DOL_URL_ROOT.'/contact/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
    @@ -1247,7 +1281,6 @@ else
             }
     
             print "</div>";
    -
         }
     }
     
    diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
    index dbf45cfb1a0..b1d83abac77 100644
    --- a/htdocs/contact/class/contact.class.php
    +++ b/htdocs/contact/class/contact.class.php
    @@ -37,9 +37,25 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Contact extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='contact';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='socpeople';
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'contact';
     
     
    @@ -88,7 +104,7 @@ class Contact extends CommonObject
     	public $state_code;		    // Code of department
     	public $state;			        // Label of department
     
    -    	public $poste;                 // Position
    +    public $poste;                 // Position
     
     	public $socid;					// fk_soc
     	public $statut;				// 0=inactif, 1=actif
    @@ -123,9 +139,6 @@ class Contact extends CommonObject
     	public $oldcopy;				// To contains a clone of this when we need to save old properties of object
     
     
    -
    -
    -
     	/**
     	 *	Constructor
     	 *
    @@ -137,6 +150,7 @@ class Contact extends CommonObject
     		$this->statut = 1;	// By default, status is enabled
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load indicators into this->nb for board
     	 *
    @@ -144,6 +158,7 @@ class Contact extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $user;
     
     		$this->nb=array();
    @@ -343,6 +358,8 @@ class Contact extends CommonObject
     		$sql .= ", fax='".$this->db->escape($this->fax)."'";
     		$sql .= ", email='".$this->db->escape($this->email)."'";
     		$sql .= ", skype='".$this->db->escape($this->skype)."'";
    +		$sql .= ", twitter='".$this->db->escape($this->twitter)."'";
    +		$sql .= ", facebook='".$this->db->escape($this->facebook)."'";
     		$sql .= ", photo='".$this->db->escape($this->photo)."'";
     		$sql .= ", birthday=".($this->birthday ? "'".$this->db->idate($this->birthday)."'" : "null");
     		$sql .= ", note_private = ".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null");
    @@ -430,6 +447,16 @@ class Contact extends CommonObject
     					$tmpobj->skype = $this->skype;
     					$usermustbemodified++;
     				}
    +				if ($tmpobj->twitter != $this->twitter)
    +				{
    +					$tmpobj->twitter = $this->twitter;
    +					$usermustbemodified++;
    +				}
    +				if ($tmpobj->facebook != $this->facebook)
    +				{
    +					$tmpobj->facebook = $this->facebook;
    +					$usermustbemodified++;
    +				}
     				if ($usermustbemodified)
     				{
     					$result=$tmpobj->update($user, 0, 1, 1, 1);
    @@ -466,6 +493,7 @@ class Contact extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
     	 *
    @@ -477,15 +505,17 @@ class Contact extends CommonObject
     	 */
     	function _load_ldap_dn($info,$mode=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$dn='';
     		if ($mode==0) $dn=$conf->global->LDAP_KEY_CONTACTS."=".$info[$conf->global->LDAP_KEY_CONTACTS].",".$conf->global->LDAP_CONTACT_DN;
    -		if ($mode==1) $dn=$conf->global->LDAP_CONTACT_DN;
    -		if ($mode==2) $dn=$conf->global->LDAP_KEY_CONTACTS."=".$info[$conf->global->LDAP_KEY_CONTACTS];
    +		elseif ($mode==1) $dn=$conf->global->LDAP_CONTACT_DN;
    +		elseif ($mode==2) $dn=$conf->global->LDAP_KEY_CONTACTS."=".$info[$conf->global->LDAP_KEY_CONTACTS];
     		return $dn;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Initialise tableau info (tableau des attributs LDAP)
     	 *
    @@ -493,12 +523,13 @@ class Contact extends CommonObject
     	 */
     	function _load_ldap_info()
     	{
    -		global $conf,$langs;
    +        // phpcs:enable
    +		global $conf, $langs;
     
             $info = array();
     
             // Object classes
    -		$info["objectclass"]=explode(',',$conf->global->LDAP_CONTACT_OBJECT_CLASS);
    +		$info["objectclass"]=explode(',', $conf->global->LDAP_CONTACT_OBJECT_CLASS);
     
     		$this->fullname=$this->getFullName($langs);
     
    @@ -559,6 +590,7 @@ class Contact extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update field alert birthday
     	 *
    @@ -569,6 +601,7 @@ class Contact extends CommonObject
     	 */
     	function update_perso($id, $user=null, $notrigger=0)
     	{
    +        // phpcs:enable
     	    $error=0;
     	    $result=false;
     
    @@ -673,7 +706,7 @@ class Contact extends CommonObject
     		$sql.= " c.fk_pays as country_id,";
     		$sql.= " c.fk_departement,";
     		$sql.= " c.birthday,";
    -		$sql.= " c.poste, c.phone, c.phone_perso, c.phone_mobile, c.fax, c.email, c.jabberid, c.skype,";
    +		$sql.= " c.poste, c.phone, c.phone_perso, c.phone_mobile, c.fax, c.email, c.jabberid, c.skype, c.twitter, c.facebook,";
             $sql.= " c.photo,";
     		$sql.= " c.priv, c.note_private, c.note_public, c.default_lang, c.no_email, c.canvas,";
     		$sql.= " c.import_key,";
    @@ -714,7 +747,7 @@ class Contact extends CommonObject
     
     				$this->date_creation     = $this->db->jdate($obj->date_creation);
     				$this->date_modification = $this->db->jdate($obj->date_modification);
    -				
    +
     				$this->fk_departement	= $obj->fk_departement;    // deprecated
     				$this->state_id			= $obj->fk_departement;
     				$this->departement_code	= $obj->state_code;	       // deprecated
    @@ -739,6 +772,8 @@ class Contact extends CommonObject
     				$this->email				= $obj->email;
     				$this->jabberid			= $obj->jabberid;
     				$this->skype				= $obj->skype;
    +				$this->twitter				= $obj->twitter;
    +				$this->facebook				= $obj->facebook;
     				$this->photo				= $obj->photo;
     				$this->priv				= $obj->priv;
     				$this->mail				= $obj->email;
    @@ -840,6 +875,7 @@ class Contact extends CommonObject
         	}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load number of elements the contact is used as a link for
     	 *  ref_facturation
    @@ -851,6 +887,7 @@ class Contact extends CommonObject
     	 */
     	function load_ref_elements()
     	{
    +        // phpcs:enable
     		// Compte les elements pour lesquels il est contact
     		$sql ="SELECT tc.element, count(ec.rowid) as nb";
     		$sql.=" FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc";
    @@ -869,9 +906,9 @@ class Contact extends CommonObject
     				if ($obj->nb)
     				{
     					if ($obj->element=='facture')  $this->ref_facturation = $obj->nb;
    -					if ($obj->element=='contrat')  $this->ref_contrat = $obj->nb;
    -					if ($obj->element=='commande') $this->ref_commande = $obj->nb;
    -					if ($obj->element=='propal')   $this->ref_propal = $obj->nb;
    +					elseif ($obj->element=='contrat')  $this->ref_contrat = $obj->nb;
    +					elseif ($obj->element=='commande') $this->ref_commande = $obj->nb;
    +					elseif ($obj->element=='propal')   $this->ref_propal = $obj->nb;
     				}
     			}
     			$this->db->free($resql);
    @@ -896,8 +933,8 @@ class Contact extends CommonObject
     
     		$error=0;
     
    -		$this->old_lastname       = $obj->lastname;
    -		$this->old_firstname      = $obj->firstname;
    +		$this->old_lastname = $obj->lastname;
    +		$this->old_firstname = $obj->firstname;
     
     		$this->db->begin();
     
    @@ -1017,7 +1054,7 @@ class Contact extends CommonObject
     			{
     				$obj = $this->db->fetch_object($resql);
     
    -				$this->id                = $obj->rowid;
    +				$this->id = $obj->rowid;
     
     				if ($obj->fk_user_creat) {
     					$cuser = new User($this->db);
    @@ -1182,6 +1219,7 @@ class Contact extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoi le libelle d'un statut donne
     	 *
    @@ -1191,6 +1229,7 @@ class Contact extends CommonObject
     	 */
     	function LibStatut($statut,$mode)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
    @@ -1207,7 +1246,6 @@ class Contact extends CommonObject
     		{
     			if ($statut==0 || $statut==5) return img_picto($langs->trans('Disabled'),'statut5', 'class="pictostatus"').' '.$langs->trans('Disabled');
     			elseif ($statut==1 || $statut==4) return img_picto($langs->trans('Enabled'),'statut4', 'class="pictostatus"').' '.$langs->trans('Enabled');
    -
     		}
     		elseif ($mode == 3)
     		{
    @@ -1227,6 +1265,7 @@ class Contact extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return translated label of Public or Private
     	 *
    @@ -1235,6 +1274,7 @@ class Contact extends CommonObject
     	 */
     	function LibPubPriv($statut)
     	{
    +        // phpcs:enable
     		global $langs;
     		if ($statut=='1') return $langs->trans('ContactPrivate');
     		else return $langs->trans('ContactPublic');
    @@ -1339,6 +1379,7 @@ class Contact extends CommonObject
     	 * Existing categories are left untouch.
     	 *
     	 * @param int[]|int $categories Category or categories IDs
    +     * @return void
     	 */
     	public function setCategories($categories)
     	{
    diff --git a/htdocs/contact/document.php b/htdocs/contact/document.php
    index 1a60ddaaccb..07795da30d0 100644
    --- a/htdocs/contact/document.php
    +++ b/htdocs/contact/document.php
    @@ -97,7 +97,7 @@ if ($object->id)
         dol_fiche_head($head, 'documents', $title, -1, 'contact');
     
     
    -    // Construit liste des fichiers
    +    // Build file list
         $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
         $totalsize=0;
         foreach($filearray as $key => $file)
    diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
    index 04132fa9b75..52a2c4bbe7f 100644
    --- a/htdocs/contact/list.php
    +++ b/htdocs/contact/list.php
    @@ -68,6 +68,8 @@ $search_phone_mobile=GETPOST("search_phone_mobile",'alpha');
     $search_fax=GETPOST("search_fax",'alpha');
     $search_email=GETPOST("search_email",'alpha');
     $search_skype=GETPOST("search_skype",'alpha');
    +$search_twitter=GETPOST("search_twitter",'alpha');
    +$search_facebook=GETPOST("search_facebook",'alpha');
     $search_priv=GETPOST("search_priv",'alpha');
     $search_categ=GETPOST("search_categ",'int');
     $search_categ_thirdparty=GETPOST("search_categ_thirdparty",'int');
    @@ -156,7 +158,9 @@ $arrayfields=array(
     	'p.phone_mobile'=>array('label'=>"PhoneMobile", 'checked'=>1),
     	'p.fax'=>array('label'=>"Fax", 'checked'=>0),
     	'p.email'=>array('label'=>"EMail", 'checked'=>1),
    -	'p.skype'=>array('label'=>"Skype", 'checked'=>1, 'enabled'=>(! empty($conf->skype->enabled))),
    +	'p.skype'=>array('label'=>"Skype", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
    +	'p.twitter'=>array('label'=>"Twitter", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
    +	'p.facebook'=>array('label'=>"Facebook", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
     	'p.thirdparty'=>array('label'=>"ThirdParty", 'checked'=>1, 'enabled'=>empty($conf->global->SOCIETE_DISABLE_CONTACTS)),
     	'p.priv'=>array('label'=>"ContactVisibility", 'checked'=>1, 'position'=>200),
     	'p.datec'=>array('label'=>"DateCreationShort", 'checked'=>0, 'position'=>500),
    @@ -198,7 +202,7 @@ if (empty($reshook))
     	include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
     
     	// Did we click on purge search criteria ?
    -	if (GETPOST('button_removefilter_x') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter'))	// All tests are required to be compatible with all browsers
    +	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
     	{
     		$sall="";
     		$search_id='';
    @@ -217,6 +221,8 @@ if (empty($reshook))
     		$search_fax="";
     		$search_email="";
     		$search_skype="";
    +		$search_twitter="";
    +		$search_facebook="";
     		$search_priv="";
     		$search_status=-1;
     		$search_categ='';
    @@ -311,6 +317,8 @@ if (strlen($search_phone_pro))      $sql.= natural_search('p.phone', $search_pho
     if (strlen($search_phone_mobile))   $sql.= natural_search('p.phone_mobile', $search_phone_mobile);
     if (strlen($search_fax))            $sql.= natural_search('p.fax', $search_fax);
     if (strlen($search_skype))          $sql.= natural_search('p.skype', $search_skype);
    +if (strlen($search_twitter))        $sql.= natural_search('p.twitter', $search_twitter);
    +if (strlen($search_facebook))       $sql.= natural_search('p.facebook', $search_facebook);
     if (strlen($search_email))          $sql.= natural_search('p.email', $search_email);
     if (strlen($search_zip))   			$sql.= natural_search("p.zip",$search_zip);
     if ($search_status != '' && $search_status >= 0) $sql.= " AND p.statut = ".$db->escape($search_status);
    @@ -601,6 +609,18 @@ if (! empty($arrayfields['p.skype']['checked']))
     	print '<input class="flat" type="text" name="search_skype" size="6" value="'.dol_escape_htmltag($search_skype).'">';
     	print '</td>';
     }
    +if (! empty($arrayfields['p.twitter']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat" type="text" name="search_twitter" size="6" value="'.dol_escape_htmltag($search_twitter).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['p.facebook']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat" type="text" name="search_facebook" size="6" value="'.dol_escape_htmltag($search_facebook).'">';
    +	print '</td>';
    +}
     if (! empty($arrayfields['p.thirdparty']['checked']))
     {
     	print '<td class="liste_titre">';
    @@ -671,6 +691,8 @@ if (! empty($arrayfields['p.phone_mobile']['checked']))        print_liste_field
     if (! empty($arrayfields['p.fax']['checked']))                 print_liste_field_titre($arrayfields['p.fax']['label'],$_SERVER["PHP_SELF"],"p.fax", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.email']['checked']))               print_liste_field_titre($arrayfields['p.email']['label'],$_SERVER["PHP_SELF"],"p.email", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.skype']['checked']))               print_liste_field_titre($arrayfields['p.skype']['label'],$_SERVER["PHP_SELF"],"p.skype", $begin, $param, '', $sortfield,$sortorder);
    +if (! empty($arrayfields['p.twitter']['checked']))             print_liste_field_titre($arrayfields['p.twitter']['label'],$_SERVER["PHP_SELF"],"p.twitter", $begin, $param, '', $sortfield,$sortorder);
    +if (! empty($arrayfields['p.facebook']['checked']))            print_liste_field_titre($arrayfields['p.facebook']['label'],$_SERVER["PHP_SELF"],"p.facebook", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.thirdparty']['checked']))          print_liste_field_titre($arrayfields['p.thirdparty']['label'],$_SERVER["PHP_SELF"],"s.nom", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.priv']['checked']))                print_liste_field_titre($arrayfields['p.priv']['label'],$_SERVER["PHP_SELF"],"p.priv", $begin, $param, 'align="center"', $sortfield,$sortorder);
     // Extra fields
    @@ -801,7 +823,19 @@ while ($i < min($num,$limit))
     	// Skype
     	if (! empty($arrayfields['p.skype']['checked']))
     	{
    -		if (! empty($conf->skype->enabled)) { print '<td>'.dol_print_skype($obj->skype,$obj->rowid,$obj->socid,'AC_SKYPE',18).'</td>'; }
    +		if (! empty($conf->socialnetworks->enabled)) { print '<td>'.dol_print_socialnetworks($obj->skype,$obj->rowid,$obj->socid,'skype').'</td>'; }
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Twitter
    +	if (! empty($arrayfields['p.twitter']['checked']))
    +	{
    +		if (! empty($conf->socialnetworks->enabled)) { print '<td>'.dol_print_socialnetworks($obj->twitter,$obj->rowid,$obj->socid,'twitter').'</td>'; }
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Facebook
    +	if (! empty($arrayfields['p.facebook']['checked']))
    +	{
    +		if (! empty($conf->socialnetworks->enabled)) { print '<td>'.dol_print_socialnetworks($obj->facebook,$obj->rowid,$obj->socid,'facebook').'</td>'; }
     		if (! $i) $totalarray['nbfield']++;
     	}
     	// Company
    diff --git a/htdocs/contact/perso.php b/htdocs/contact/perso.php
    index 3e5ec085132..4932d549df4 100644
    --- a/htdocs/contact/perso.php
    +++ b/htdocs/contact/perso.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2004       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2011  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -199,7 +200,7 @@ if ($action == 'edit')
         // Date To Birth
         print '<tr><td>'.$langs->trans("DateToBirth").'</td><td>';
         $form=new Form($db);
    -    print $form->select_date($object->birthday,'birthday',0,0,1,"perso", 1,0,1);
    +    print $form->selectDate($object->birthday, 'birthday', 0, 0, 1, "perso", 1,0);
         print '</td>';
     
         print '<td colspan="2">'.$langs->trans("Alert").': ';
    diff --git a/htdocs/contrat/admin/contract_extrafields.php b/htdocs/contrat/admin/contract_extrafields.php
    index b9b0d51c162..d19c91e0bf2 100644
    --- a/htdocs/contrat/admin/contract_extrafields.php
    +++ b/htdocs/contrat/admin/contract_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,7 +94,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -	print '<div name="topofform"></div><br>';
    +	print '<br><div name="topofform" id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    diff --git a/htdocs/contrat/admin/contractdet_extrafields.php b/htdocs/contrat/admin/contractdet_extrafields.php
    index 42a8ed589d7..af2585eaf3a 100644
    --- a/htdocs/contrat/admin/contractdet_extrafields.php
    +++ b/htdocs/contrat/admin/contractdet_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,8 +94,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php
    index 5f418cb0568..0c0247dc7fa 100644
    --- a/htdocs/contrat/card.php
    +++ b/htdocs/contrat/card.php
    @@ -1,14 +1,15 @@
     <?php
    -/* Copyright (C) 2003-2004	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2014	Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2014	Regis Houssin			<regis.houssin@capnetworks.com>
    - * Copyright (C) 2006		Andre Cianfarani		<acianfa@free.fr>
    - * Copyright (C) 2010-2017	Juanjo Menent			<jmenent@2byte.es>
    +/* Copyright (C) 2003-2004  Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2014  Laurent Destailleur		<eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2014  Regis Houssin			<regis.houssin@capnetworks.com>
    + * Copyright (C) 2006       Andre Cianfarani		<acianfa@free.fr>
    + * Copyright (C) 2010-2017  Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2013       Christophe Battarel     <christophe.battarel@altairis.fr>
      * Copyright (C) 2013-2014  Florian Henry		  	<florian.henry@open-concept.pro>
      * Copyright (C) 2014-2018	Ferran Marcet		  	<fmarcet@2byte.es>
      * Copyright (C) 2014-2016  Marcos García           <marcosgdf@gmail.com>
    - * Copyright (C) 2015       Jean-François Ferry		<jfefe@aternatik.fr>
    + * Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,7 +31,7 @@
      *       \brief      Page of a contract
      */
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
    @@ -565,7 +566,7 @@ if (empty($reshook))
     			$info_bits=0;
     			if ($tva_npr) $info_bits |= 0x01;
     
    -			if($price_min && (price2num($pu_ht)*(1-price2num($remise_percent)/100) < price2num($price_min)))
    +			if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& ($price_min && (price2num($pu_ht)*(1-price2num($remise_percent)/100) < price2num($price_min))))
     			{
     				$object->error = $langs->trans("CantBeLessThanMinPrice",price(price2num($price_min,'MU'),0,$langs,0,0,-1,$conf->currency));
     				$result = -1 ;
    @@ -1242,7 +1243,7 @@ if ($action == 'create')
     	print '</td></tr>';
     
     	print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td>';
    -	$form->select_date($datecontrat,'',0,0,'',"contrat");
    +	print $form->selectDate($datecontrat, '', 0, 0, '', "contrat");
     	print "</td></tr>";
     
     	// Project
    @@ -1317,8 +1318,10 @@ else
     	{
     		$object->fetch_thirdparty();
     
    -		$result=$object->fetch_lines();	// This also init $this->nbofserviceswait, $this->nbofservicesopened, $this->nbofservicesexpired=, $this->nbofservicesclosed
    -		if ($result < 0) dol_print_error($db,$object->error);
    +		$result=$object->fetch_lines(); // This also init $this->nbofserviceswait, $this->nbofservicesopened, $this->nbofservicesexpired=, $this->nbofservicesclosed
    +		if ($result < 0) {
    +            dol_print_error($db,$object->error);
    +        }
     
     		$nbofservices=count($object->lines);
     
    @@ -1333,56 +1336,54 @@ else
     
     		$head = contract_prepare_head($object);
     
    -		$hselected = 0;
    +        $hselected = 0;
    +        $formconfirm = '';
     
    -		dol_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract');
    +        dol_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract');
     
     
    -		/*
    -         * Confirmation de la suppression du contrat
    -         */
    -		if ($action == 'delete')
    -		{
    -			print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("DeleteAContract"),$langs->trans("ConfirmDeleteAContract"),"confirm_delete",'',0,1);
    +        if ($action == 'delete') {
    +            //Confirmation de la suppression du contrat
    +            $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("DeleteAContract"),$langs->trans("ConfirmDeleteAContract"),"confirm_delete",'',0,1);
    +        } elseif ($action == 'valid') {
    +            //Confirmation de la validation
    +            $ref = substr($object->ref, 1, 4);
    +            if ($ref == 'PROV' && !empty($modCodeContract->code_auto)) {
    +                $numref = $object->getNextNumRef($object->thirdparty);
    +            } else {
    +                $numref = $object->ref;
    +            }
    +            $text = $langs->trans('ConfirmValidateContract',$numref);
    +            $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ValidateAContract"),$text,"confirm_valid",'',0,1);
    +        } elseif ($action == 'close') {
    +            // Confirmation de la fermeture
    +            $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("CloseAContract"),$langs->trans("ConfirmCloseContract"),"confirm_close",'',0,1);
    +        } elseif ($action == 'activate') {
    +            $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ActivateAllOnContract"),$langs->trans("ConfirmActivateAllOnContract"),"confirm_activate",'',0,1);
    +        } elseif ($action == 'clone') {
    +            // Clone confirmation
    +            $formquestion = array(array('type' => 'other','name' => 'socid','label' => $langs->trans("SelectThirdParty"),'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')));
    +            $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('CloneContract'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
    +        }
     
    -		}
     
    -		/*
    -         * Confirmation de la validation
    -         */
    -		if ($action == 'valid')
    -		{
    -			$ref = substr($object->ref, 1, 4);
    -			if ($ref == 'PROV' && !empty($modCodeContract->code_auto))
    -			{
    -				$numref = $object->getNextNumRef($object->thirdparty);
    -			}
    -			else
    -			{
    -				$numref = $object->ref;
    -			}
    +        // Call Hook formConfirm
    +        $parameters = array(
    +            'id' => $id,
    +            //'lineid' => $lineid,
    +        );
    +        // Note that $action and $object may have been modified by hook
    +        $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
    +        if (empty($reshook)) {
    +            $formconfirm .= $hookmanager->resPrint;
    +        } elseif ($reshook > 0) {
    +            $formconfirm = $hookmanager->resPrint;
    +        }
     
    -			$text=$langs->trans('ConfirmValidateContract',$numref);
    +        // Print form confirm
    +        print $formconfirm;
     
    -			print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ValidateAContract"),$text,"confirm_valid",'',0,1);
    -
    -		}
    -
    -		/*
    -         * Confirmation de la fermeture
    -         */
    -		if ($action == 'close')
    -		{
    -			print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("CloseAContract"),$langs->trans("ConfirmCloseContract"),"confirm_close",'',0,1);
    -
    -		}
    -		if ($action == 'activate')
    -		{
    -			print $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id,$langs->trans("ActivateAllOnContract"),$langs->trans("ConfirmActivateAllOnContract"),"confirm_activate",'',0,1);
    -
    -		}
    -
    -		/*
    +        /*
              *   Contrat
              */
     		if (! empty($object->brouillon) && $user->rights->contrat->creer)
    @@ -1392,12 +1393,6 @@ else
     			print '<input type="hidden" name="action" value="setremise">';
     		}
     
    -		// Clone confirmation
    -		if ($action == 'clone') {
    -			$formquestion = array(array('type' => 'other','name' => 'socid','label' => $langs->trans("SelectThirdParty"),'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')));
    -			print $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('CloneContract'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
    -		}
    -
     		// Contract card
     
     		$linkback = '<a href="'.DOL_URL_ROOT.'/contrat/list.php?restore_lastsearch_values=1'.(! empty($socid)?'&socid='.$socid:'').'">'.$langs->trans("BackToList").'</a>';
    @@ -1516,7 +1511,7 @@ else
     		}
     
     
    -		$colorb='666666';
    +		$colorb = '666666';
     
     		$arrayothercontracts=$object->getListOfContracts('others');
     
    @@ -1782,9 +1777,9 @@ else
     					print '<tr class="oddeven">';
     					print '<td colspan="'.$colspan.'">';
     					print $langs->trans("DateStartPlanned").' ';
    -					$form->select_date($db->jdate($objp->date_debut),"date_start_update",$usehm,$usehm,($db->jdate($objp->date_debut)>0?0:1),"update");
    +					print $form->selectDate($db->jdate($objp->date_debut), "date_start_update", $usehm, $usehm, ($db->jdate($objp->date_debut)>0?0:1), "update");
     					print ' &nbsp;&nbsp;'.$langs->trans("DateEndPlanned").' ';
    -					$form->select_date($db->jdate($objp->date_fin),"date_end_update",$usehm,$usehm,($db->jdate($objp->date_fin)>0?0:1),"update");
    +					print $form->selectDate($db->jdate($objp->date_fin), "date_end_update", $usehm, $usehm, ($db->jdate($objp->date_fin)>0?0:1), "update");
     					print '</td>';
     					print '</tr>';
     
    @@ -1967,10 +1962,10 @@ else
     
     				print '<tr class="oddeven">';
     				print '<td class="nohover">'.$langs->trans("DateServiceActivate").'</td><td class="nohover">';
    -				print $form->select_date($dateactstart,'',$usehm,$usehm,'',"active",1,0,1);
    +				print $form->selectDate($dateactstart, '', $usehm, $usehm, '', "active", 1, 0);
     				print '</td>';
     				print '<td class="nohover">'.$langs->trans("DateEndPlanned").'</td><td class="nohover">';
    -				print $form->select_date($dateactend,"end",$usehm,$usehm,'',"active",1,0,1);
    +				print $form->selectDate($dateactend, "end", $usehm, $usehm, '', "active", 1, 0);
     				print '</td>';
     				print '<td class="center nohover">';
     				print '</td>';
    @@ -2028,7 +2023,7 @@ else
     					if ($objp->statut == 4)
     					{
     						print $langs->trans("DateEndReal").' ';
    -						print $form->select_date($dateactend,"end",$usehm,$usehm,($objp->date_fin_reelle>0?0:1),"closeline",1,1,1);
    +						print $form->selectDate($dateactend, "end", $usehm, $usehm, ($objp->date_fin_reelle>0?0:1), "closeline", 1, 1);
     					}
     				}
     				print '</td>';
    diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php
    index 1bb17eb4352..585d5399771 100644
    --- a/htdocs/contrat/class/api_contracts.class.php
    +++ b/htdocs/contrat/class/api_contracts.class.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2015   Jean-François Ferry     <jfefe@aternatik.fr>
      * Copyright (C) 2016	Laurent Destailleur		<eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -55,13 +56,13 @@ class Contracts extends DolibarrApi
         }
     
         /**
    -     * Get properties of a contrat object
    +     * Get properties of a contract object
          *
    -     * Return an array with contrat informations
    +     * Return an array with contract informations
          *
          * @param       int         $id         ID of contract
          * @return 	array|mixed data without useless information
    -	 *
    +     *
          * @throws 	RestException
          */
         function get($id)
    @@ -100,7 +101,8 @@ class Contracts extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -214,27 +216,28 @@ class Contracts extends DolibarrApi
          *
          * @url	GET {id}/lines
          *
    -     * @return int
    +     * @return array
          */
    -    function getLines($id) {
    -      if(! DolibarrApiAccess::$user->rights->contrat->lire) {
    -		  	throw new RestException(401);
    -		  }
    +    function getLines($id)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->contrat->lire) {
    +            throw new RestException(401);
    +		}
     
    -      $result = $this->contract->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Contract not found');
    -      }
    +        $result = $this->contract->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Contract not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    -      $this->contract->getLinesArray();
    -      $result = array();
    -      foreach ($this->contract->lines as $line) {
    -        array_push($result,$this->_cleanObjectDatas($line));
    -      }
    -      return $result;
    +		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +		    throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
    +        $this->contract->getLinesArray();
    +        $result = array();
    +        foreach ($this->contract->lines as $line) {
    +            array_push($result, $this->_cleanObjectDatas($line));
    +        }
    +        return $result;
         }
     
         /**
    @@ -245,48 +248,48 @@ class Contracts extends DolibarrApi
          *
          * @url	POST {id}/lines
          *
    -     * @return int
    +     * @return int|bool
          */
    -    function postLine($id, $request_data = null) {
    -      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function postLine($id, $request_data = null)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    +			throw new RestException(401);
    +		}
     
    -      $result = $this->contract->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Contract not found');
    -      }
    +        $result = $this->contract->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Contract not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    -			$request_data = (object) $request_data;
    -      $updateRes = $this->contract->addline(
    -                        $request_data->desc,
    -                        $request_data->subprice,
    -                        $request_data->qty,
    -                        $request_data->tva_tx,
    -                        $request_data->localtax1_tx,
    -                        $request_data->localtax2_tx,
    -                        $request_data->fk_product,
    -                        $request_data->remise_percent,
    -                        $request_data->date_start,			// date_start = date planned start, date ouverture = date_start_real
    -                        $request_data->date_end,			// date_end = date planned end, date_cloture = date_end_real
    -                        $request_data->HT,
    -      					$request_data->subprice_excl_tax,
    -      					$request_data->info_bits,
    -                        $request_data->fk_fournprice,
    -				      	$request_data->pa_ht,
    -      					$request_data->array_options,
    -      					$request_data->fk_unit,
    -      					$request_data->rang
    -      );
    +		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
    +		$request_data = (object) $request_data;
    +        $updateRes = $this->contract->addline(
    +            $request_data->desc,
    +            $request_data->subprice,
    +            $request_data->qty,
    +            $request_data->tva_tx,
    +            $request_data->localtax1_tx,
    +            $request_data->localtax2_tx,
    +            $request_data->fk_product,
    +            $request_data->remise_percent,
    +            $request_data->date_start,			// date_start = date planned start, date ouverture = date_start_real
    +            $request_data->date_end,			// date_end = date planned end, date_cloture = date_end_real
    +            $request_data->HT,
    +      		$request_data->subprice_excl_tax,
    +      		$request_data->info_bits,
    +            $request_data->fk_fournprice,
    +			$request_data->pa_ht,
    +      		$request_data->array_options,
    +      		$request_data->fk_unit,
    +      		$request_data->rang
    +        );
     
    -      if ($updateRes > 0) {
    -        return $updateRes;
    -
    -      }
    -      return false;
    +        if ($updateRes > 0) {
    +            return $updateRes;
    +        }
    +        return false;
         }
     
         /**
    @@ -298,52 +301,53 @@ class Contracts extends DolibarrApi
          *
          * @url	PUT {id}/lines/{lineid}
          *
    -     * @return object
    +     * @return array|bool
          */
    -    function putLine($id, $lineid, $request_data = null) {
    -      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    -		  	throw new RestException(401);
    -		  }
    -
    -      $result = $this->contract->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Contrat not found');
    -      }
    -
    -		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +    function putLine($id, $lineid, $request_data = null)
    +    {
    +        if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    +			throw new RestException(401);
     		}
     
    -      $request_data = (object) $request_data;
    +        $result = $this->contract->fetch($id);
    +        if( ! $result ) {
    +            throw new RestException(404, 'Contrat not found');
    +        }
     
    -      $updateRes = $this->contract->updateline(
    -                        $lineid,
    -                        $request_data->desc,
    -                        $request_data->subprice,
    -                        $request_data->qty,
    -                        $request_data->remise_percent,
    -                        $request_data->date_ouveture_prevue,
    -                        $request_data->date_fin_validite,
    -      					$request_data->tva_tx,
    -                        $request_data->localtax1_tx,
    -                        $request_data->localtax2_tx,
    -                        $request_data->date_ouverture,
    -                        $request_data->date_cloture,
    -      					'HT',
    -                        $request_data->info_bits,
    -                        $request_data->fk_fourn_price,
    -                        $request_data->pa_ht,
    -                        $request_data->array_options,
    -                        $request_data->fk_unit
    -      );
    +		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +		}
     
    -      if ($updateRes > 0) {
    -        $result = $this->get($id);
    -        unset($result->line);
    -        return $this->_cleanObjectDatas($result);
    -      }
    +        $request_data = (object) $request_data;
     
    -      return false;
    +        $updateRes = $this->contract->updateline(
    +            $lineid,
    +            $request_data->desc,
    +            $request_data->subprice,
    +            $request_data->qty,
    +            $request_data->remise_percent,
    +            $request_data->date_ouveture_prevue,
    +            $request_data->date_fin_validite,
    +      		$request_data->tva_tx,
    +            $request_data->localtax1_tx,
    +            $request_data->localtax2_tx,
    +            $request_data->date_ouverture,
    +            $request_data->date_cloture,
    +      		'HT',
    +            $request_data->info_bits,
    +            $request_data->fk_fourn_price,
    +            $request_data->pa_ht,
    +            $request_data->array_options,
    +            $request_data->fk_unit
    +        );
    +
    +        if ($updateRes > 0) {
    +            $result = $this->get($id);
    +            unset($result->line);
    +            return $this->_cleanObjectDatas($result);
    +        }
    +
    +        return false;
         }
     
         /**
    @@ -357,15 +361,16 @@ class Contracts extends DolibarrApi
          *
          * @url	PUT {id}/lines/{lineid}/activate
          *
    -     * @return object
    +     * @return array|bool
          */
    -    function activateLine($id, $lineid, $datestart, $dateend = null, $comment = null) {
    +    function activateLine($id, $lineid, $datestart, $dateend = null, $comment = null)
    +    {
         	if(! DolibarrApiAccess::$user->rights->contrat->creer) {
         		throw new RestException(401);
         	}
     
         	$result = $this->contract->fetch($id);
    -    	if( ! $result ) {
    +    	if (! $result) {
         		throw new RestException(404, 'Contrat not found');
         	}
     
    @@ -394,15 +399,16 @@ class Contracts extends DolibarrApi
          *
          * @url	PUT {id}/lines/{lineid}/unactivate
          *
    -     * @return object
    +     * @return array|bool
          */
    -    function unactivateLine($id, $lineid, $datestart, $comment = null) {
    -    	if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    +    function unactivateLine($id, $lineid, $datestart, $comment = null)
    +    {
    +    	if (! DolibarrApiAccess::$user->rights->contrat->creer) {
         		throw new RestException(401);
         	}
     
         	$result = $this->contract->fetch($id);
    -    	if( ! $result ) {
    +    	if (! $result) {
         		throw new RestException(404, 'Contrat not found');
         	}
     
    @@ -436,51 +442,53 @@ class Contracts extends DolibarrApi
          * @throws 401
          * @throws 404
          */
    -    function deleteLine($id, $lineid) {
    -      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function deleteLine($id, $lineid)
    +    {
    +        if (! DolibarrApiAccess::$user->rights->contrat->creer) {
    +			throw new RestException(401);
    +		}
     
    -      $result = $this->contract->fetch($id);
    -      if( ! $result ) {
    -         throw new RestException(404, 'Contrat not found');
    -      }
    +        $result = $this->contract->fetch($id);
    +        if (! $result) {
    +            throw new RestException(404, 'Contrat not found');
    +        }
     
    -		  if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    -			  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -      }
    +		if (! DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
     
    -      // TODO Check the lineid $lineid is a line of ojbect
    +        // TODO Check the lineid $lineid is a line of object
     
    -      $updateRes = $this->contract->deleteline($lineid, DolibarrApiAccess::$user);
    -      if ($updateRes > 0) {
    -        return $this->get($id);
    -      }
    -      else
    -      {
    -      	throw new RestException(405, $this->contract->error);
    -      }
    +        $updateRes = $this->contract->deleteline($lineid, DolibarrApiAccess::$user);
    +        if ($updateRes > 0) {
    +            return $this->get($id);
    +        }
    +        else
    +        {
    +      	    throw new RestException(405, $this->contract->error);
    +        }
         }
     
         /**
          * Update contract general fields (won't touch lines of contract)
          *
    -     * @param int   $id             Id of contrat to update
    +     * @param int   $id             Id of contract to update
          * @param array $request_data   Datas
          *
          * @return int
          */
    -    function put($id, $request_data = null) {
    -      if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    -		  	throw new RestException(401);
    -		  }
    +    function put($id, $request_data = null)
    +    {
    +        if (! DolibarrApiAccess::$user->rights->contrat->creer) {
    +			throw new RestException(401);
    +		}
     
             $result = $this->contract->fetch($id);
    -        if( ! $result ) {
    +        if (! $result) {
                 throw new RestException(404, 'Contrat not found');
             }
     
    -		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +		if (! DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
     			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
     		}
             foreach($request_data as $field => $value) {
    @@ -507,19 +515,19 @@ class Contracts extends DolibarrApi
          */
         function delete($id)
         {
    -        if(! DolibarrApiAccess::$user->rights->contrat->supprimer) {
    +        if (! DolibarrApiAccess::$user->rights->contrat->supprimer) {
     			throw new RestException(401);
     		}
             $result = $this->contract->fetch($id);
    -        if( ! $result ) {
    +        if (! $result) {
                 throw new RestException(404, 'Contract not found');
             }
     
    -		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +		if (! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
     			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
     		}
     
    -        if( ! $this->contract->delete(DolibarrApiAccess::$user)) {
    +        if (! $this->contract->delete(DolibarrApiAccess::$user)) {
                 throw new RestException(500, 'Error when delete contract : '.$this->contract->error);
             }
     
    @@ -529,11 +537,10 @@ class Contracts extends DolibarrApi
                     'message' => 'Contract deleted'
                 )
             );
    -
         }
     
         /**
    -     * Validate an contract
    +     * Validate a contract
          *
          * @param   int $id             Contract ID
          * @param   int $notrigger      1=Does not execute triggers, 0= execute triggers
    @@ -550,15 +557,15 @@ class Contracts extends DolibarrApi
          */
         function validate($id, $notrigger=0)
         {
    -        if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    +        if (! DolibarrApiAccess::$user->rights->contrat->creer) {
     			throw new RestException(401);
     		}
             $result = $this->contract->fetch($id);
    -        if( ! $result ) {
    +        if (! $result) {
                 throw new RestException(404, 'Contract not found');
             }
     
    -		if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +		if (! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
     			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
     		}
     
    @@ -596,15 +603,15 @@ class Contracts extends DolibarrApi
          */
         function close($id, $notrigger=0)
         {
    -    	if(! DolibarrApiAccess::$user->rights->contrat->creer) {
    +    	if (! DolibarrApiAccess::$user->rights->contrat->creer) {
         		throw new RestException(401);
         	}
         	$result = $this->contract->fetch($id);
    -    	if( ! $result ) {
    +    	if (! $result) {
         		throw new RestException(404, 'Contract not found');
         	}
     
    -    	if( ! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
    +    	if (! DolibarrApi::_checkAccessToResource('contrat',$this->contract->id)) {
         		throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
         	}
     
    @@ -632,7 +639,8 @@ class Contracts extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -665,7 +673,6 @@ class Contracts extends DolibarrApi
                 if (!isset($data[$field]))
                     throw new RestException(400, "$field field missing");
                 $contrat[$field] = $data[$field];
    -
             }
             return $contrat;
         }
    diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
    index 291569270b3..8d2194bb60a 100644
    --- a/htdocs/contrat/class/contrat.class.php
    +++ b/htdocs/contrat/class/contrat.class.php
    @@ -10,6 +10,7 @@
      * Copyright (C) 2014-2015	Marcos García			<marcosgdf@gmail.com>
      * Copyright (C) 2015-2017	Ferran Marcet			<fmarcet@2byte.es>
      * Copyright (C) 2018   	Nicolas ZABOURI			<info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -41,16 +42,37 @@ require_once DOL_DOCUMENT_ROOT . '/margin/lib/margins.lib.php';
      */
     class Contrat extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='contrat';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='contrat';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line='contratdet';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_contrat';
    -    public $picto='contract';
    +
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto='contract';
    +
         /**
          * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
          * @var int
          */
         public $ismultientitymanaged = 1;
    +
         /**
          * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
          * @var integer
    @@ -66,27 +88,29 @@ class Contrat extends CommonObject
     	 * Customer reference of the contract
     	 * @var string
     	 */
    -	var $ref_customer;
    +	public $ref_customer;
     
     	/**
     	 * Supplier reference of the contract
     	 * @var string
     	 */
    -	var $ref_supplier;
    +	public $ref_supplier;
     
     	/**
     	 * Client id linked to the contract
     	 * @var int
     	 */
    -	var $socid;
    -	var $societe;		// Objet societe
    +	public $socid;
    +
    +	public $societe;		// Objet societe
     
     	/**
     	 * Status of the contract
     	 * @var int
     	 */
    -	var $statut=0;		// 0=Draft,
    -	var $product;
    +	public $statut=0;		// 0=Draft,
    +
    +	public $product;
     
     	/**
     	 * @var int		Id of user author of the contract
    @@ -113,7 +137,7 @@ class Contrat extends CommonObject
     	/**
     	 * @var int		Date of creation
     	 */
    -	var $date_creation;
    +	public $date_creation;
     
     	/**
     	 * @var int		Date of last modification. Not filled until you call ->info()
    @@ -123,34 +147,34 @@ class Contrat extends CommonObject
     	/**
     	 * @var int		Date of validation
     	 */
    -	var $date_validation;
    +	public $date_validation;
     
     	/**
     	 * @var int		Date when contract was signed
     	 */
    -	var $date_contrat;
    +	public $date_contrat;
     
     	/**
     	 * @var int		Date of contract closure
     	 * @deprecated we close contract lines, not a contract
     	 */
    -	var $date_cloture;
    +	public $date_cloture;
     
    -	var $commercial_signature_id;
    -	var $commercial_suivi_id;
    +	public $commercial_signature_id;
    +	public $commercial_suivi_id;
     
     	/**
     	 * @deprecated Use fk_project instead
     	 * @see fk_project
     	 */
    -	var $fk_projet;
    +	public $fk_projet;
     
    -	var $extraparams=array();
    +	public $extraparams=array();
     
     	/**
     	 * @var ContratLigne[]		Contract lines
     	 */
    -	var $lines=array();
    +	public $lines=array();
     
     	/**
     	 * Maps ContratLigne IDs to $this->lines indexes
    @@ -226,18 +250,20 @@ class Contrat extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Activate a contract line
     	 *
     	 *  @param	User		$user       Objet User who activate contract
     	 *  @param  int			$line_id    Id of line to activate
    -	 *  @param  int			$date       Date d'ouverture
    -	 *  @param  int|string	$date_end   Date fin prevue
    +	 *  @param  int			$date       Opening date
    +	 *  @param  int|string	$date_end   Expected end date
     	 * 	@param	string		$comment	A comment typed by user
     	 *  @return int         			<0 if KO, >0 if OK
     	 */
     	function active_line($user, $line_id, $date, $date_end='', $comment='')
     	{
    +        // phpcs:enable
     		$result = $this->lines[$this->lines_id_index_mapper[$line_id]]->active_line($user, $date, $date_end, $comment);
     		if ($result < 0)
     		{
    @@ -248,17 +274,19 @@ class Contrat extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Close a contract line
     	 *
     	 *  @param	User		$user       Objet User who close contract
     	 *  @param  int			$line_id    Id of line to close
    -	 *  @param  int			$date_end	Date end
    +	 *  @param  int			$date_end	End date
     	 * 	@param	string		$comment	A comment typed by user
     	 *  @return int         			<0 if KO, >0 if OK
     	 */
     	function close_line($user, $line_id, $date_end, $comment='')
     	{
    +        // phpcs:enable
     		$result=$this->lines[$this->lines_id_index_mapper[$line_id]]->close_line($user, $date_end, $comment);
     		if ($result < 0)
     		{
    @@ -285,11 +313,11 @@ class Contrat extends CommonObject
     
     		$this->db->begin();
     
    +		$error=0;
    +
     		// Load lines
     		$this->fetch_lines();
     
    -		$error=0;
    -
     		foreach($this->lines as $contratline)
     		{
     			// Open lines not already open
    @@ -510,13 +538,12 @@ class Contrat extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
     	 * Unvalidate a contract
     	 *
    -	 * @param	User	$user      		Objet User
    +	 * @param	User	$user      		Object User
          * @param	int		$notrigger		1=Does not execute triggers, 0=execute triggers
     	 * @return	int						<0 if KO, >0 if OK
     	 */
    @@ -558,7 +585,7 @@ class Contrat extends CommonObject
     			// End call triggers
     		}
     
    -		// Set new ref and define current statut
    +		// Set new ref and define current status
     		if (! $error)
     		{
     			$this->statut=0;
    @@ -617,56 +644,49 @@ class Contrat extends CommonObject
     		$resql = $this->db->query($sql);
     		if ($resql)
     		{
    -			$result = $this->db->fetch_array($resql);
    +			$obj = $this->db->fetch_object($resql);
     
    -			if ($result)
    +			if ($obj)
     			{
    -				$this->id						= $result["rowid"];
    -				$this->ref						= (!isset($result["ref"]) || !$result["ref"]) ? $result["rowid"] : $result["ref"];
    -				$this->ref_customer				= $result["ref_customer"];
    -				$this->ref_supplier				= $result["ref_supplier"];
    -				$this->ref_ext					= $result["ref_ext"];
    -				$this->statut					= $result["statut"];
    -				$this->mise_en_service			= $this->db->jdate($result["datemise"]);
    +				$this->id						= $obj->rowid;
    +				$this->ref						= (!isset($obj->ref) || !$obj->ref) ? $obj->rowid : $obj->ref;
    +				$this->ref_customer				= $obj->ref_customer;
    +				$this->ref_supplier				= $obj->ref_supplier;
    +				$this->ref_ext					= $obj->ref_ext;
    +				$this->statut					= $obj->statut;
    +				$this->mise_en_service			= $this->db->jdate($obj->datemise);
     
    -				$this->date_contrat				= $this->db->jdate($result["datecontrat"]);
    -				$this->date_creation			= $this->db->jdate($result["datecontrat"]);
    +				$this->date_contrat				= $this->db->jdate($obj->datecontrat);
    +				$this->date_creation			= $this->db->jdate($obj->datecontrat);
     
    -				$this->fin_validite				= $this->db->jdate($result["fin_validite"]);
    -				$this->date_cloture				= $this->db->jdate($result["date_cloture"]);
    +				$this->fin_validite				= $this->db->jdate($obj->fin_validite);
    +				$this->date_cloture				= $this->db->jdate($obj->date_cloture);
     
     
    -				$this->user_author_id			= $result["fk_user_author"];
    +				$this->user_author_id			= $obj->fk_user_author;
     
    -				$this->commercial_signature_id	= $result["fk_commercial_signature"];
    -				$this->commercial_suivi_id		= $result["fk_commercial_suivi"];
    +				$this->commercial_signature_id	= $obj->fk_commercial_signature;
    +				$this->commercial_suivi_id		= $obj->fk_commercial_suivi;
     
    -				$this->note_private				= $result["note_private"];
    -				$this->note_public				= $result["note_public"];
    -				$this->modelpdf					= $result["model_pdf"];
    +				$this->note_private				= $obj->note_private;
    +				$this->note_public				= $obj->note_public;
    +				$this->modelpdf					= $obj->model_pdf;
     
    -				$this->fk_projet				= $result["fk_projet"]; // deprecated
    -				$this->fk_project				= $result["fk_projet"];
    +				$this->fk_projet				= $obj->fk_projet; // deprecated
    +				$this->fk_project				= $obj->fk_projet;
     
    -				$this->socid					= $result["fk_soc"];
    -				$this->fk_soc					= $result["fk_soc"];
    +				$this->socid					= $obj->fk_soc;
    +				$this->fk_soc					= $obj->fk_soc;
     
    -				$this->extraparams				= (array) json_decode($result["extraparams"], true);
    +				$this->extraparams				= (array) json_decode($obj->extraparams, true);
     
     				$this->db->free($resql);
     
    -
    -				// Retreive all extrafield
    +				// Retreive all extrafields
     				// fetch optionals attributes and labels
     				$this->fetch_optionals();
     
    -
    -				/*
    -				 * Lines
    -				 */
    -
    -				$this->lines  = array();
    -
    +				// Lines
     				$result=$this->fetch_lines();
     				if ($result < 0)
     				{
    @@ -689,9 +709,9 @@ class Contrat extends CommonObject
     			$this->error=$this->db->error();
     			return -1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load lines array into this->lines.
     	 *  This set also nbofserviceswait, nbofservicesopened, nbofservicesexpired and nbofservicesclosed
    @@ -700,6 +720,7 @@ class Contrat extends CommonObject
     	 */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		$this->nbofserviceswait=0;
     		$this->nbofservicesopened=0;
     		$this->nbofservicesexpired=0;
    @@ -719,7 +740,7 @@ class Contrat extends CommonObject
     		$this->lines=array();
             $pos = 0;
     
    -		// Selectionne les lignes contrats liees a un produit
    +		// Selects contract lines related to a product
     		$sql = "SELECT p.label as product_label, p.description as product_desc, p.ref as product_ref,";
     		$sql.= " d.rowid, d.fk_contrat, d.statut, d.description, d.price_ht, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.remise_percent, d.subprice, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht,";
     		$sql.= " d.total_ht,";
    @@ -753,7 +774,7 @@ class Contrat extends CommonObject
     				$line->id				= $objp->rowid;
     				$line->ref				= $objp->rowid;
     				$line->fk_contrat		= $objp->fk_contrat;
    -				$line->desc				= $objp->description;  // Description ligne
    +				$line->desc				= $objp->description;  // Description line
     				$line->qty				= $objp->qty;
     				$line->vat_src_code 	= $objp->vat_src_code ;
     				$line->tva_tx			= $objp->tva_tx;
    @@ -784,9 +805,9 @@ class Contrat extends CommonObject
     				$line->fk_unit           = $objp->fk_unit;
     
     				$line->ref				= $objp->product_ref;	// deprecated
    -				$line->product_ref		= $objp->product_ref;   // Ref product
    -				$line->product_desc		= $objp->product_desc;  // Description product
    -				$line->product_label	= $objp->product_label; // Label product
    +				$line->product_ref		= $objp->product_ref;   // Product Ref
    +				$line->product_desc		= $objp->product_desc;  // Product Description
    +				$line->product_label	= $objp->product_label; // Product Label
     
     				$line->description		= $objp->description;
     
    @@ -804,7 +825,7 @@ class Contrat extends CommonObject
     				$line->date_fin_prevue   = $this->db->jdate($objp->date_fin_validite);
     				$line->date_fin_reel     = $this->db->jdate($objp->date_cloture);
     
    -				// Retreive all extrafield for contract
    +				// Retreive all extrafields for contract
     				// fetch optionals attributes and labels
     				$line->fetch_optionals();
     
    @@ -910,7 +931,7 @@ class Contrat extends CommonObject
     				$modCodeContract = new $module();
     
     				if (!empty($modCodeContract->code_auto)) {
    -					// Mise a jour ref
    +					// Update ref
     					$sql = 'UPDATE '.MAIN_DB_PREFIX."contrat SET ref='(PROV".$this->id.")' WHERE rowid=".$this->id;
     					if ($this->db->query($sql))
     					{
    @@ -934,14 +955,14 @@ class Contrat extends CommonObject
     				}
     			}
     
    -			// Insert contacts commerciaux ('SALESREPSIGN','contrat')
    +			// Insert business contacts ('SALESREPSIGN','contrat')
     			if (! $error)
     			{
         			$result=$this->add_contact($this->commercial_signature_id,'SALESREPSIGN','internal');
         			if ($result < 0) $error++;
     			}
     
    -			// Insert contacts commerciaux ('SALESREPFOLL','contrat')
    +			// Insert business contacts ('SALESREPFOLL','contrat')
     			if (! $error)
     			{
                     $result=$this->add_contact($this->commercial_suivi_id,'SALESREPFOLL','internal');
    @@ -1690,7 +1711,7 @@ class Contrat extends CommonObject
     			else
     			{
     				$this->db->rollback();
    -				dol_syslog(get_class($this)."::updateligne Erreur -2");
    +				dol_syslog(get_class($this)."::updateline Erreur -2");
     				return -2;
     			}
     		}
    @@ -1698,7 +1719,7 @@ class Contrat extends CommonObject
     		{
     			$this->db->rollback();
     			$this->error=$this->db->error();
    -			dol_syslog(get_class($this)."::updateligne Erreur -1");
    +			dol_syslog(get_class($this)."::updateline Erreur -1");
     			return -1;
     		}
     	}
    @@ -1769,6 +1790,7 @@ class Contrat extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update statut of contract according to services
     	 *
    @@ -1778,6 +1800,7 @@ class Contrat extends CommonObject
     	 */
     	function update_statut($user)
     	{
    +        // phpcs:enable
     		dol_syslog(__METHOD__ . " is deprecated", LOG_WARNING);
     
     		// If draft, we keep it (should not happen)
    @@ -1807,6 +1830,7 @@ class Contrat extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi label of a given contrat status
     	 *
    @@ -1816,33 +1840,34 @@ class Contrat extends CommonObject
     	 */
     	function LibStatut($statut,$mode)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load("contracts");
     		if ($mode == 0)
     		{
     			if ($statut == 0) { return $langs->trans("ContractStatusDraft"); }
    -			if ($statut == 1) { return $langs->trans("ContractStatusValidated"); }
    -			if ($statut == 2) { return $langs->trans("ContractStatusClosed"); }
    +			elseif ($statut == 1) { return $langs->trans("ContractStatusValidated"); }
    +			elseif ($statut == 2) { return $langs->trans("ContractStatusClosed"); }
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut == 0) { return $langs->trans("ContractStatusDraft"); }
    -			if ($statut == 1) { return $langs->trans("ContractStatusValidated"); }
    -			if ($statut == 2) { return $langs->trans("ContractStatusClosed"); }
    +			elseif ($statut == 1) { return $langs->trans("ContractStatusValidated"); }
    +			elseif ($statut == 2) { return $langs->trans("ContractStatusClosed"); }
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut == 0) { return img_picto($langs->trans('ContractStatusDraft'),'statut0').' '.$langs->trans("ContractStatusDraft"); }
    -			if ($statut == 1) { return img_picto($langs->trans('ContractStatusValidated'),'statut4').' '.$langs->trans("ContractStatusValidated"); }
    -			if ($statut == 2) { return img_picto($langs->trans('ContractStatusClosed'),'statut6').' '.$langs->trans("ContractStatusClosed"); }
    +			elseif ($statut == 1) { return img_picto($langs->trans('ContractStatusValidated'),'statut4').' '.$langs->trans("ContractStatusValidated"); }
    +			elseif ($statut == 2) { return img_picto($langs->trans('ContractStatusClosed'),'statut6').' '.$langs->trans("ContractStatusClosed"); }
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut == 0) { return img_picto($langs->trans('ContractStatusDraft'),'statut0'); }
    -			if ($statut == 1) { return img_picto($langs->trans('ContractStatusValidated'),'statut4'); }
    -			if ($statut == 2) { return img_picto($langs->trans('ContractStatusClosed'),'statut6'); }
    +			elseif ($statut == 1) { return img_picto($langs->trans('ContractStatusValidated'),'statut4'); }
    +			elseif ($statut == 2) { return img_picto($langs->trans('ContractStatusClosed'),'statut6'); }
     		}
    -		if ($mode == 4 || $mode == 6 || $mode == 7)
    +		elseif ($mode == 4 || $mode == 6 || $mode == 7)
     		{
     			$text='';
     			if ($mode == 4)
    @@ -1864,11 +1889,11 @@ class Contrat extends CommonObject
     			$text.=($mode == 7?'</div>':'');
     			return $text;
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut == 0) { return $langs->trans("ContractStatusDraft").' '.img_picto($langs->trans('ContractStatusDraft'),'statut0'); }
    -			if ($statut == 1) { return $langs->trans("ContractStatusValidated").' '.img_picto($langs->trans('ContractStatusValidated'),'statut4'); }
    -			if ($statut == 2) { return $langs->trans("ContractStatusClosed").' '.img_picto($langs->trans('ContractStatusClosed'),'statut6'); }
    +			elseif ($statut == 1) { return $langs->trans("ContractStatusValidated").' '.img_picto($langs->trans('ContractStatusValidated'),'statut4'); }
    +			elseif ($statut == 2) { return $langs->trans("ContractStatusClosed").' '.img_picto($langs->trans('ContractStatusClosed'),'statut6'); }
     		}
     	}
     
    @@ -1981,7 +2006,6 @@ class Contrat extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -1989,6 +2013,7 @@ class Contrat extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of line rowid
     	 *
    @@ -1997,6 +2022,7 @@ class Contrat extends CommonObject
     	 */
     	function array_detail($statut=-1)
     	{
    +        // phpcs:enable
     		$tab=array();
     
     		$sql = "SELECT cd.rowid";
    @@ -2064,6 +2090,7 @@ class Contrat extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
    @@ -2073,6 +2100,7 @@ class Contrat extends CommonObject
     	 */
     	function load_board($user,$mode)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$this->from = " FROM ".MAIN_DB_PREFIX."contrat as c";
    @@ -2088,7 +2116,7 @@ class Contrat extends CommonObject
     			$sql.= " AND c.rowid = cd.fk_contrat";
     			$sql.= " AND cd.statut = 0";
     		}
    -		if ($mode == 'expired')
    +		elseif ($mode == 'expired')
     		{
     			$sql = "SELECT cd.rowid, cd.date_fin_validite as datefin";
     			$sql.= $this->from;
    @@ -2142,6 +2170,7 @@ class Contrat extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Charge indicateurs this->nb de tableau de bord
     	 *
    @@ -2149,6 +2178,7 @@ class Contrat extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		$this->nb=array();
    @@ -2350,8 +2380,9 @@ class Contrat extends CommonObject
     	 * @param int $notrigger	1=Does not execute triggers, 0= execute triggers
     	 * @return int New id of clone
     	 */
    -	function createFromClone($socid = 0, $notrigger=0) {
    -		global $db, $user, $langs, $conf, $hookmanager;
    +    function createFromClone($socid = 0, $notrigger=0)
    +    {
    +		global $db, $user, $langs, $conf, $hookmanager, $extrafields;
     
     		dol_include_once('/projet/class/project.class.php');
     
    @@ -2360,6 +2391,7 @@ class Contrat extends CommonObject
     		$error = 0;
     
     		$this->fetch($this->id);
    +
     		// Load dest object
     		$clonedObj = clone $this;
             $clonedObj->socid = $socid;
    @@ -2370,8 +2402,23 @@ class Contrat extends CommonObject
     
     		$objsoc->fetch($clonedObj->socid);
     
    -		// $clonedObj->id=0;
    +		// Clean data
     		$clonedObj->statut = 0;
    +		// Clean extrafields
    +		if (is_array($clonedObj->array_options) && count($clonedObj->array_options) > 0)
    +		{
    +			$extrafields->fetch_name_optionals_label($this->element);
    +			foreach($clonedObj->array_options as $key => $option)
    +			{
    +				$shortkey = preg_replace('/options_/', '', $key);
    +				//var_dump($shortkey); var_dump($extrafields->attributes[$this->element]['unique'][$shortkey]);
    +				if (! empty($extrafields->attributes[$this->element]['unique'][$shortkey]))
    +				{
    +					//var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
    +					unset($clonedObj->array_options[$key]);
    +				}
    +			}
    +		}
     
     		if (empty($conf->global->CONTRACT_ADDON) || ! is_readable(DOL_DOCUMENT_ROOT . "/core/modules/contract/" . $conf->global->CONTRACT_ADDON . ".php")) {
     			$this->error = 'ErrorSetupNotComplete';
    @@ -2386,8 +2433,8 @@ class Contrat extends CommonObject
     		$clonedObj->ref = $modContract->getNextValue($objsoc, $clonedObj);
     
     		// get extrafields so they will be clone
    -		foreach ( $this->lines as $line ) {
    -			$line->fetch_optionals($line->rowid);
    +		foreach ($this->lines as $line) {
    +			$line->fetch_optionals($line->id);
     		}
     
     		// Create clone
    @@ -2428,7 +2475,6 @@ class Contrat extends CommonObject
     				if ($reshook < 0)
     					$error ++;
     			}
    -
     		}
     
     		unset($this->context['createfromclone']);
    @@ -2450,55 +2496,87 @@ class Contrat extends CommonObject
      */
     class ContratLigne extends CommonObjectLine
     {
    -    public $element='contratdet';
    -    public $table_element='contratdet';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='contratdet';
     
    -	var $id;
    -	var $ref;
    -	var $tms;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='contratdet';
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +	 * @var string Ref
    +	 */
    +	public $ref;
    +
    +	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_contrat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_product;
    +
    +	public $statut;					// 0 inactive, 4 active, 5 closed
    +	public $type;						// 0 for product, 1 for service
     
    -	var $fk_contrat;
    -	var $fk_product;
    -	var $statut;					// 0 inactive, 4 active, 5 closed
    -	var $type;						// 0 for product, 1 for service
     	/**
     	 * @var string
     	 * @deprecated
     	 */
    -	var $label;
    +	public $label;
    +
     	/**
     	 * @var string
     	 * @deprecated
     	 */
     	public $libelle;
     
    -	var $description;
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
     
    -	var $product_ref;
    -	var $product_label;
    +	public $product_ref;
    +	public $product_label;
     
    -	var $date_commande;
    +	public $date_commande;
     
    -	var $date_start;				// date start planned
    -	var $date_start_real;			// date start real
    -	var $date_end;					// date end planned
    -	var $date_end_real;				// date end real
    +	public $date_start;				// date start planned
    +	public $date_start_real;			// date start real
    +	public $date_end;					// date end planned
    +	public $date_end_real;				// date end real
     	// For backward compatibility
    -	var $date_ouverture_prevue;		// date start planned
    -	var $date_ouverture;			// date start real
    -	var $date_fin_validite;			// date end planned
    -	var $date_cloture;				// date end real
    -	var $tva_tx;
    -	var $localtax1_tx;
    -	var $localtax2_tx;
    -	var $localtax1_type;	// Local tax 1 type
    -	var $localtax2_type;	// Local tax 2 type
    -	var $qty;
    -	var $remise_percent;
    -	var $remise;
    -	var $fk_remise_except;
    +	public $date_ouverture_prevue;		// date start planned
    +	public $date_ouverture;			// date start real
    +	public $date_fin_validite;			// date end planned
    +	public $date_cloture;				// date end real
    +	public $tva_tx;
    +	public $localtax1_tx;
    +	public $localtax2_tx;
    +	public $localtax1_type;	// Local tax 1 type
    +	public $localtax2_type;	// Local tax 2 type
    +	public $qty;
    +	public $remise_percent;
    +	public $remise;
     
    -	var $subprice;					// Unit price HT
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_remise_except;
    +
    +	public $subprice;					// Unit price HT
     
     	/**
     	 * @var float
    @@ -2507,22 +2585,39 @@ class ContratLigne extends CommonObjectLine
     	 */
     	public $price;
     
    -	var $price_ht;
    +	public $price_ht;
     
    -	var $total_ht;
    -	var $total_tva;
    -	var $total_localtax1;
    -	var $total_localtax2;
    -	var $total_ttc;
    +	public $total_ht;
    +	public $total_tva;
    +	public $total_localtax1;
    +	public $total_localtax2;
    +	public $total_ttc;
     
    -	var $fk_fournprice;
    -	var $pa_ht;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_fournprice;
     
    -	var $info_bits;
    -	var $fk_user_author;
    -	var $fk_user_ouverture;
    -	var $fk_user_cloture;
    -	var $commentaire;
    +	public $pa_ht;
    +
    +	public $info_bits;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_ouverture;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_cloture;
    +
    +	public $commentaire;
     
     	const STATUS_INITIAL = 0;
     	const STATUS_OPEN = 4;
    @@ -2552,6 +2647,7 @@ class ContratLigne extends CommonObjectLine
     		return $this->LibStatut($this->statut,$mode,((! empty($this->date_fin_validite))?($this->date_fin_validite < dol_now()?1:0):-1));
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return label of a contract line status
     	 *
    @@ -2563,55 +2659,56 @@ class ContratLigne extends CommonObjectLine
     	 */
     	static function LibStatut($statut,$mode,$expired=-1,$moreatt='')
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load("contracts");
     		if ($mode == 0)
     		{
     			if ($statut == self::STATUS_INITIAL) { return $langs->trans("ServiceStatusInitial"); }
    -			if ($statut == self::STATUS_OPEN && $expired == -1) { return $langs->trans("ServiceStatusRunning"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 0)  { return $langs->trans("ServiceStatusNotLate"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 1)  { return $langs->trans("ServiceStatusLate"); }
    -			if ($statut == self::STATUS_CLOSED) { return $langs->trans("ServiceStatusClosed");  }
    +			elseif ($statut == self::STATUS_OPEN && $expired == -1) { return $langs->trans("ServiceStatusRunning"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 0)  { return $langs->trans("ServiceStatusNotLate"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 1)  { return $langs->trans("ServiceStatusLate"); }
    +			elseif ($statut == self::STATUS_CLOSED) { return $langs->trans("ServiceStatusClosed");  }
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut == self::STATUS_INITIAL) { return $langs->trans("ServiceStatusInitial"); }
    -			if ($statut == self::STATUS_OPEN && $expired == -1) { return $langs->trans("ServiceStatusRunning"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 0)  { return $langs->trans("ServiceStatusNotLateShort"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 1)  { return $langs->trans("ServiceStatusLateShort"); }
    -			if ($statut == self::STATUS_CLOSED) { return $langs->trans("ServiceStatusClosed");  }
    +			elseif ($statut == self::STATUS_OPEN && $expired == -1) { return $langs->trans("ServiceStatusRunning"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 0)  { return $langs->trans("ServiceStatusNotLateShort"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 1)  { return $langs->trans("ServiceStatusLateShort"); }
    +			elseif ($statut == self::STATUS_CLOSED) { return $langs->trans("ServiceStatusClosed");  }
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut == self::STATUS_INITIAL) { return img_picto($langs->trans('ServiceStatusInitial'),'statut0').' '.$langs->trans("ServiceStatusInitial"); }
    -			if ($statut == self::STATUS_OPEN && $expired == -1) { return img_picto($langs->trans('ServiceStatusRunning'),'statut4').' '.$langs->trans("ServiceStatusRunning"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 0)  { return img_picto($langs->trans('ServiceStatusNotLate'),'statut4').' '.$langs->trans("ServiceStatusNotLateShort"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 1)  { return img_picto($langs->trans('ServiceStatusLate'),'statut3').' '.$langs->trans("ServiceStatusLateShort"); }
    -			if ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans('ServiceStatusClosed'),'statut6') .' '.$langs->trans("ServiceStatusClosed"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == -1) { return img_picto($langs->trans('ServiceStatusRunning'),'statut4').' '.$langs->trans("ServiceStatusRunning"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 0)  { return img_picto($langs->trans('ServiceStatusNotLate'),'statut4').' '.$langs->trans("ServiceStatusNotLateShort"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 1)  { return img_picto($langs->trans('ServiceStatusLate'),'statut3').' '.$langs->trans("ServiceStatusLateShort"); }
    +			elseif ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans('ServiceStatusClosed'),'statut6') .' '.$langs->trans("ServiceStatusClosed"); }
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut == self::STATUS_INITIAL) { return img_picto($langs->trans('ServiceStatusInitial'),'statut0',$moreatt); }
    -			if ($statut == self::STATUS_OPEN && $expired == -1) { return img_picto($langs->trans('ServiceStatusRunning'),'statut4',$moreatt); }
    -			if ($statut == self::STATUS_OPEN && $expired == 0)  { return img_picto($langs->trans('ServiceStatusNotLate'),'statut4',$moreatt); }
    -			if ($statut == self::STATUS_OPEN && $expired == 1)  { return img_picto($langs->trans('ServiceStatusLate'),'statut3',$moreatt); }
    -			if ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans('ServiceStatusClosed'),'statut6',$moreatt); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == -1) { return img_picto($langs->trans('ServiceStatusRunning'),'statut4',$moreatt); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 0)  { return img_picto($langs->trans('ServiceStatusNotLate'),'statut4',$moreatt); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 1)  { return img_picto($langs->trans('ServiceStatusLate'),'statut3',$moreatt); }
    +			elseif ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans('ServiceStatusClosed'),'statut6',$moreatt); }
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut == self::STATUS_INITIAL) { return img_picto($langs->trans('ServiceStatusInitial'),'statut0').' '.$langs->trans("ServiceStatusInitial"); }
    -			if ($statut == self::STATUS_OPEN && $expired == -1) { return img_picto($langs->trans('ServiceStatusRunning'),'statut4').' '.$langs->trans("ServiceStatusRunning"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 0)  { return img_picto($langs->trans('ServiceStatusNotLate'),'statut4').' '.$langs->trans("ServiceStatusNotLate"); }
    -			if ($statut == self::STATUS_OPEN && $expired == 1)  { return img_picto($langs->trans('ServiceStatusLate'),'statut3').' '.$langs->trans("ServiceStatusLate"); }
    -			if ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans('ServiceStatusClosed'),'statut6') .' '.$langs->trans("ServiceStatusClosed"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == -1) { return img_picto($langs->trans('ServiceStatusRunning'),'statut4').' '.$langs->trans("ServiceStatusRunning"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 0)  { return img_picto($langs->trans('ServiceStatusNotLate'),'statut4').' '.$langs->trans("ServiceStatusNotLate"); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 1)  { return img_picto($langs->trans('ServiceStatusLate'),'statut3').' '.$langs->trans("ServiceStatusLate"); }
    +			elseif ($statut == self::STATUS_CLOSED) { return img_picto($langs->trans('ServiceStatusClosed'),'statut6') .' '.$langs->trans("ServiceStatusClosed"); }
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut == self::STATUS_INITIAL) { return $langs->trans("ServiceStatusInitial").' '.img_picto($langs->trans('ServiceStatusInitial'),'statut0'); }
    -			if ($statut == self::STATUS_OPEN && $expired == -1) { return $langs->trans("ServiceStatusRunning").' '.img_picto($langs->trans('ServiceStatusRunning'),'statut4'); }
    -			if ($statut == self::STATUS_OPEN && $expired == 0)  { return $langs->trans("ServiceStatusNotLateShort").' '.img_picto($langs->trans('ServiceStatusNotLateShort'),'statut4'); }
    -			if ($statut == self::STATUS_OPEN && $expired == 1)  { return $langs->trans("ServiceStatusLateShort").' '.img_picto($langs->trans('ServiceStatusLate'),'statut3'); }
    -			if ($statut == self::STATUS_CLOSED) { return $langs->trans("ServiceStatusClosed").' '.img_picto($langs->trans('ServiceStatusClosed'),'statut6'); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == -1) { return $langs->trans("ServiceStatusRunning").' '.img_picto($langs->trans('ServiceStatusRunning'),'statut4'); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 0)  { return $langs->trans("ServiceStatusNotLateShort").' '.img_picto($langs->trans('ServiceStatusNotLateShort'),'statut4'); }
    +			elseif ($statut == self::STATUS_OPEN && $expired == 1)  { return $langs->trans("ServiceStatusLateShort").' '.img_picto($langs->trans('ServiceStatusLate'),'statut3'); }
    +			elseif ($statut == self::STATUS_CLOSED) { return $langs->trans("ServiceStatusClosed").' '.img_picto($langs->trans('ServiceStatusClosed'),'statut6'); }
     		}
     	}
     
    @@ -2761,7 +2858,6 @@ class ContratLigne extends CommonObjectLine
     				$marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->fk_fournprice, $obj->pa_ht);
     				$this->pa_ht = $marginInfos[0];
     				$this->fk_unit     = $obj->fk_unit;
    -
     			}
     			$this->db->free($resql);
     
    @@ -2789,9 +2885,9 @@ class ContratLigne extends CommonObjectLine
     		$error=0;
     
     		// Clean parameters
    -		$this->fk_contrat=trim($this->fk_contrat);
    -		$this->fk_product=trim($this->fk_product);
    -		$this->statut=(int) $this->statut;
    +		$this->fk_contrat = (int) $this->fk_contrat;
    +		$this->fk_product = (int) $this->fk_product;
    +		$this->statut = (int) $this->statut;
     		$this->label=trim($this->label);
     		$this->description=trim($this->description);
     		$this->vat_src_code=trim($this->vat_src_code);
    @@ -2801,7 +2897,7 @@ class ContratLigne extends CommonObjectLine
     		$this->qty=trim($this->qty);
     		$this->remise_percent=trim($this->remise_percent);
     		$this->remise=trim($this->remise);
    -		$this->fk_remise_except=trim($this->fk_remise_except);
    +		$this->fk_remise_except = (int) $this->fk_remise_except;
     		$this->subprice=price2num($this->subprice);
     		$this->price_ht=price2num($this->price_ht);
     		$this->total_ht=trim($this->total_ht);
    @@ -2810,9 +2906,9 @@ class ContratLigne extends CommonObjectLine
     		$this->total_localtax2=trim($this->total_localtax2);
     		$this->total_ttc=trim($this->total_ttc);
     		$this->info_bits=trim($this->info_bits);
    -		$this->fk_user_author=trim($this->fk_user_author);
    -		$this->fk_user_ouverture=trim($this->fk_user_ouverture);
    -		$this->fk_user_cloture=trim($this->fk_user_cloture);
    +		$this->fk_user_author = (int) $this->fk_user_author;
    +		$this->fk_user_ouverture = (int) $this->fk_user_ouverture;
    +		$this->fk_user_cloture = (int) $this->fk_user_cloture;
     		$this->commentaire=trim($this->commentaire);
     		//if (empty($this->subprice)) $this->subprice = 0;
     		if (empty($this->price_ht)) $this->price_ht = 0;
    @@ -2951,15 +3047,14 @@ class ContratLigne extends CommonObjectLine
     			}
     		}
     
    -		if (! $error)
    -		{
    -			if (! $notrigger)
    -			{
    -	            // Call trigger
    -	            $result=$this->call_trigger('LINECONTRACT_UPDATE', $user);
    -	            if ($result < 0) { $error++; $this->db->rollback(); }
    -	            // End call triggers
    -			}
    +		if (! $error && ! $notrigger) {
    +	        // Call trigger
    +	        $result=$this->call_trigger('LINECONTRACT_UPDATE', $user);
    +	        if ($result < 0) {
    +                $error++;
    +                $this->db->rollback();
    +            }
    +	        // End call triggers
     		}
     
     		if (! $error)
    @@ -2974,6 +3069,7 @@ class ContratLigne extends CommonObjectLine
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Mise a jour en base des champs total_xxx de ligne
     	 *		Used by migration process
    @@ -2982,6 +3078,7 @@ class ContratLigne extends CommonObjectLine
     	 */
     	function update_total()
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		// Mise a jour ligne en base
    @@ -3090,6 +3187,7 @@ class ContratLigne extends CommonObjectLine
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Activate a contract line
     	 *
    @@ -3101,6 +3199,7 @@ class ContratLigne extends CommonObjectLine
     	 */
     	function active_line($user, $date, $date_end = '', $comment = '')
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		$error = 0;
    @@ -3147,6 +3246,7 @@ class ContratLigne extends CommonObjectLine
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Close a contract line
     	 *
    @@ -3158,6 +3258,7 @@ class ContratLigne extends CommonObjectLine
     	 */
     	function close_line($user, $date_end, $comment = '', $notrigger=0)
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		// Update object
    diff --git a/htdocs/contrat/contact.php b/htdocs/contrat/contact.php
    index 4d403198eb8..b659aa01aab 100644
    --- a/htdocs/contrat/contact.php
    +++ b/htdocs/contrat/contact.php
    @@ -24,7 +24,7 @@
      *      \brief      Onglet de gestion des contacts des contrats
      */
     
    -require ("../main.inc.php");
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
     require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
    @@ -163,27 +163,26 @@ if ($id > 0 || ! empty($ref))
     		$morehtmlref.=$form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', null, null, '', 1);
     		// Thirdparty
     	    $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
    -	    // Project
    -	    if (! empty($conf->projet->enabled))
    -	    {
    -	        $langs->load("projects");
    -	        $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
    -	        if ($user->rights->contrat->creer)
    -	        {
    -	            if ($action != 'classify')
    -	                //$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
    -	                $morehtmlref.=' : ';
    -	            	if ($action == 'classify') {
    -	                    //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
    -	                    $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
    -	                    $morehtmlref.='<input type="hidden" name="action" value="classin">';
    -	                    $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    -	                    $morehtmlref.=$formproject->select_projects($object->thirdparty->id, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
    -	                    $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    -	                    $morehtmlref.='</form>';
    -	                } else {
    -	                    $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->thirdparty->id, $object->fk_project, 'none', 0, 0, 0, 1);
    -	                }
    +        // Project
    +        if (! empty($conf->projet->enabled)) {
    +            $langs->load("projects");
    +            $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
    +            if ($user->rights->contrat->creer) {
    +                if ($action != 'classify') {
    +                    //$morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
    +                    $morehtmlref.=' : ';
    +                }
    +                if ($action == 'classify') {
    +	                //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
    +	                $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
    +	                $morehtmlref.='<input type="hidden" name="action" value="classin">';
    +	                $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +	                $morehtmlref.=$formproject->select_projects($object->thirdparty->id, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
    +	                $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    +	                $morehtmlref.='</form>';
    +	            } else {
    +	                $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->thirdparty->id, $object->fk_project, 'none', 0, 0, 0, 1);
    +	            }
     	        } else {
     	            if (! empty($object->fk_project)) {
     	                $proj = new Project($db);
    @@ -210,9 +209,12 @@ if ($id > 0 || ! empty($ref))
     
             // Ligne info remises tiers
             print '<tr><td class="titlefield">'.$langs->trans('Discount').'</td><td colspan="3">';
    -        if ($object->thirdparty->remise_percent) print $langs->trans("CompanyHasRelativeDiscount",$object->thirdparty->remise_percent);
    -        else print $langs->trans("CompanyHasNoRelativeDiscount");
    -        $absolute_discount=$object->thirdparty->getAvailableDiscounts();
    +        if ($object->thirdparty->remise_percent) {
    +            print $langs->trans("CompanyHasRelativeDiscount",$object->thirdparty->remise_percent);
    +        } else {
    +            print $langs->trans("CompanyHasNoRelativeDiscount");
    +        }
    +        $absolute_discount = $object->thirdparty->getAvailableDiscounts();
             print '. ';
             if ($absolute_discount) print $langs->trans("CompanyHasAbsoluteDiscount",price($absolute_discount),$langs->trans("Currency".$conf->currency));
             else print $langs->trans("CompanyHasNoAbsoluteDiscount");
    @@ -238,10 +240,7 @@ if ($id > 0 || ! empty($ref))
     
     		// Contacts lines
     		include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php';
    -
    -	}
    -	else
    -	{
    +	} else {
     		print "ErrorRecordNotFound";
     	}
     }
    diff --git a/htdocs/contrat/document.php b/htdocs/contrat/document.php
    index 0208d68f80d..cd98f787ff6 100644
    --- a/htdocs/contrat/document.php
    +++ b/htdocs/contrat/document.php
    @@ -27,7 +27,7 @@
      *       \brief      Page des documents joints sur les contrats
      */
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -103,7 +103,7 @@ if ($object->id)
     	dol_fiche_head($head, 'documents', $langs->trans("Contract"), -1, 'contract');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -192,7 +192,6 @@ if ($object->id)
         $permtoedit = $user->rights->contrat->creer;
         $param = '&id=' . $object->id;
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
    diff --git a/htdocs/contrat/index.php b/htdocs/contrat/index.php
    index b78bf52b6be..c0404b5cf3f 100644
    --- a/htdocs/contrat/index.php
    +++ b/htdocs/contrat/index.php
    @@ -24,9 +24,9 @@
      *		\brief      Home page of contract area
      */
     
    -require ("../main.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php");
    -require_once (DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    +require "../main.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php";
    +require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
     
     // Load translation files required by the page
     $langs->loadLangs(array('products', 'companies', 'contracts'));
    @@ -279,7 +279,6 @@ if (! empty($conf->contrat->enabled) && $user->rights->contrat->lire)
     				print '</tr>';
     				//$tot_ttc+=$obj->total_ttc;
     				$i++;
    -
     			}
     		}
     		else
    @@ -365,7 +364,6 @@ if ($result)
     	$db->free($result);
     
     	print "</table>";
    -
     }
     else
     {
    @@ -444,7 +442,6 @@ if ($resql)
     	$db->free();
     
     	print "</table>";
    -
     }
     else
     {
    @@ -523,7 +520,6 @@ if ($resql)
     	$db->free();
     
     	print "</table>";
    -
     }
     else
     {
    @@ -603,7 +599,6 @@ if ($resql)
     	$db->free();
     
     	print "</table>";
    -
     }
     else
     {
    diff --git a/htdocs/contrat/info.php b/htdocs/contrat/info.php
    index 8899351c284..c783ca4948c 100644
    --- a/htdocs/contrat/info.php
    +++ b/htdocs/contrat/info.php
    @@ -22,7 +22,7 @@
      *      \brief      Page des informations d'un contrat
      */
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
    diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php
    index b4255046ad4..96f20fdaf67 100644
    --- a/htdocs/contrat/list.php
    +++ b/htdocs/contrat/list.php
    @@ -28,7 +28,7 @@
      *       \brief      Page liste des contrats
      */
     
    -require ("../main.inc.php");
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
    @@ -621,7 +621,7 @@ while ($i < min($num,$limit))
     		if (!empty($obj->note_private) || !empty($obj->note_public))
     		{
     			print ' <span class="note">';
    -			print '<a href="'.DOL_URL_ROOT.'/contrat/note.php?id='.$obj->rowid.'">'.img_picto($langs->trans("ViewPrivateNote"),'object_generic').'</a>';
    +			print '<a href="'.DOL_URL_ROOT.'/contrat/note.php?id='.$obj->rowid.'&save_lastsearch_values=1">'.img_picto($langs->trans("ViewPrivateNote"),'note').'</a>';
     			print '</span>';
     		}
     
    diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php
    index c160201191a..ec93d112ef4 100644
    --- a/htdocs/contrat/note.php
    +++ b/htdocs/contrat/note.php
    @@ -24,7 +24,7 @@
      *      \brief      Fiche de notes sur un contrat
      */
     
    -require ("../main.inc.php");
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
     if (! empty($conf->projet->enabled)) {
    @@ -177,7 +177,6 @@ if ($id > 0 || ! empty($ref))
     	include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php';
     
     	dol_fiche_end();
    -
     }
     
     
    diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php
    index 66c56e2a162..72b45f49db5 100644
    --- a/htdocs/contrat/services_list.php
    +++ b/htdocs/contrat/services_list.php
    @@ -1,9 +1,10 @@
     <?php
    -/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
    - * Copyright (C) 2018      Ferran Marcet		<fmarcet@2byte.es>
    +/* Copyright (C) 2001-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2015       Jean-François Ferry     <jfefe@aternatik.fr>
    + * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -25,10 +26,10 @@
      *		\brief      Page to list services in contracts
      */
     
    -require ("../main.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php");
    -require_once (DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    -require_once (DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    +require "../main.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/contrat/class/contrat.class.php";
    +require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
    +require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
     
     // Load translation files required by the page
     $langs->loadLangs(array('products', 'contracts', 'companies'));
    @@ -455,7 +456,7 @@ if (! empty($arrayfields['cd.date_ouverture_prevue']['checked']))
     	print $form->selectarray('filter_opouvertureprevue',$arrayofoperators,$filter_opouvertureprevue,1);
     	print ' ';
     	$filter_dateouvertureprevue=dol_mktime(0,0,0,$opouvertureprevuemonth,$opouvertureprevueday,$opouvertureprevueyear);
    -	print $form->select_date($filter_dateouvertureprevue,'opouvertureprevue',0,0,1,'',1,0,1);
    +	print $form->selectDate($filter_dateouvertureprevue, 'opouvertureprevue', 0, 0, 1, '', 1, 0);
     	print '</td>';
     }
     if (! empty($arrayfields['cd.date_ouverture']['checked']))
    @@ -465,7 +466,7 @@ if (! empty($arrayfields['cd.date_ouverture']['checked']))
     	print $form->selectarray('filter_op1',$arrayofoperators,$filter_op1,1);
     	print ' ';
     	$filter_date1=dol_mktime(0,0,0,$op1month,$op1day,$op1year);
    -	print $form->select_date($filter_date1,'op1',0,0,1,'',1,0,1);
    +	print $form->selectDate($filter_date1, 'op1', 0, 0, 1, '', 1, 0);
     	print '</td>';
     }
     if (! empty($arrayfields['cd.date_fin_validite']['checked']))
    @@ -475,7 +476,7 @@ if (! empty($arrayfields['cd.date_fin_validite']['checked']))
     	print $form->selectarray('filter_op2',$arrayofoperators,$filter_op2,1);
     	print ' ';
     	$filter_date2=dol_mktime(0,0,0,$op2month,$op2day,$op2year);
    -	print $form->select_date($filter_date2,'op2',0,0,1,'',1,0,1);
    +	print $form->selectDate($filter_date2, 'op2', 0, 0, 1, '', 1, 0);
     	print '</td>';
     }
     if (! empty($arrayfields['cd.date_cloture']['checked']))
    @@ -485,7 +486,7 @@ if (! empty($arrayfields['cd.date_cloture']['checked']))
     	print $form->selectarray('filter_opcloture',$arrayofoperators,$filter_opcloture,1);
     	print ' ';
     	$filter_date_cloture=dol_mktime(0,0,0,$opcloturemonth,$opclotureday,$opclotureyear);
    -	print $form->select_date($filter_date_cloture,'opcloture',0,0,1,'',1,0,1);
    +	print $form->selectDate($filter_date_cloture, 'opcloture', 0, 0, 1, '', 1, 0);
     	print '</td>';
     }
     // Extra fields
    diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php
    index 6b6d40acd9c..6b6d4b7a176 100644
    --- a/htdocs/core/actions_extrafields.inc.php
    +++ b/htdocs/core/actions_extrafields.inc.php
    @@ -178,10 +178,12 @@ if ($action == 'add')
                     	(GETPOST('alwayseditable', 'alpha')?1:0),
                     	(GETPOST('perms', 'alpha')?GETPOST('perms', 'alpha'):''),
                     	$visibility,
    -					0,
    +					GETPOST('help','alpha'),
                         GETPOST('computed_value','alpha'),
                     	(GETPOST('entitycurrentorall', 'alpha')?0:''),
    -                	GETPOST('langfile', 'alpha')
    +                    GETPOST('langfile', 'alpha'),
    +                    1,
    +                    (GETPOST('totalizable', 'alpha')?1:0)
                     );
         			if ($result > 0)
         			{
    @@ -331,7 +333,7 @@ if ($action == 'update')
         			$visibility = GETPOST('list', 'alpha');
         			if ($type == 'separate') $visibility=3;
     
    -    			$result=$extrafields->update(
    +                $result=$extrafields->update(
         				GETPOST('attrname', 'alpha'),
         				GETPOST('label', 'alpha'),
         				$type,
    @@ -344,11 +346,13 @@ if ($action == 'update')
         				(GETPOST('alwayseditable', 'alpha')?1:0),
         				(GETPOST('perms', 'alpha')?GETPOST('perms', 'alpha'):''),
                     	$visibility,
    -					0,
    +					GETPOST('help','alpha'),
         			    GETPOST('default_value','alpha'),
         				GETPOST('computed_value','alpha'),
         				(GETPOST('entitycurrentorall', 'alpha')?0:''),
    -    				GETPOST('langfile')
    +                    GETPOST('langfile'),
    +                    1,
    +                    (GETPOST('totalizable', 'alpha')?1:0)
         			);
         			if ($result > 0)
         			{
    diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php
    index 297f7821599..58f96b7faf1 100644
    --- a/htdocs/core/actions_linkedfiles.inc.php
    +++ b/htdocs/core/actions_linkedfiles.inc.php
    @@ -50,13 +50,17 @@ if (GETPOST('sendit','alpha') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     
     		if (! $error)
     		{
    +			// Define if we have to generate thumbs or not
    +			$generatethumbs = 1;
    +			if (GETPOST('section_dir')) $generatethumbs=0;
    +
     			if (! empty($upload_dirold) && ! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
     			{
    -				$result = dol_add_file_process($upload_dirold, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'));
    +				$result = dol_add_file_process($upload_dirold, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'), null, '', $generatethumbs);
     			}
     			elseif (! empty($upload_dir))
     			{
    -				$result = dol_add_file_process($upload_dir, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'));
    +				$result = dol_add_file_process($upload_dir, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'), null, '', $generatethumbs);
     			}
     		}
     	}
    @@ -69,7 +73,7 @@ elseif (GETPOST('linkit','none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
             if (substr($link, 0, 7) != 'http://' && substr($link, 0, 8) != 'https://' && substr($link, 0, 7) != 'file://') {
                 $link = 'http://' . $link;
             }
    -        dol_add_file_process($upload_dir, 0, 1, 'userfile', null, $link);
    +        dol_add_file_process($upload_dir, 0, 1, 'userfile', null, $link, '', 0);
         }
     }
     
    @@ -77,20 +81,23 @@ elseif (GETPOST('linkit','none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     // Delete file/link
     if ($action == 'confirm_deletefile' && $confirm == 'yes')
     {
    -        $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1);	// Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
    -        if (GETPOST('section', 'alpha')) $file = $upload_dir . "/" . $urlfile;	// For a delete of GED module urlfile contains full path from upload_dir
    -        else															// For documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
    +        $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1);				// Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
    +        if (GETPOST('section', 'alpha')) 	// For a delete from the ECM module, upload_dir is ECM root dir and urlfile contains relative path from upload_dir
    +        {
    +        	$file = $upload_dir . (preg_match('/\/$/', $upload_dir) ? '' : '/') . $urlfile;
    +        }
    +        else								// For a delete from the file manager into another module, or from documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
     		{
            		$urlfile=basename($urlfile);
    -			$file = $upload_dir . "/" . $urlfile;
    +       		$file = $upload_dir . (preg_match('/\/$/', $upload_dir) ? '' : '/') . $urlfile;
     			if (! empty($upload_dirold)) $fileold = $upload_dirold . "/" . $urlfile;
     		}
    -        $linkid = GETPOST('linkid', 'int');	// Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
    +        $linkid = GETPOST('linkid', 'int');
     
    -        if ($urlfile)
    +        if ($urlfile)		// delete of a file
             {
    -	        $dir = dirname($file).'/';     // Chemin du dossier contenant l'image d'origine
    -	        $dirthumb = $dir.'/thumbs/';   // Chemin du dossier contenant la vignette
    +	        $dir = dirname($file).'/';		// Chemin du dossier contenant l'image d'origine
    +	        $dirthumb = $dir.'/thumbs/';	// Chemin du dossier contenant la vignette (if file is an image)
     
     	        $ret = dol_delete_file($file, 0, 0, 0, (is_object($object)?$object:null));
                 if (! empty($fileold)) dol_delete_file($fileold, 0, 0, 0, (is_object($object)?$object:null));     // Delete file using old path
    @@ -114,7 +121,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
                 if ($ret) setEventMessages($langs->trans("FileWasRemoved", $urlfile), null, 'mesgs');
                 else setEventMessages($langs->trans("ErrorFailToDeleteFile", $urlfile), null, 'errors');
             }
    -        elseif ($linkid)
    +        elseif ($linkid)	// delete of external link
             {
                 require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
                 $link = new Link($db);
    @@ -143,7 +150,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
             	}
             	else
             	{
    -        		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id.(!empty($withproject)?'&withproject=1':''));
    +        		header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.(GETPOST('section_dir','alpha')?'&section_dir='.urlencode(GETPOST('section_dir','alpha')):'').(!empty($withproject)?'&withproject=1':''));
             		exit;
             	}
             }
    @@ -208,13 +215,20 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave','alpha'))
     	            		$result = dol_move($srcpath, $destpath);
     			            if ($result)
     			            {
    -			            	if ($object->id)
    -			            	{
    -			                	$object->addThumbs($destpath);
    -			            	}
    +			            	// Define if we have to generate thumbs or not
    +			            	$generatethumbs = 1;
    +			            	if (GETPOST('section_dir')) $generatethumbs=0;
     
    -			                // TODO Add revert function of addThumbs to remove for old name
    -			                //$object->delThumbs($srcpath);
    +			            	if ($generatethumbs)
    +			            	{
    +				            	if ($object->id)
    +				            	{
    +				                	$object->addThumbs($destpath);
    +				            	}
    +
    +				                // TODO Add revert function of addThumbs to remove thumbs with old name
    +				                //$object->delThumbs($srcpath);
    +			            	}
     
     			                setEventMessages($langs->trans("FileRenamed"), null);
     			            }
    diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
    index 312d6c3d507..39b89ba21f9 100644
    --- a/htdocs/core/actions_massactions.inc.php
    +++ b/htdocs/core/actions_massactions.inc.php
    @@ -74,6 +74,7 @@ if (! $error && $massaction == 'confirm_presend')
     	{
     		$thirdparty=new Societe($db);
     		if ($objecttmp->element == 'expensereport') $thirdparty=new User($db);
    +		if ($objecttmp->element == 'holiday')       $thirdparty=new User($db);
     
     		$objecttmp=new $objectclass($db);
     		foreach($toselect as $toselectid)
    @@ -83,9 +84,10 @@ if (! $error && $massaction == 'confirm_presend')
     			if ($result > 0)
     			{
     				$listofobjectid[$toselectid]=$toselectid;
    -				$thirdpartyid=$objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid;
    -				if ($objecttmp->element == 'societe') $thirdpartyid=$objecttmp->id;
    +				$thirdpartyid=($objecttmp->fk_soc?$objecttmp->fk_soc:$objecttmp->socid);
    +				if ($objecttmp->element == 'societe')       $thirdpartyid=$objecttmp->id;
     				if ($objecttmp->element == 'expensereport') $thirdpartyid=$objecttmp->fk_user_author;
    +				if ($objecttmp->element == 'holiday')       $thirdpartyid=$objecttmp->fk_user;
     				$listofobjectthirdparties[$thirdpartyid]=$thirdpartyid;
     				$listofobjectref[$thirdpartyid][$toselectid]=$objecttmp;
     			}
    @@ -326,7 +328,7 @@ if (! $error && $massaction == 'confirm_presend')
     				$message = GETPOST('message','none');
     
     				$sendtobcc = GETPOST('sendtoccc');
    -				if ($objectclass == 'Propale') 				$sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO));
    +				if ($objectclass == 'Propal') 				$sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_PROPOSAL_TO));
     				if ($objectclass == 'Commande') 			$sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_ORDER_TO));
     				if ($objectclass == 'Facture') 				$sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO));
     				if ($objectclass == 'Supplier_Proposal') 	$sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO));
    @@ -379,11 +381,32 @@ if (! $error && $massaction == 'confirm_presend')
     					$filename = $attachedfiles['names'];
     					$mimetype = $attachedfiles['mimes'];
     
    +					// Define the trackid when emails sent from the mass action
    +					if ($oneemailperrecipient)
    +					{
    +						$trackid='thi'.$thirdparty->id;
    +						if ($objecttmp->element == 'expensereport') $trackid='use'.$thirdparty->id;
    +						if ($objecttmp->element == 'holiday') $trackid='use'.$thirdparty->id;
    +					}
    +					else
    +					{
    +						$trackid=strtolower(get_class($objecttmp));
    +						if (get_class($objecttmp)=='Contrat')  $trackid='con';
    +						if (get_class($objecttmp)=='Propal')   $trackid='pro';
    +						if (get_class($objecttmp)=='Commande') $trackid='ord';
    +						if (get_class($objecttmp)=='Facture')  $trackid='inv';
    +						if (get_class($objecttmp)=='Supplier_Proposal')   $trackid='spr';
    +						if (get_class($objecttmp)=='CommandeFournisseur') $trackid='sor';
    +						if (get_class($objecttmp)=='FactureFournisseur')  $trackid='sin';
    +
    +						$trackid.=$objecttmp->id;
    +					}
     					//var_dump($filepath);
    +					//var_dump($trackid);exit;
     
     					// Send mail (substitutionarray must be done just before this)
    -					require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
    -					$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1);
    +					require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
    +					$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid);
     					if ($mailfile->error)
     					{
     						$resaction.='<div class="error">'.$mailfile->error.'</div>';
    @@ -437,7 +460,7 @@ if (! $error && $massaction == 'confirm_presend')
     								if (! empty($triggername))
     								{
     									// Appel des triggers
    -									include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
    +									include_once DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php";
     									$interface=new Interfaces($db);
     									$result=$interface->run_triggers($triggername, $objectobj, $user, $langs, $conf);
     									if ($result < 0) { $error++; $errors=$interface->errors; }
    @@ -707,7 +730,7 @@ if ($massaction == 'confirm_createbills')
     	if (! $error)
     	{
     		$db->commit();
    -		setEventMessage($langs->trans('BillCreated', $nb_bills_created));
    +		setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs');
     
     		// Make a redirect to avoid to bill twice if we make a refresh or back
     		$param='';
    @@ -829,7 +852,8 @@ if (! $error && $massaction == "builddoc" && $permtoread && ! GETPOST('button_se
     	}
     
     	$arrayofinclusion=array();
    -	foreach($listofobjectref as $tmppdf) $arrayofinclusion[]='^'.preg_quote(dol_sanitizeFileName($tmppdf).'.pdf','/').'$';
    +	foreach($listofobjectref as $tmppdf) $arrayofinclusion[]='^'.preg_quote(dol_sanitizeFileName($tmppdf),'/').'\.pdf$';
    +	foreach($listofobjectref as $tmppdf) $arrayofinclusion[]='^'.preg_quote(dol_sanitizeFileName($tmppdf),'/').'_[a-zA-Z0-9-_]+\.pdf$';	// To include PDF generated from ODX files
     	$listoffiles = dol_dir_list($uploaddir,'all',1,implode('|',$arrayofinclusion),'\.meta$|\.png','date',SORT_DESC,0,true);
     
     	// build list of files with full path
    diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php
    index 302ad161241..d5c40c17ad0 100644
    --- a/htdocs/core/actions_printing.inc.php
    +++ b/htdocs/core/actions_printing.inc.php
    @@ -28,8 +28,7 @@
     // Filename to print must be provided into 'file' parameter
     
     // Print file
    -if ($action == 'print_file' && $user->rights->printing->read)
    -{
    +if ($action == 'print_file' && $user->rights->printing->read) {
         $langs->load("printing");
         require_once DOL_DOCUMENT_ROOT . '/core/modules/printing/modules_printing.php';
         $objectprint = new PrintingDriver($db);
    @@ -48,14 +47,24 @@ if ($action == 'print_file' && $user->rights->printing->read)
                 {
                     $printerfound++;
     
    -                $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':'');
    +                $subdir='';
                     $module = GETPOST('printer', 'alpha');
    -                if ($module =='commande_fournisseur') {
    -                    $module = 'fournisseur';
    -                    $subdir = 'commande';
    +                switch ($module )
    +                {
    +                    case 'livraison' :
    +                        $subdir = 'receipt';
    +                        $module = 'expedition';
    +                        break;
    +                    case 'expedition' :
    +                        $subdir = 'sending';
    +                        break;
    +                    case 'commande_fournisseur' :
    +                        $module = 'fournisseur';
    +                        $subdir = 'commande';
    +                        break;
                     }
                     try {
    -                    $ret = $printer->print_file(GETPOST('file', 'alpha'), $module, $subdir);
    +                    $ret = $printer->printFile(GETPOST('file', 'alpha'), $module, $subdir);
                         if ($ret > 0) {
                             //print '<pre>'.print_r($printer->errors, true).'</pre>';
                             setEventMessages($printer->error, $printer->errors, 'errors');
    diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
    index 6afd6b1e354..0715a78495e 100644
    --- a/htdocs/core/actions_sendmails.inc.php
    +++ b/htdocs/core/actions_sendmails.inc.php
    @@ -425,7 +425,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
     					    if (empty($actiontypecode)) $actiontypecode='AC_OTH_AUTO'; // Event insert into agenda automatically
     
     						$object->socid			= $sendtosocid;	   // To link to a company
    -						$object->sendtoid		= $sendtoid;	   // To link to contacts/addresses. This is an array.
    +						$object->sendtoid		= $sendtoid;	   // To link to contact addresses. This is an array.
     						$object->actiontypecode	= $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
     						$object->actionmsg		= $actionmsg;      // Long text
     						$object->actionmsg2		= $actionmsg2;     // Short text
    @@ -496,5 +496,4 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
     		dol_syslog('Failed to read data of object id='.$object->id.' element='.$object->element);
     		$action = 'presend';
     	}
    -
     }
    diff --git a/htdocs/core/actions_setnotes.inc.php b/htdocs/core/actions_setnotes.inc.php
    index 50b35392644..ec253d5ef4a 100644
    --- a/htdocs/core/actions_setnotes.inc.php
    +++ b/htdocs/core/actions_setnotes.inc.php
    @@ -32,8 +32,33 @@ if ($action == 'setnote_public' && ! empty($permissionnote) && ! GETPOST('cancel
     {
     	if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before');
     	if (empty($object->id)) $object->fetch($id);	// Fetch may not be already done
    -	$result=$object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES),'_public');
    -	if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
    +	
    +	$result_update=$object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES),'_public');
    +
    +	if ($result_update < 0) setEventMessages($object->error, $object->errors, 'errors');
    +	elseif (in_array($object->table_element, array('supplier_proposal', 'propal', 'commande_fournisseur', 'commande', 'facture_fourn', 'facture')))
    +	{
    +		// Define output language
    +		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
    +		{
    +			$outputlangs = $langs;
    +			$newlang = '';
    +			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
    +			if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
    +			if (! empty($newlang)) {
    +				$outputlangs = new Translate("", $conf);
    +				$outputlangs->setDefaultLang($newlang);
    +			}
    +			$model=$object->modelpdf;
    +			$hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
    +			$hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ?  1 : 0));
    +			$hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
    +
    +			$result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
    +			
    +			if ($result < 0) dol_print_error($db,$result);
    +		}
    +	}
     }
     // Set public note
     else if ($action == 'setnote_private' && ! empty($permissionnote) && ! GETPOST('cancel','alpha'))
    diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php
    index f69cc85e026..82f83595537 100644
    --- a/htdocs/core/ajax/ajaxdirpreview.php
    +++ b/htdocs/core/ajax/ajaxdirpreview.php
    @@ -82,9 +82,16 @@ else    // For no ajax call
                 dol_print_error($db,$ecmdir->error);
                 exit;
             }
    +
    +        $relativepath=$ecmdir->getRelativePath();	// Example   'mydir/'
         }
    -    $relativepath=$ecmdir->getRelativePath();
    -    $upload_dir = $rootdirfordoc.'/'.$relativepath;
    +	elseif (GETPOST('section_dir'))
    +	{
    +		$relativepath=GETPOST('section_dir');
    +	}
    +	//var_dump($section.'-'.GETPOST('section_dir').'-'.$relativepath);
    +
    +	$upload_dir = $rootdirfordoc.'/'.$relativepath;
     }
     
     if (empty($url))
    @@ -158,8 +165,8 @@ print '<!-- ajaxdirpreview type='.$type.' -->'."\n";
     //print '<!-- Page called with mode='.dol_escape_htmltag(isset($mode)?$mode:'').' type='.dol_escape_htmltag($type).' module='.dol_escape_htmltag($module).' url='.dol_escape_htmltag($url).' '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
     
     $param=($sortfield?'&sortfield='.$sortfield:'').($sortorder?'&sortorder='.$sortorder:'');
    -if (! empty($website)) $param.='&website='.$website;
    -if (! empty($pageid))  $param.='&pageid='.$pageid;
    +if (! empty($websitekey)) $param.='&website='.$websitekey;
    +if (! empty($pageid))     $param.='&pageid='.$pageid;
     
     
     // Dir scan
    @@ -226,7 +233,18 @@ if ($type == 'directory')
         {
         	if ($module == 'medias')
         	{
    -    		$relativepath=GETPOST('file','alpha');
    +    		/*
    +    		   $_POST is array like
    +    		  'token' => string '062380e11b7dcd009d07318b57b71750' (length=32)
    +			  'action' => string 'file_manager' (length=12)
    +			  'website' => string 'template' (length=8)
    +			  'pageid' => string '124' (length=3)
    +			  'section_dir' => string 'mydir/' (length=3)
    +			  'section_id' => string '0' (length=1)
    +			  'max_file_size' => string '2097152' (length=7)
    +			  'sendit' => string 'Envoyer fichier' (length=15)
    +    		 */
    +    		$relativepath=GETPOST('file','alpha')?GETPOST('file','alpha'):GETPOST('section_dir','alpha');
         		if ($relativepath && $relativepath!= '/') $relativepath.='/';
         		$upload_dir = $dolibarr_main_data_root.'/'.$module.'/'.$relativepath;
         		if (GETPOSTISSET('website') || GETPOSTISSET('file_manager'))
    @@ -234,7 +252,7 @@ if ($type == 'directory')
     	    		$param.='&file_manager=1';
     	    		if (!preg_match('/website=/',$param)) $param.='&website='.urlencode(GETPOST('website','alpha'));
     	    		if (!preg_match('/pageid=/',$param)) $param.='&pageid='.urlencode(GETPOST('pageid','int'));
    -	    		//if (!preg_match('/backtopage=/',$param)) $param.='&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$website.'&pageid='.$pageid);
    +	    		//if (!preg_match('/backtopage=/',$param)) $param.='&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid);
     	    	}
         	}
         	else
    @@ -315,7 +333,7 @@ if ($useajax || $action == 'delete')
     	$formquestion['section_id']=array('type'=>'hidden','value'=>$section_id,'name'=>'section_id');		// We must always put field, even if empty because it is fille by javascript later
     	$formquestion['section_dir']=array('type'=>'hidden','value'=>$section_dir,'name'=>'section_dir');	// We must always put field, even if empty because it is fille by javascript later
     	if (! empty($action) && $action == 'file_manager')	$formquestion['file_manager']=array('type'=>'hidden','value'=>1,'name'=>'file_manager');
    -	if (! empty($website))								$formquestion['website']=array('type'=>'hidden','value'=>$website,'name'=>'website');
    +	if (! empty($websitekey))							$formquestion['website']=array('type'=>'hidden','value'=>$websitekey,'name'=>'website');
     	if (! empty($pageid) && $pageid > 0)				$formquestion['pageid']=array('type'=>'hidden','value'=>$pageid,'name'=>'pageid');
     
     	print $form->formconfirm($url,$langs->trans("DeleteFile"),$langs->trans("ConfirmDeleteFile"),'confirm_deletefile',$formquestion,"no",($useajax?'deletefile':0));
    diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
    index cfff81749de..749f81f1197 100644
    --- a/htdocs/core/ajax/ajaxdirtree.php
    +++ b/htdocs/core/ajax/ajaxdirtree.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2007-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2007-2018  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,6 +31,7 @@ if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
     if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
     if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
     
    +
     if (! isset($mode) || $mode != 'noajax')    // For ajax call
     {
     	$res=@include '../../main.inc.php';
    @@ -39,16 +41,26 @@ if (! isset($mode) || $mode != 'noajax')    // For ajax call
     	include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
     	include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
     
    +	//if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = '/bbb/'; }
    +
     	$openeddir = GETPOST('openeddir');
     	$modulepart= GETPOST('modulepart');
     	$selecteddir = jsUnEscape(GETPOST('dir'));        // relative path. We must decode using same encoding function used by javascript: escape()
    +
    +	$preopened = GETPOST('preopened');
    +
     	if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir);    // We removed last '/' except if it is '/'
     }
     else    // For no ajax call
     {
    +	//if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = GETPOST('preopened'); }
    +
     	$openeddir = GETPOST('openeddir');
     	$modulepart= GETPOST('modulepart');
     	$selecteddir = GETPOST('dir');
    +
    +	$preopened = GETPOST('preopened');
    +
     	if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir);    // We removed last '/' except if it is '/'
     	if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
     }
    @@ -58,8 +70,16 @@ $langs->load("ecm");
     
     // Define fullpathselecteddir.
     $fullpathselecteddir='<none>';
    -if ($modulepart == 'ecm') $fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
    -if ($modulepart == 'medias') $fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
    +if ($modulepart == 'ecm')
    +{
    +	$fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
    +	$fullpathpreopened=$conf->ecm->dir_output.'/'.($preopened != '/' ? $preopened : '');
    +}
    +elseif ($modulepart == 'medias')
    +{
    +	$fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
    +	$fullpathpreopened=$dolibarr_main_data_root.'/medias/'.($preopened != '/' ? $preopened : '');
    +}
     
     
     // Security:
    @@ -77,7 +97,7 @@ if ($modulepart == 'ecm')
     {
     	if (! $user->rights->ecm->read) accessforbidden();
     }
    -if ($modulepart == 'medias')
    +elseif ($modulepart == 'medias')
     {
     	// Always allowed
     }
    @@ -87,20 +107,20 @@ if ($modulepart == 'medias')
      * View
      */
     
    -if (! isset($mode) || $mode != 'noajax')
    +if (! isset($mode) || $mode != 'noajax')	// if ajax mode
     {
     	top_httphead();
     }
     
    -//print '<!-- selecteddir = '.$selecteddir.', openeddir = '.$openeddir.', modulepart='.$modulepart.' -->'."\n";
    +//print '<!-- selecteddir (relative dir we click on) = '.$selecteddir.', openeddir = '.$openeddir.', modulepart='.$modulepart.', preopened='.$preopened.' -->'."\n";
     $userstatic=new User($db);
     $form=new Form($db);
     $ecmdirstatic = new EcmDirectory($db);
     
    -// Load full tree from database. We will use it to define nbofsubdir and nboffilesinsubdir
    +// Load full tree of ECM module from database. We will use it to define nbofsubdir and nboffilesinsubdir
     if (empty($sqltree)) $sqltree=$ecmdirstatic->get_full_arbo(0);
     
    -// Try to find key into $sqltree
    +// Try to find selected dir id into $sqltree and save it into $current_ecmdir_id
     $current_ecmdir_id=-1;
     foreach($sqltree as $keycursor => $val)
     {
    @@ -113,131 +133,13 @@ foreach($sqltree as $keycursor => $val)
     
     if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
     {
    -	if (file_exists($fullpathselecteddir))
    -	{
    -		$files = @scandir($fullpathselecteddir);
    +	treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened);
     
    -		if ($files)
    -	    {
    -	    	natcasesort($files);
    -	    	if (count($files) > 2)    /* The 2 accounts for . and .. */
    -	    	{
    -	    		echo '<ul class="ecmjqft" style="display: none;">'."\n";
    -
    -	    		// All dirs
    -	    		foreach ($files as $file)    // $file can be '.', '..', or 'My dir' or 'My file'
    -	    		{
    -	    		    if ($file == 'temp') continue;
    -
    -	    	        $nbofsubdir=0;
    -	    	        $nboffilesinsubdir=0;
    -
    -	    	        $val=array();
    -
    -	    	        // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
    -			        foreach($sqltree as $key => $tmpval)
    -			        {
    -	    	            //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."<br>\n";
    -			        	if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file))		// We found equivalent record into database
    -			            {
    -			                $val=$tmpval;
    -			                $resarray=tree_showpad($sqltree,$key,1);
    -
    -			                // Refresh cache for this subdir
    -			            	if (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] < 0)	// Cache is not up to date, so we update it for this directory t
    -			            	{
    -			            		$result=$ecmdirstatic->fetch($val['id']);
    -			            		$ecmdirstatic->ref=$ecmdirstatic->label;
    -
    -			            		$result=$ecmdirstatic->refreshcachenboffile(0);
    -			            		$val['cachenbofdoc']=$result;
    -			            	}
    -
    -	                        $a=$resarray[0];
    -	                        $nbofsubdir=$resarray[1];
    -	                        $nboffilesinsubdir=$resarray[2];
    -	                        break;
    -			            }
    -			        }
    -
    -	    		    //print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
    -	    		    if ($file != '.' && $file != '..' && ((! empty($val['fullrelativename']) && $val['id'] >= 0) || dol_is_dir($fullpathselecteddir . (preg_match('/\/$/',$fullpathselecteddir)?'':'/') . $file)))
    -	    		    {
    -						if (empty($val['fullrelativename']))	// If we did not find entry into database, but found a directory (dol_is_dir was ok at previous test)
    -						{
    -	    		    		$val['fullrelativename']=(($selecteddir && $selecteddir != '/')?$selecteddir.'/':'').$file;
    -	    		    		$val['id']=0;
    -	    		    		$val['label']=$file;
    -	    		    		$val['description']='';
    -	    		    		$nboffilesinsubdir=$langs->trans("Unknown");
    -						}
    -
    -			        	print '<li class="directory collapsed">';
    -
    -	    				print "<a class=\"fmdirlia jqft ecmjqft\" href=\"";
    -	    				print "#";
    -	    				print "\" rel=\"" . dol_escape_htmltag($val['fullrelativename'].'/') . "\" id=\"fmdirlia_id_".$val['id']."\"";
    -						print " onClick=\"loadandshowpreview('".dol_escape_js($val['fullrelativename'])."',".$val['id'].")";
    -	    				print "\">";
    -	    				print dol_escape_htmltag($file);
    -	    				print "</a>";
    -
    -	    				print '<div class="ecmjqft">';
    -
    -	    				print '<table class="nobordernopadding"><tr>';
    -
    -	    				/*print '<td align="left">';
    -	    				print dol_escape_htmltag($file);
    -	    				print '</td>';*/
    -
    -	    				// Nb of docs
    -	    				print '<td align="right">';
    -	    				print (isset($val['cachenbofdoc']) && $val['cachenbofdoc']  >= 0)?$val['cachenbofdoc']:'&nbsp;';
    -	    				print '</td>';
    -	    				print '<td align="left">';
    -	    				if ($nbofsubdir > 0  && $nboffilesinsubdir > 0) print '<font color="#AAAAAA">+'.$nboffilesinsubdir.'</font> ';
    -	    				print '</td>';
    -
    -	    				// Edit link
    -	    				print '<td align="right" width="18"><a href="';
    -	    				print DOL_URL_ROOT.'/ecm/dir_card.php?module='.urlencode($modulepart).'&section='.$val['id'].'&relativedir='.urlencode($val['fullrelativename']);
    -	    				print '&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$website.'&pageid='.$pageid);
    -	    				print '">'.img_edit($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle opacitymedium"').'</a></td>';
    -
    -	    				// Add link
    -	    				//print '<td align="right"><a href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&amp;catParent='.$val['id'].'">'.img_edit_add().'</a></td>';
    -	    				//print '<td align="right" width="14">&nbsp;</td>';
    -
    -	    				// Info
    -	    				if ($modulepart == 'ecm')
    -	    				{
    -	    					print '<td align="right" width="18">';
    -		    				$userstatic->id=isset($val['fk_user_c'])?$val['fk_user_c']:0;
    -		    				$userstatic->lastname=isset($val['login_c'])?$val['login_c']:0;
    -		    				$htmltooltip='<b>'.$langs->trans("ECMSection").'</b>: '.$val['label'].'<br>';
    -		    				$htmltooltip='<b>'.$langs->trans("Type").'</b>: '.$langs->trans("ECMSectionManual").'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("ECMCreationUser").'</b>: '.$userstatic->getNomUrl(1, '', false, 1).'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("ECMCreationDate").'</b>: '.(isset($val['date_c'])?dol_print_date($val['date_c'],"dayhour"):$langs->trans("NeedRefresh")).'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("Description").'</b>: '.$val['description'].'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInDir").'</b>: '.((isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:$langs->trans("NeedRefresh")).'<br>';
    -		    				if ($nboffilesinsubdir > 0) $htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInSubDir").'</b>: '.$nboffilesinsubdir;
    -		    				else $htmltooltip.='<b>'.$langs->trans("ECMNbOfSubDir").'</b>: '.($nbofsubdir >= 0 ? $nbofsubdir : $langs->trans("NeedRefresh")).'<br>';
    -		    				print $form->textwithpicto('',$htmltooltip,1,"info");
    -		    				print "</td>";
    -	    				}
    -
    -	    				print "</tr></table>\n";
    -	                    print '</div>';
    -
    -	                    //print '<div>&nbsp;</div>';
    -	    				print "</li>\n";
    -	    			}
    -	    		}
    -
    -	    		// Enable jquery handlers on new generated HTML objects (same code than into lib_footer.js.php)
    -	    		// Because the content is reloaded by ajax call, we must also reenable some jquery hooks
    -				print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip (reload into ajaxdirtree) -->\n";
    -	    		print '<script type="text/javascript">
    +	// TODO Find a solution to not output this code for each leaf we open
    +	// Enable jquery handlers on new generated HTML objects (same code than into lib_footer.js.php)
    +	// Because the content is reloaded by ajax call, we must also reenable some jquery hooks
    +	print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip (reload into ajaxdirtree) -->\n";
    +	print '<script type="text/javascript">
     	            	jQuery(document).ready(function () {
     	            		jQuery(".classfortooltip").tooltip({
     							show: { collision: "flipfit", effect:\'toggle\', delay:50 },
    @@ -250,13 +152,6 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE
     	            	});
     	            	</script>';
     
    -	    		echo "</ul>\n";
    -
    -	    	}
    -	    }
    -	    else print "PermissionDenied";
    -	}
    -
     	// This ajax service is called only when a directory $selecteddir is opened but not when closed.
     	//print '<script language="javascript">';
     	//print "loadandshowpreview('".dol_escape_js($selecteddir)."');";
    @@ -426,3 +321,175 @@ if (empty($conf->use_javascript_ajax) || ! empty($conf->global->MAIN_ECM_DISABLE
     
     // Close db if mode is not noajax
     if ((! isset($mode) || $mode != 'noajax') && is_object($db)) $db->close();
    +
    +
    +
    +/**
    + * treeOutputForAbsoluteDir
    + *
    + * @param	array	$sqltree				Sqltree
    + * @param	string	$selecteddir			Selected dir
    + * @param	string	$fullpathselecteddir	Full path of selected dir
    + * @param	string	$modulepart				Modulepart
    + * @param	string	$websitekey				Website key
    + * @param	int		$pageid					Page id
    + * @param	string	$preopened				Current open dir
    + * @param	string	$fullpathpreopened		Full path of current open dir
    + * @param	int		$depth					Depth
    + * @return	void
    + */
    +function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened, $depth=0)
    +{
    +	global $conf, $db, $langs, $form;
    +	global $dolibarr_main_data_root;
    +
    +	$ecmdirstatic = new EcmDirectory($db);
    +	$userstatic = new User($db);
    +
    +	if (file_exists($fullpathselecteddir))
    +	{
    +		$files = @scandir($fullpathselecteddir);
    +
    +		if (! empty($files))
    +		{
    +			natcasesort($files);
    +			if (count($files) > 2)    /* The 2 accounts for . and .. */
    +			{
    +				echo '<ul class="ecmjqft" style="display: none;">'."\n";
    +
    +				// All dirs
    +				foreach ($files as $file)    // $file can be '.', '..', or 'My dir' or 'My file'
    +				{
    +					if ($file == 'temp') continue;
    +
    +					$nbofsubdir=0;
    +					$nboffilesinsubdir=0;
    +
    +					$val=array();
    +
    +					// Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
    +					foreach($sqltree as $key => $tmpval)
    +					{
    +						//print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."<br>\n";
    +						if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file))		// We found equivalent record into database
    +						{
    +							$val=$tmpval;
    +							$resarray=tree_showpad($sqltree,$key,1);
    +
    +							// Refresh cache for this subdir
    +							if (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] < 0)	// Cache is not up to date, so we update it for this directory t
    +							{
    +								$result=$ecmdirstatic->fetch($val['id']);
    +								$ecmdirstatic->ref=$ecmdirstatic->label;
    +
    +								$result=$ecmdirstatic->refreshcachenboffile(0);
    +								$val['cachenbofdoc']=$result;
    +							}
    +
    +							$a=$resarray[0];
    +							$nbofsubdir=$resarray[1];
    +							$nboffilesinsubdir=$resarray[2];
    +							break;
    +						}
    +					}
    +
    +					//print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
    +					if ($file != '.' && $file != '..' && ((! empty($val['fullrelativename']) && $val['id'] >= 0) || dol_is_dir($fullpathselecteddir . (preg_match('/\/$/',$fullpathselecteddir)?'':'/') . $file)))
    +					{
    +						if (empty($val['fullrelativename']))	// If we did not find entry into database, but found a directory (dol_is_dir was ok at previous test)
    +						{
    +							$val['fullrelativename']=(($selecteddir && $selecteddir != '/')?$selecteddir.'/':'').$file;
    +							$val['id']=0;
    +							$val['label']=$file;
    +							$val['description']='';
    +							$nboffilesinsubdir=$langs->trans("Unknown");
    +						}
    +
    +						$collapsedorexpanded='collapsed';
    +						if (preg_match('/^'.preg_quote($val['fullrelativename'].'/', '/').'/', $preopened)) $collapsedorexpanded='expanded';
    +						print '<li class="directory '.$collapsedorexpanded.'">';	// collapsed is opposite if expanded
    +
    +						print "<a class=\"fmdirlia jqft ecmjqft\" href=\"";
    +						print "#";
    +						print "\" rel=\"" . dol_escape_htmltag($val['fullrelativename'].'/') . "\" id=\"fmdirlia_id_".$val['id']."\"";
    +						print " onClick=\"loadandshowpreview('".dol_escape_js($val['fullrelativename'])."',".$val['id'].")";
    +						print "\">";
    +						print dol_escape_htmltag($file);
    +						print "</a>";
    +
    +						print '<div class="ecmjqft">';
    +
    +						print '<table class="nobordernopadding"><tr>';
    +
    +						/*print '<td align="left">';
    +						 print dol_escape_htmltag($file);
    +						 print '</td>';*/
    +
    +						// Nb of docs
    +						print '<td align="right">';
    +						print (isset($val['cachenbofdoc']) && $val['cachenbofdoc']  >= 0)?$val['cachenbofdoc']:'&nbsp;';
    +						print '</td>';
    +						print '<td align="left">';
    +						if ($nbofsubdir > 0  && $nboffilesinsubdir > 0) print '<font color="#AAAAAA">+'.$nboffilesinsubdir.'</font> ';
    +						print '</td>';
    +
    +						// Edit link
    +						print '<td align="right" width="18"><a href="';
    +						print DOL_URL_ROOT.'/ecm/dir_card.php?module='.urlencode($modulepart).'&section='.$val['id'].'&relativedir='.urlencode($val['fullrelativename']);
    +						print '&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid);
    +						print '">'.img_edit($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle opacitymedium"').'</a></td>';
    +
    +						// Add link
    +						//print '<td align="right"><a href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&amp;catParent='.$val['id'].'">'.img_edit_add().'</a></td>';
    +						//print '<td align="right" width="14">&nbsp;</td>';
    +
    +						// Info
    +						if ($modulepart == 'ecm')
    +						{
    +							print '<td align="right" width="18">';
    +							$userstatic->id=isset($val['fk_user_c'])?$val['fk_user_c']:0;
    +							$userstatic->lastname=isset($val['login_c'])?$val['login_c']:0;
    +							$htmltooltip='<b>'.$langs->trans("ECMSection").'</b>: '.$val['label'].'<br>';
    +							$htmltooltip='<b>'.$langs->trans("Type").'</b>: '.$langs->trans("ECMSectionManual").'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("ECMCreationUser").'</b>: '.$userstatic->getNomUrl(1, '', false, 1).'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("ECMCreationDate").'</b>: '.(isset($val['date_c'])?dol_print_date($val['date_c'],"dayhour"):$langs->trans("NeedRefresh")).'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("Description").'</b>: '.$val['description'].'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInDir").'</b>: '.((isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:$langs->trans("NeedRefresh")).'<br>';
    +							if ($nboffilesinsubdir > 0) $htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInSubDir").'</b>: '.$nboffilesinsubdir;
    +							else $htmltooltip.='<b>'.$langs->trans("ECMNbOfSubDir").'</b>: '.($nbofsubdir >= 0 ? $nbofsubdir : $langs->trans("NeedRefresh")).'<br>';
    +							print $form->textwithpicto('',$htmltooltip,1,"info");
    +							print "</td>";
    +						}
    +
    +						print "</tr></table>\n";
    +						print '</div>';
    +
    +						//print 'selecteddir='.$selecteddir.' preopened='.$preopened.' $val[\'fullrelativename\']='.$val['fullrelativename']."<br>\n";
    +						if (preg_match('/^'.preg_quote($val['fullrelativename'].'/', '/').'/', $preopened))
    +						{
    +							//print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
    +							$newselecteddir = $val['fullrelativename'];
    +							$newfullpathselecteddir='';
    +							if ($modulepart == 'ecm')
    +							{
    +								$newfullpathselecteddir=$conf->ecm->dir_output.'/'.($val['fullrelativename'] != '/' ? $val['fullrelativename'] : '');
    +							}
    +							elseif ($modulepart == 'medias')
    +							{
    +								$newfullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($val['fullrelativename'] != '/' ? $val['fullrelativename'] : '');
    +							}
    +
    +							if ($newfullpathselecteddir) treeOutputForAbsoluteDir($sqltree, $newselecteddir, $newfullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened, $depth+1);
    +						}
    +
    +						print "</li>\n";
    +					}
    +				}
    +
    +				echo "</ul>\n";
    +			}
    +		}
    +		else print "PermissionDenied";
    +	}
    +}
    +
    diff --git a/htdocs/core/ajax/check_notifications.php b/htdocs/core/ajax/check_notifications.php
    index 6984bbff5b4..a5c73655bab 100644
    --- a/htdocs/core/ajax/check_notifications.php
    +++ b/htdocs/core/ajax/check_notifications.php
    @@ -44,37 +44,37 @@ $eventfound = array();
     //dol_syslog('time='.$time.' $_SESSION[auto_ck_events_not_before]='.$_SESSION['auto_check_events_not_before']);
     
     // TODO Try to make a solution with only a javascript timer that is easier. Difficulty is to avoid notification twice when several tabs are opened.
    -if ($time >= $_SESSION['auto_check_events_not_before']) 
    +if ($time >= $_SESSION['auto_check_events_not_before'])
     {
         $time_update = (int) $conf->global->MAIN_BROWSER_NOTIFICATION_FREQUENCY;   // Always defined
    -    if (! empty($_SESSION['auto_check_events_not_before'])) 
    +    if (! empty($_SESSION['auto_check_events_not_before']))
         {
             // We start scan from the not before so if two tabs were opend at differents seconds and we close one (so the js timer),
    -        // then we are not losing periods 
    +        // then we are not losing periods
             $starttime = $_SESSION['auto_check_events_not_before'];
             // Protection to avoid too long sessions
    -        if ($starttime < ($time - (int) $conf->global->MAIN_SESSION_TIMEOUT)) 
    +        if ($starttime < ($time - (int) $conf->global->MAIN_SESSION_TIMEOUT))
             {
                 dol_syslog("We ask to check browser notification on a too large period. We fix this with current date.");
                 $starttime = $time;
             }
         }
    -    else 
    +    else
         {
             $starttime = $time;
         }
    -    
    +
         $_SESSION['auto_check_events_not_before'] = $time + $time_update;
    -    
    -    // Force save of session change we did. 
    +
    +    // Force save of session change we did.
         // WARNING: Any change in sessions after that will not be saved !
         session_write_close();
    -    
    +
         require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
    -	
    -    
    +
    +
         dol_syslog('NEW $_SESSION[auto_check_events_not_before]='.$_SESSION['auto_check_events_not_before']);
    -    
    +
         $sql = 'SELECT id';
         $sql .= ' FROM ' . MAIN_DB_PREFIX . 'actioncomm a, ' . MAIN_DB_PREFIX . 'actioncomm_resources ar';
         $sql .= ' WHERE a.id = ar.fk_actioncomm';
    @@ -91,11 +91,11 @@ if ($time >= $_SESSION['auto_check_events_not_before'])
     
             $actionmod = new ActionComm($db);
     
    -        while ($obj = $db->fetch_object($resql)) 
    +        while ($obj = $db->fetch_object($resql))
             {
    -            $langs->load("agenda");
    -            $langs->load("commercial");
    -            
    +            // Load translation files required by the page
    +            $langs->loadLangs(array('agenda', 'commercial'));
    +
                 $actionmod->fetch($obj->id);
     
                 // Message must be formated and translated to be used with javascript directly
    @@ -105,7 +105,7 @@ if ($time >= $_SESSION['auto_check_events_not_before'])
                 $event['tipo'] = $langs->transnoentities('Action' . $actionmod->code);
                 $event['titulo'] = $actionmod->label;
                 $event['location'] = $langs->transnoentities('Location').': '.$actionmod->location;
    -            
    +
                 $eventfound[] = $event;
             }
         }
    @@ -113,7 +113,6 @@ if ($time >= $_SESSION['auto_check_events_not_before'])
         {
             dol_syslog("Error sql = ".$db->lasterror(), LOG_ERR);
         }
    -
     }
     
     print json_encode($eventfound);
    diff --git a/htdocs/core/ajax/price.php b/htdocs/core/ajax/price.php
    index 577f659b2cc..86073a5a409 100644
    --- a/htdocs/core/ajax/price.php
    +++ b/htdocs/core/ajax/price.php
    @@ -25,7 +25,7 @@ if (! defined('NOREQUIREMENU'))  define('NOREQUIREMENU','1');
     if (! defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX','1');
     if (! defined('NOREQUIRESOC'))   define('NOREQUIRESOC','1');
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     
     $output		= GETPOST('output','alpha');
     $amount		= price2num(GETPOST('amount','alpha'));
    @@ -52,7 +52,6 @@ if (! empty($output) && isset($amount) && isset($tva_tx))
     			$price = price2num($amount * (1 + ($tva_tx/100)), 'MU');
     			$return['price_ht'] = $amount;
     			$return['price_ttc'] = (isset($price) && $price != '' ? price($price) : '');
    -
     		}
     		else if ($output == 'price_ht') {
     
    diff --git a/htdocs/core/boxes/box_actions.php b/htdocs/core/boxes/box_actions.php
    index f6d9d03dccf..05bbdba3831 100644
    --- a/htdocs/core/boxes/box_actions.php
    +++ b/htdocs/core/boxes/box_actions.php
    @@ -37,7 +37,11 @@ class box_actions extends ModeleBoxes
     	var $boxlabel="BoxLastActions";
     	var $depends = array("agenda");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -228,7 +232,6 @@ class box_actions extends ModeleBoxes
     					}
     				}
     				$out.= '</table>';
    -
     			}
     			$out.= '</div>';
     			if ($actioncejour)
    @@ -256,6 +259,5 @@ class box_actions extends ModeleBoxes
     
     		return '';
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php
    index 4fb8cc19c82..bd3163268ac 100644
    --- a/htdocs/core/boxes/box_activity.php
    +++ b/htdocs/core/boxes/box_activity.php
    @@ -35,7 +35,11 @@ class box_activity extends ModeleBoxes
         var $boxlabel='BoxGlobalActivity';
         var $depends = array("facture");
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
         var $param;
         var $enabled = 1;
     
    diff --git a/htdocs/core/boxes/box_bookmarks.php b/htdocs/core/boxes/box_bookmarks.php
    index e2a45ffab22..c3a29877104 100644
    --- a/htdocs/core/boxes/box_bookmarks.php
    +++ b/htdocs/core/boxes/box_bookmarks.php
    @@ -33,7 +33,11 @@ class box_bookmarks extends ModeleBoxes
     	var $boxlabel="BoxMyLastBookmarks";
     	var $depends = array("bookmark");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -157,6 +161,5 @@ class box_bookmarks extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php
    index 7ab2de66a7b..96ccd7b675d 100644
    --- a/htdocs/core/boxes/box_clients.php
    +++ b/htdocs/core/boxes/box_clients.php
    @@ -37,7 +37,11 @@ class box_clients extends ModeleBoxes
     	var $boxlabel="BoxLastCustomers";
     	var $depends = array("societe");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $enabled = 1;
     
     	var $info_box_head = array();
    @@ -159,7 +163,6 @@ class box_clients extends ModeleBoxes
                     'text' => $langs->trans("ReadPermissionNotAllowed")
     			);
     		}
    -
     	}
     
     	/**
    @@ -174,6 +177,5 @@ class box_clients extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php
    index 9bbde140dbe..5aeb6179207 100644
    --- a/htdocs/core/boxes/box_commandes.php
    +++ b/htdocs/core/boxes/box_commandes.php
    @@ -37,7 +37,11 @@ class box_commandes extends ModeleBoxes
         var $boxlabel="BoxLastCustomerOrders";
         var $depends = array("commande");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
         var $info_box_head = array();
    @@ -198,6 +202,5 @@ class box_commandes extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
     }
     
    diff --git a/htdocs/core/boxes/box_comptes.php b/htdocs/core/boxes/box_comptes.php
    index 52f8e6c7d9e..8606d9b91f7 100644
    --- a/htdocs/core/boxes/box_comptes.php
    +++ b/htdocs/core/boxes/box_comptes.php
    @@ -38,7 +38,11 @@ class box_comptes extends ModeleBoxes
     	var $boxlabel="BoxCurrentAccounts";
     	var $depends = array("banque");     // Box active if module banque active
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     	var $enabled = 1;
     
    @@ -170,7 +174,6 @@ class box_comptes extends ModeleBoxes
                     'text' => $langs->trans("ReadPermissionNotAllowed")
                 );
             }
    -
     	}
     
     	/**
    @@ -185,6 +188,5 @@ class box_comptes extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php
    index a8dc7f1231d..4feb101c090 100644
    --- a/htdocs/core/boxes/box_contacts.php
    +++ b/htdocs/core/boxes/box_contacts.php
    @@ -39,7 +39,11 @@ class box_contacts extends ModeleBoxes
     	var $boxlabel="BoxLastContacts";
     	var $depends = array("societe");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -185,6 +189,5 @@ class box_contacts extends ModeleBoxes
     	{
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php
    index 49d6df67d7f..7592f882b59 100644
    --- a/htdocs/core/boxes/box_contracts.php
    +++ b/htdocs/core/boxes/box_contracts.php
    @@ -36,7 +36,11 @@ class box_contracts extends ModeleBoxes
         var $boxlabel="BoxLastContracts";
         var $depends = array("contrat");	// conf->contrat->enabled
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
         var $param;
     
         var $info_box_head = array();
    @@ -79,7 +83,7 @@ class box_contracts extends ModeleBoxes
             	$contractstatic=new Contrat($db);
             	$thirdpartytmp=new Societe($db);
     
    -    	    $sql = "SELECT s.nom as name, s.rowid as socid,";
    +    	    $sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
         		$sql.= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.datec, c.fin_validite, c.date_cloture";
         		$sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c";
         		if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    @@ -104,6 +108,7 @@ class box_contracts extends ModeleBoxes
                     while ($line < $num)
                     {
         				$objp = $db->fetch_object($resql);
    +
         				$datec=$db->jdate($objp->datec);
         				$dateterm=$db->jdate($objp->fin_validite);
         				$dateclose=$db->jdate($objp->date_cloture);
    @@ -116,6 +121,13 @@ class box_contracts extends ModeleBoxes
     
         				$thirdpartytmp->name = $objp->name;
         				$thirdpartytmp->id = $objp->socid;
    +    				$thirdpartytmp->email = $objp->email;
    +    				$thirdpartytmp->client = $objp->client;
    +    				$thirdpartytmp->fournisseur = $objp->fournisseur;
    +    				$thirdpartytmp->code_client = $objp->code_client;
    +    				$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
    +    				$thirdpartytmp->code_compta = $objp->code_compta;
    +    				$thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
     
         				// fin_validite is no more on contract but on services
         				// if ($objp->fk_statut == 1 && $dateterm < ($now - $conf->contrat->cloture->warning_delay)) { $late = img_warning($langs->trans("Late")); }
    @@ -181,6 +193,5 @@ class box_contracts extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
     }
     
    diff --git a/htdocs/core/boxes/box_external_rss.php b/htdocs/core/boxes/box_external_rss.php
    index 01eb4ac8893..f08c809627d 100644
    --- a/htdocs/core/boxes/box_external_rss.php
    +++ b/htdocs/core/boxes/box_external_rss.php
    @@ -39,7 +39,11 @@ class box_external_rss extends ModeleBoxes
         var $boxlabel="BoxLastRssInfos";
         var $depends = array("externalrss");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $paramdef;	// Params of box definition (not user params)
     
         var $info_box_head = array();
    @@ -194,6 +198,5 @@ class box_external_rss extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
     }
     
    diff --git a/htdocs/core/boxes/box_factures.php b/htdocs/core/boxes/box_factures.php
    index 9b457bab856..36c472cfc22 100644
    --- a/htdocs/core/boxes/box_factures.php
    +++ b/htdocs/core/boxes/box_factures.php
    @@ -35,7 +35,11 @@ class box_factures extends ModeleBoxes
     	var $boxlabel="BoxLastCustomerBills";
     	var $depends = array("facture");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -189,7 +193,6 @@ class box_factures extends ModeleBoxes
                         'text' => ($db->error().' sql='.$sql),
                     );
                 }
    -
             } else {
                 $this->info_box_contents[0][0] = array(
                     'td' => 'align="left" class="nohover opacitymedium"',
    @@ -210,5 +213,4 @@ class box_factures extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
    diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php
    index 00df80f334b..c865cf185c4 100644
    --- a/htdocs/core/boxes/box_factures_fourn.php
    +++ b/htdocs/core/boxes/box_factures_fourn.php
    @@ -36,7 +36,11 @@ class box_factures_fourn extends ModeleBoxes
     	var $boxlabel="BoxLastSupplierBills";
     	var $depends = array("facture","fournisseur");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -214,6 +218,5 @@ class box_factures_fourn extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php
    index 1f894be3309..e8dedf59c41 100644
    --- a/htdocs/core/boxes/box_factures_fourn_imp.php
    +++ b/htdocs/core/boxes/box_factures_fourn_imp.php
    @@ -35,7 +35,11 @@ class box_factures_fourn_imp extends ModeleBoxes
     	var $boxlabel = "BoxOldestUnpaidSupplierBills";
     	var $depends = array("facture","fournisseur");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -187,7 +191,6 @@ class box_factures_fourn_imp extends ModeleBoxes
                     'text' => $langs->trans("ReadPermissionNotAllowed")
                 );
             }
    -
         }
     
     	/**
    @@ -202,6 +205,5 @@ class box_factures_fourn_imp extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php
    index 32fa7c823d7..dd64a07b8d9 100644
    --- a/htdocs/core/boxes/box_factures_imp.php
    +++ b/htdocs/core/boxes/box_factures_imp.php
    @@ -38,7 +38,11 @@ class box_factures_imp extends ModeleBoxes
     	var $boxlabel="BoxOldestUnpaidCustomerBills";
     	var $depends = array("facture");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -207,5 +211,4 @@ class box_factures_imp extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
    diff --git a/htdocs/core/boxes/box_ficheinter.php b/htdocs/core/boxes/box_ficheinter.php
    index ef7ba62c15c..76d1414f53f 100644
    --- a/htdocs/core/boxes/box_ficheinter.php
    +++ b/htdocs/core/boxes/box_ficheinter.php
    @@ -36,7 +36,11 @@ class box_ficheinter extends ModeleBoxes
     	var $boxlabel="BoxFicheInter";
     	var $depends = array("ficheinter");	// conf->contrat->enabled
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -166,6 +170,5 @@ class box_ficheinter extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php
    index 32ffd1f5618..0ca14fae7f5 100644
    --- a/htdocs/core/boxes/box_fournisseurs.php
    +++ b/htdocs/core/boxes/box_fournisseurs.php
    @@ -36,7 +36,11 @@ class box_fournisseurs extends ModeleBoxes
         var $boxlabel="BoxLastSuppliers";
         var $depends = array("fournisseur");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
         var $info_box_head = array();
    @@ -146,7 +150,6 @@ class box_fournisseurs extends ModeleBoxes
                     'text' => $langs->trans("ReadPermissionNotAllowed")
                 );
             }
    -
         }
     
     	/**
    @@ -161,6 +164,5 @@ class box_fournisseurs extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
     }
     
    diff --git a/htdocs/core/boxes/box_goodcustomers.php b/htdocs/core/boxes/box_goodcustomers.php
    index 8e4ec988144..16668987a40 100644
    --- a/htdocs/core/boxes/box_goodcustomers.php
    +++ b/htdocs/core/boxes/box_goodcustomers.php
    @@ -38,7 +38,11 @@ class box_goodcustomers extends ModeleBoxes
     	var $boxlabel="BoxGoodCustomers";
     	var $depends = array("societe");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $enabled = 1;
     
     	var $info_box_head = array();
    @@ -155,7 +159,6 @@ class box_goodcustomers extends ModeleBoxes
     				'text' => $langs->trans("ReadPermissionNotAllowed")
     			);
     		}
    -
     	}
     
     	/**
    diff --git a/htdocs/core/boxes/box_graph_invoices_permonth.php b/htdocs/core/boxes/box_graph_invoices_permonth.php
    index abbdc7b7c71..fd0b4e593c0 100644
    --- a/htdocs/core/boxes/box_graph_invoices_permonth.php
    +++ b/htdocs/core/boxes/box_graph_invoices_permonth.php
    @@ -33,7 +33,10 @@ class box_graph_invoices_permonth extends ModeleBoxes
     	var $boxlabel="BoxCustomersInvoicesPerMonth";
     	var $depends = array("facture");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $info_box_head = array();
     	var $info_box_contents = array();
    @@ -255,7 +258,6 @@ class box_graph_invoices_permonth extends ModeleBoxes
     			{
     				$this->info_box_contents[0][0] = array('tr'=>'class="oddeven nohover"', 'td' => 'align="left" class="nohover"', 'maxlength'=>500, 'text' => $mesg);
     			}
    -
     		}
     		else {
     			$this->info_box_contents[0][0] = array(
    @@ -277,6 +279,5 @@ class box_graph_invoices_permonth extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php
    index 53d9ce08059..f13b19259c9 100644
    --- a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php
    +++ b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php
    @@ -33,7 +33,10 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes
     	var $boxlabel="BoxSuppliersInvoicesPerMonth";
     	var $depends = array("fournisseur");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $info_box_head = array();
     	var $info_box_contents = array();
    @@ -254,7 +257,6 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes
         	        										'maxlength'=>500,
     	            										'text' => $mesg);
     			}
    -
     		}
     		else {
     			$this->info_box_contents[0][0] = array(
    @@ -276,6 +278,5 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_graph_orders_permonth.php b/htdocs/core/boxes/box_graph_orders_permonth.php
    index 05a0ff498ec..fefa90c5fea 100644
    --- a/htdocs/core/boxes/box_graph_orders_permonth.php
    +++ b/htdocs/core/boxes/box_graph_orders_permonth.php
    @@ -33,7 +33,10 @@ class box_graph_orders_permonth extends ModeleBoxes
     	var $boxlabel="BoxCustomersOrdersPerMonth";
     	var $depends = array("commande");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $info_box_head = array();
     	var $info_box_contents = array();
    @@ -253,7 +256,6 @@ class box_graph_orders_permonth extends ModeleBoxes
         	        										'maxlength'=>500,
     	            										'text' => $mesg);
     			}
    -
     		}
     		else {
     			$this->info_box_contents[0][0] = array(
    @@ -275,6 +277,5 @@ class box_graph_orders_permonth extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php
    index e88ed46be72..e388d226fd2 100644
    --- a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php
    +++ b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php
    @@ -33,7 +33,10 @@ class box_graph_orders_supplier_permonth extends ModeleBoxes
     	var $boxlabel="BoxSuppliersOrdersPerMonth";
     	var $depends = array("fournisseur");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $info_box_head = array();
     	var $info_box_contents = array();
    @@ -252,7 +255,6 @@ class box_graph_orders_supplier_permonth extends ModeleBoxes
         	        										'maxlength'=>500,
     	            										'text' => $mesg);
     			}
    -
     		}
     		else {
     			$this->info_box_contents[0][0] = array(
    @@ -274,6 +276,5 @@ class box_graph_orders_supplier_permonth extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php
    index 39a7a3984d2..9dc4c162e0f 100644
    --- a/htdocs/core/boxes/box_graph_product_distribution.php
    +++ b/htdocs/core/boxes/box_graph_product_distribution.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2013-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -33,7 +34,11 @@ class box_graph_product_distribution extends ModeleBoxes
     	var $boxlabel="BoxProductDistribution";
     	var $depends = array("product|service","facture|propal|commande");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -135,10 +140,10 @@ class box_graph_product_distribution extends ModeleBoxes
     
     		if (! empty($conf->facture->enabled) && ! empty($user->rights->facture->lire))
     		{
    -
     			// Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...)
     			if ($showinvoicenb)
     			{
    +                $langs->load("bills");
     				include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facturestats.class.php';
     
     				$showpointvalue = 1; $nocolor = 0;
    @@ -198,6 +203,7 @@ class box_graph_product_distribution extends ModeleBoxes
     			// Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...)
     			if ($showpropalnb)
     			{
    +                $langs->load("propal");
     				include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propalestats.class.php';
     
     				$showpointvalue = 1; $nocolor = 0;
    @@ -254,11 +260,10 @@ class box_graph_product_distribution extends ModeleBoxes
     
     		if (! empty($conf->commande->enabled) && ! empty($user->rights->commande->lire))
     		{
    -			$langs->load("orders");
    -
     			// Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...)
     			if ($showordernb)
     			{
    +			    $langs->load("orders");
     				include_once DOL_DOCUMENT_ROOT.'/commande/class/commandestats.class.php';
     
     				$showpointvalue = 1; $nocolor = 0;
    @@ -397,7 +402,6 @@ class box_graph_product_distribution extends ModeleBoxes
     				'text' => $mesg
     			);
     		}
    -
     	}
     
     	/**
    @@ -412,6 +416,5 @@ class box_graph_product_distribution extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_graph_propales_permonth.php b/htdocs/core/boxes/box_graph_propales_permonth.php
    index 4f05e186b43..f28b0ec2c99 100644
    --- a/htdocs/core/boxes/box_graph_propales_permonth.php
    +++ b/htdocs/core/boxes/box_graph_propales_permonth.php
    @@ -33,7 +33,10 @@ class box_graph_propales_permonth extends ModeleBoxes
     	var $boxlabel="BoxProposalsPerMonth";
     	var $depends = array("propal");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $info_box_head = array();
     	var $info_box_contents = array();
    @@ -256,7 +259,6 @@ class box_graph_propales_permonth extends ModeleBoxes
         	        										'maxlength'=>500,
     	            										'text' => $mesg);
     			}
    -
     		}
     		else {
     			$this->info_box_contents[0][0] = array(
    @@ -278,6 +280,5 @@ class box_graph_propales_permonth extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_last_modified_ticket.php b/htdocs/core/boxes/box_last_modified_ticket.php
    index a0613d58f3e..9ce7dd91605 100644
    --- a/htdocs/core/boxes/box_last_modified_ticket.php
    +++ b/htdocs/core/boxes/box_last_modified_ticket.php
    @@ -34,7 +34,12 @@ class box_last_modified_ticket extends ModeleBoxes
         public $boximg = "ticket";
         public $boxlabel;
         public $depends = array("ticket");
    +    
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
    +    
         public $param;
         public $info_box_head = array();
         public $info_box_contents = array();
    diff --git a/htdocs/core/boxes/box_last_ticket.php b/htdocs/core/boxes/box_last_ticket.php
    index 2dfa71af904..a824a707168 100644
    --- a/htdocs/core/boxes/box_last_ticket.php
    +++ b/htdocs/core/boxes/box_last_ticket.php
    @@ -34,7 +34,12 @@ class box_last_ticket extends ModeleBoxes
         public $boximg = "ticket";
         public $boxlabel;
         public $depends = array("ticket");
    +    
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
    +    
         public $param;
         public $info_box_head = array();
         public $info_box_contents = array();
    diff --git a/htdocs/core/boxes/box_lastlogin.php b/htdocs/core/boxes/box_lastlogin.php
    index 05bd3043b0a..c8149c6384b 100644
    --- a/htdocs/core/boxes/box_lastlogin.php
    +++ b/htdocs/core/boxes/box_lastlogin.php
    @@ -35,7 +35,11 @@ class box_lastlogin extends ModeleBoxes
         var $boxlabel='BoxLoginInformation';
         var $depends = array("user");
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
         var $param;
         var $enabled = 1;
     
    @@ -94,7 +98,6 @@ class box_lastlogin extends ModeleBoxes
                 'td' => '',
                 'text' => $tmp,
             );
    -        
         }
     
     
    diff --git a/htdocs/core/boxes/box_members.php b/htdocs/core/boxes/box_members.php
    index e5819f0f14c..6f7e62aa457 100644
    --- a/htdocs/core/boxes/box_members.php
    +++ b/htdocs/core/boxes/box_members.php
    @@ -37,7 +37,11 @@ class box_members extends ModeleBoxes
     	var $boxlabel="BoxLastMembers";
     	var $depends = array("adherent");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     	var $enabled = 1;
     
    @@ -164,7 +168,6 @@ class box_members extends ModeleBoxes
                     'text' => $langs->trans("ReadPermissionNotAllowed")
                 );
             }
    -
         }
     
     	/**
    @@ -179,6 +182,5 @@ class box_members extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php
    index 53449afceeb..cadda2b8058 100644
    --- a/htdocs/core/boxes/box_produits.php
    +++ b/htdocs/core/boxes/box_produits.php
    @@ -38,7 +38,11 @@ class box_produits extends ModeleBoxes
     	var $boxlabel="BoxLastProducts";
     	var $depends = array("produit");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -226,6 +230,5 @@ class box_produits extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php
    index ee49e9e4534..648da118e09 100644
    --- a/htdocs/core/boxes/box_produits_alerte_stock.php
    +++ b/htdocs/core/boxes/box_produits_alerte_stock.php
    @@ -40,7 +40,11 @@ class box_produits_alerte_stock extends ModeleBoxes
     	var $boxlabel="BoxProductsAlertStock";
     	var $depends = array("produit");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $param;
     
     	var $info_box_head = array();
    @@ -238,6 +242,5 @@ class box_produits_alerte_stock extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php
    index 976cbf1766c..a48543a00f6 100644
    --- a/htdocs/core/boxes/box_project.php
    +++ b/htdocs/core/boxes/box_project.php
    @@ -23,7 +23,7 @@
      *  \ingroup    projet
      *  \brief      Module to show Projet activity of the current Year
      */
    -include_once(DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php");
    +include_once DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php";
     
     /**
      * Class to manage the box to show last projet
    @@ -34,7 +34,12 @@ class box_project extends ModeleBoxes
     	var $boximg="object_projectpub";
     	var $boxlabel;
     	//var $depends = array("projet");
    -	var $db;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
     	var $param;
     
     	var $info_box_head = array();
    @@ -49,8 +54,9 @@ class box_project extends ModeleBoxes
         function __construct($db,$param='')
         {
             global $user, $langs;
    -        $langs->load("boxes");
    -        $langs->load("projects");
    +
    +        // Load translation files required by the page
    +        $langs->loadLangs(array('boxes', 'projects'));
     
             $this->db = $db;
             $this->boxlabel="Projects";
    @@ -80,7 +86,7 @@ class box_project extends ModeleBoxes
     		// list the summary of the orders
     		if ($user->rights->projet->lire) {
     
    -		    include_once(DOL_DOCUMENT_ROOT.'/projet/class/project.class.php');
    +		    include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     		    $projectstatic = new Project($this->db);
     
     		    $socid=$user->societe_id;
    @@ -179,7 +185,6 @@ class box_project extends ModeleBoxes
                 'td' => '',
                 'text' => "&nbsp;",
             );
    -
     	}
     
     	/**
    diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php
    index 8dad41f64a1..6db4ac11250 100644
    --- a/htdocs/core/boxes/box_propales.php
    +++ b/htdocs/core/boxes/box_propales.php
    @@ -37,7 +37,11 @@ class box_propales extends ModeleBoxes
         var $boxlabel="BoxLastProposals";
         var $depends = array("propal");	// conf->propal->enabled
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
         var $param;
     
         var $info_box_head = array();
    @@ -188,6 +192,5 @@ class box_propales extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
     }
     
    diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php
    index 3186d0d30ce..629da790f3c 100644
    --- a/htdocs/core/boxes/box_prospect.php
    +++ b/htdocs/core/boxes/box_prospect.php
    @@ -39,7 +39,11 @@ class box_prospect extends ModeleBoxes
     	var $boxlabel="BoxLastProspects";
     	var $depends = array("societe");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $enabled = 1;
     
     	var $info_box_head = array();
    @@ -176,6 +180,5 @@ class box_prospect extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php
    index 44a1ca020b5..7c73bbbe328 100644
    --- a/htdocs/core/boxes/box_services_contracts.php
    +++ b/htdocs/core/boxes/box_services_contracts.php
    @@ -37,7 +37,11 @@ class box_services_contracts extends ModeleBoxes
     	var $boxlabel="BoxLastProductsInContract";
     	var $depends = array("service","contrat");
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
     	var $param;
     
     	var $info_box_head = array();
    @@ -84,8 +88,8 @@ class box_services_contracts extends ModeleBoxes
     		    $thirdpartytmp = new Societe($db);
     		    $productstatic = new Product($db);
     
    -			$sql = "SELECT s.nom as name, s.rowid as socid,";
    -			$sql.= " c.rowid, c.ref, c.statut as contract_status,";
    +			$sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
    +			$sql.= " c.rowid, c.ref, c.statut as contract_status, c.ref_customer, c.ref_supplier,";
     			$sql.= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type,";
     			$sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity";
     			$sql.= " FROM (".MAIN_DB_PREFIX."societe as s";
    @@ -123,9 +127,18 @@ class box_services_contracts extends ModeleBoxes
                         $contractstatic->statut=$objp->contract_status;
     					$contractstatic->id=$objp->rowid;
     					$contractstatic->ref=$objp->ref;
    +					$contractstatic->ref_customer=$objp->ref_customer;
    +					$contractstatic->ref_supplier=$objp->ref_supplier;
     
     					$thirdpartytmp->name = $objp->name;
     					$thirdpartytmp->id = $objp->socid;
    +					$thirdpartytmp->email = $objp->email;
    +					$thirdpartytmp->client = $objp->client;
    +					$thirdpartytmp->fournisseur = $objp->fournisseur;
    +					$thirdpartytmp->code_client = $objp->code_client;
    +					$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
    +					$thirdpartytmp->code_compta = $objp->code_compta;
    +					$thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
     
     					// Multilangs
     					if (! empty($conf->global->MAIN_MULTILANGS) && $objp->product_id > 0) // if option multilang is on
    @@ -218,7 +231,6 @@ class box_services_contracts extends ModeleBoxes
                     'text' => $langs->trans("ReadPermissionNotAllowed")
     			);
     		}
    -
     	}
     
     	/**
    @@ -233,6 +245,5 @@ class box_services_contracts extends ModeleBoxes
         {
     		return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
     	}
    -
     }
     
    diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php
    index 72d4390a2e2..ed62e127816 100644
    --- a/htdocs/core/boxes/box_services_expired.php
    +++ b/htdocs/core/boxes/box_services_expired.php
    @@ -35,7 +35,11 @@ class box_services_expired extends ModeleBoxes
         var $boxlabel="BoxOldestExpiredServices";
         var $depends = array("contrat");	// conf->propal->enabled
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
         var $param;
     
         var $info_box_head = array();
    @@ -80,7 +84,7 @@ class box_services_expired extends ModeleBoxes
         	    // Select contracts with at least one expired service
     			$sql = "SELECT ";
         		$sql.= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.ref_customer, c.ref_supplier,";
    -			$sql.= " s.nom as name, s.rowid as socid,";
    +			$sql.= " s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
     			$sql.= " MIN(cd.date_fin_validite) as date_line, COUNT(cd.rowid) as nb_services";
         		$sql.= " FROM ".MAIN_DB_PREFIX."contrat as c, ".MAIN_DB_PREFIX."societe s, ".MAIN_DB_PREFIX."contratdet as cd";
                 if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    @@ -109,8 +113,15 @@ class box_services_expired extends ModeleBoxes
     
         				$objp = $db->fetch_object($resql);
     
    -    				$thirdpartytmp->id = $objp->socid;
         				$thirdpartytmp->name = $objp->name;
    +    				$thirdpartytmp->id = $objp->socid;
    +    				$thirdpartytmp->email = $objp->email;
    +    				$thirdpartytmp->client = $objp->client;
    +    				$thirdpartytmp->fournisseur = $objp->fournisseur;
    +    				$thirdpartytmp->code_client = $objp->code_client;
    +    				$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
    +    				$thirdpartytmp->code_compta = $objp->code_compta;
    +    				$thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
     
         				$contract->id = $objp->rowid;
         				$contract->ref = $objp->ref;
    @@ -156,8 +167,6 @@ class box_services_expired extends ModeleBoxes
                                                             'maxlength'=>500,
                                                             'text' => ($db->error().' sql='.$sql));
         		}
    -
    -
         	}
         	else
         	{
    @@ -180,6 +189,5 @@ class box_services_expired extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
    - }
    +}
     
    diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php
    index 895f411e3d6..97b4bf8feec 100644
    --- a/htdocs/core/boxes/box_supplier_orders.php
    +++ b/htdocs/core/boxes/box_supplier_orders.php
    @@ -36,7 +36,11 @@ class box_supplier_orders extends ModeleBoxes
         var $boxlabel="BoxLatestSupplierOrders";
         var $depends = array("fournisseur");
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
         var $param;
         var $info_box_head = array();
         var $info_box_contents = array();
    @@ -184,6 +188,5 @@ class box_supplier_orders extends ModeleBoxes
         {
             return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput);
         }
    -
     }
     
    diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php
    index 3a665243073..b85ed0f4d8b 100644
    --- a/htdocs/core/boxes/box_task.php
    +++ b/htdocs/core/boxes/box_task.php
    @@ -22,8 +22,8 @@
      *  \brief      Module to Task activity of the current year
      */
     
    -include_once(DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
    +include_once DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
     
     
     /**
    @@ -31,16 +31,21 @@ require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
      */
     class box_task extends ModeleBoxes
     {
    -    var $boxcode="projet";
    -    var $boximg="object_projecttask";
    -    var $boxlabel;
    -    //var $depends = array("projet");
    -    var $db;
    -    var $param;
    -    var $enabled = 0;		// Disabled because bugged.
    +    public $boxcode="projet";
    +    public $boximg="object_projecttask";
    +    public $boxlabel;
    +    //public $depends = array("projet");
     
    -    var $info_box_head = array();
    -    var $info_box_contents = array();
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    public $param;
    +    public $enabled = 0;		// Disabled because bugged.
    +
    +    public $info_box_head = array();
    +    public $info_box_contents = array();
     
     
         /**
    @@ -52,8 +57,10 @@ class box_task extends ModeleBoxes
         function __construct($db,$param='')
         {
             global $user, $langs;
    -        $langs->load("boxes");
    -        $langs->load("projects");
    +
    +        // Load translation files required by the page
    +        $langs->loadLangs(array('boxes', 'projects'));
    +
             $this->boxlabel="Tasks";
             $this->db = $db;
     
    @@ -75,7 +82,7 @@ class box_task extends ModeleBoxes
     		$totalMnt = 0;
     		$totalnb = 0;
     		$totalDuree=0;
    -		include_once(DOL_DOCUMENT_ROOT."/projet/class/task.class.php");
    +		include_once DOL_DOCUMENT_ROOT."/projet/class/task.class.php";
     		$taskstatic=new Task($db);
     
     
    @@ -126,13 +133,12 @@ class box_task extends ModeleBoxes
     		}
     
     
    -		// Add the sum à the bottom of the boxes
    +		// Add the sum at the bottom of the boxes
     		$this->info_box_contents[$i][] = array('tr' => 'class="liste_total"', 'td' => '', 'text' => $langs->trans("Total")."&nbsp;".$textHead);
     		$this->info_box_contents[$i][] = array('td' => 'align="right" ', 'text' => number_format($totalnb, 0, ',', ' ')."&nbsp;".$langs->trans("Tasks"));
     		$this->info_box_contents[$i][] = array('td' => 'align="right" ', 'text' => ConvertSecondToTime($totalplannedtot,'all',25200,5));
     		$this->info_box_contents[$i][] = array('td' => 'align="right" ', 'text' => ConvertSecondToTime($totaldurationtot,'all',25200,5));
     		$this->info_box_contents[$i][] = array('td' => '', 'text' => "");
    -
     	}
     
     	/**
    diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php
    index 61af58a4b8b..47646a0facf 100644
    --- a/htdocs/core/boxes/modules_boxes.php
    +++ b/htdocs/core/boxes/modules_boxes.php
    @@ -31,7 +31,7 @@
      *
      * Boxes parent class
      */
    -class ModeleBoxes    // Can't be abtract as it is instantiated to build "empty" boxes
    +class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" boxes
     {
     	/**
     	 * @var DoliDB Database handler
    @@ -213,7 +213,6 @@ class ModeleBoxes    // Can't be abtract as it is instantiated to build "empty"
             require_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php';
     
     		$MAXLENGTHBOX=60;   // Mettre 0 pour pas de limite
    -		$var = false;
     
             $cachetime = 900;   // 900 : 15mn
             $cachedir = DOL_DATA_ROOT.'/boxes/temp';
    @@ -503,8 +502,6 @@ class ModeleBoxes    // Can't be abtract as it is instantiated to build "empty"
     		}
     		return $widget;
     	}
    -
    -
     }
     
     
    diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
    index 3db9fc941c8..f64e18abb32 100644
    --- a/htdocs/core/class/CMailFile.class.php
    +++ b/htdocs/core/class/CMailFile.class.php
    @@ -59,7 +59,11 @@ class CMailFile
     
     	var $eol;
     	var $eol2;
    -	var $error='';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	var $smtps;			// Contains SMTPs object (if this method is used)
     	var $phpmailer;		// Contains PHPMailer object (if this method is used)
    @@ -113,7 +117,7 @@ class CMailFile
     	 *  @param  string  $sendcontext      	 'standard', 'emailing', ... (used to define with sending mode and parameters to use)
     	 *  @param	string	$replyto			 Reply-to email (will be set to same value than From by default if not provided)
     	 */
    -	function __construct($subject,$to,$from,$msg,$filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),$addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0,$errors_to='',$css='',$trackid='',$moreinheader='',$sendcontext='standard',$replyto='')
    +	function __construct($subject, $to, $from, $msg, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=0, $errors_to='', $css='', $trackid='', $moreinheader='', $sendcontext='standard', $replyto='')
     	{
     		global $conf, $dolibarr_main_data_root;
     
    @@ -479,7 +483,6 @@ class CMailFile
     			// --------------------------------------
     			$this->error = 'Bad value for sendmode';
     		}
    -
     	}
     
     
    @@ -566,7 +569,8 @@ class CMailFile
     				$keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
     			}
     
    -			if(!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) {
    +			if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO))
    +			{
     				$this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO;
     				$this->addr_cc = '';
     				$this->addr_bcc = '';
    @@ -731,7 +735,11 @@ class CMailFile
     					if (! empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail();
     
     					$result=$this->smtps->getErrors();
    -					if (empty($this->error) && empty($result)) $res=true;
    +					if (empty($this->error) && empty($result))
    +					{
    +						dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
    +						$res=true;
    +					}
     					else
     					{
     						if (empty($this->error)) $this->error=$result;
    @@ -794,6 +802,10 @@ class CMailFile
     					dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR);
     					$res=false;
     				}
    +				else
    +				{
    +					dol_syslog("CMailFile::sendfile: mail end success", LOG_DEBUG);
    +				}
     			}
     			else
     			{
    @@ -836,6 +848,7 @@ class CMailFile
     		return '=?'.$conf->file->character_set_client.'?B?'.base64_encode($stringtoencode).'?=';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Read a file on disk and return encoded content for emails (mode = 'mail')
     	 *
    @@ -844,6 +857,7 @@ class CMailFile
     	 */
     	function _encode_file($sourcefile)
     	{
    +        // phpcs:enable
     		$newsourcefile=dol_osencode($sourcefile);
     
     		if (is_readable($newsourcefile))
    @@ -861,6 +875,7 @@ class CMailFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Write content of a SMTP request into a dump file (mode = all)
     	 *  Used for debugging.
    @@ -870,6 +885,7 @@ class CMailFile
     	 */
     	function dump_mail()
     	{
    +        // phpcs:enable
     		global $conf,$dolibarr_main_data_root;
     
     		if (@is_writeable($dolibarr_main_data_root))	// Avoid fatal error on fopen with open_basedir
    @@ -954,6 +970,7 @@ class CMailFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create SMTP headers (mode = 'mail')
     	 *
    @@ -961,6 +978,7 @@ class CMailFile
     	 */
     	function write_smtpheaders()
     	{
    +        // phpcs:enable
     		global $conf;
     		$out = "";
     
    @@ -1016,6 +1034,7 @@ class CMailFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create header MIME (mode = 'mail')
     	 *
    @@ -1025,10 +1044,11 @@ class CMailFile
     	 */
     	function write_mimeheaders($filename_list, $mimefilename_list)
     	{
    +        // phpcs:enable
     		$mimedone=0;
     		$out = "";
     
    -		if ($filename_list)
    +		if (is_array($filename_list))
     		{
     			$filename_list_size=count($filename_list);
     			for($i=0;$i < $filename_list_size;$i++)
    @@ -1045,6 +1065,7 @@ class CMailFile
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return email content (mode = 'mail')
     	 *
    @@ -1053,6 +1074,7 @@ class CMailFile
     	 */
     	function write_body($msgtext)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$out='';
    @@ -1145,6 +1167,7 @@ class CMailFile
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Attach file to email (mode = 'mail')
     	 *
    @@ -1155,6 +1178,7 @@ class CMailFile
     	 */
     	function write_files($filename_list,$mimetype_list,$mimefilename_list)
     	{
    +        // phpcs:enable
     		$out = '';
     
     		$filename_list_size=count($filename_list);
    @@ -1192,17 +1216,19 @@ class CMailFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Attach an image to email (mode = 'mail')
     	 *
    -	 * @param	array	$images_list	Tableau
    +	 * @param	array	$images_list	Array of array image
     	 * @return	string					Chaine images encodees
     	 */
     	function write_images($images_list)
     	{
    +        // phpcs:enable
     		$out = '';
     
    -		if ($images_list)
    +		if (is_array($images_list))
     		{
     			foreach ($images_list as $img)
     			{
    @@ -1223,6 +1249,7 @@ class CMailFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Try to create a socket connection
     	 *
    @@ -1232,6 +1259,7 @@ class CMailFile
     	 */
     	function check_server_port($host,$port)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$_retVal=0;
    @@ -1286,6 +1314,7 @@ class CMailFile
     		return $_retVal;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * This function has been modified as provided by SirSir to allow multiline responses when
     	 * using SMTP Extensions.
    @@ -1296,6 +1325,7 @@ class CMailFile
     	 */
     	function server_parse($socket, $response)
     	{
    +        // phpcs:enable
     		$_retVal = true;	// Indicates if Object was created or not
     		$server_response = '';
     
    @@ -1328,10 +1358,10 @@ class CMailFile
     		// Build the list of image extensions
     		$extensions = array_keys($this->image_types);
     
    -
    +		$matches = array();
     		preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches);  // If "xxx.ext" or 'xxx.ext' found
     
    -		if ($matches)
    +		if (! empty($matches))
     		{
     			$i=0;
     			foreach ($matches[1] as $full)
    @@ -1520,4 +1550,3 @@ class CMailFile
     		return $ret;
     	}
     }
    -
    diff --git a/htdocs/core/class/CSMSFile.class.php b/htdocs/core/class/CSMSFile.class.php
    index 0a149feabf4..b6c334f7e1c 100644
    --- a/htdocs/core/class/CSMSFile.class.php
    +++ b/htdocs/core/class/CSMSFile.class.php
    @@ -34,15 +34,18 @@
      */
     class CSMSFile
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -	var $addr_from;
    -	var $addr_to;
    -	var $deferred;
    -	var $priority;
    -	var $class;
    -	var $message;
    -	var $nostop;
    +	public $addr_from;
    +	public $addr_to;
    +	public $deferred;
    +	public $priority;
    +	public $class;
    +	public $message;
    +	public $nostop;
     
     
     	/**
    @@ -192,6 +195,7 @@ class CSMSFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Write content of a SendSms request into a dump file (mode = all)
     	 *  Used for debugging.
    @@ -200,6 +204,7 @@ class CSMSFile
     	 */
     	function dump_sms()
     	{
    +        // phpcs:enable
     		global $conf,$dolibarr_main_data_root;
     
     		if (@is_writeable($dolibarr_main_data_root))	// Avoid fatal error on fopen with open_basedir
    @@ -221,6 +226,7 @@ class CSMSFile
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Write content of a SendSms result into a dump file (mode = all)
          *  Used for debugging.
    @@ -230,6 +236,7 @@ class CSMSFile
          */
         function dump_sms_result($result)
         {
    +        // phpcs:enable
             global $conf,$dolibarr_main_data_root;
     
             if (@is_writeable($dolibarr_main_data_root))    // Avoid fatal error on fopen with open_basedir
    @@ -244,6 +251,4 @@ class CSMSFile
                 @chmod($outputfile, octdec($conf->global->MAIN_UMASK));
             }
         }
    -
     }
    -
    diff --git a/htdocs/core/class/antivir.class.php b/htdocs/core/class/antivir.class.php
    index 1c3ea5a07b6..c67e3f5f59d 100644
    --- a/htdocs/core/class/antivir.class.php
    +++ b/htdocs/core/class/antivir.class.php
    @@ -26,15 +26,29 @@
      */
     
     /**
    - *      \class      AntiVir
    - *      \brief      Class to scan for virus
    + *      Class to scan for virus
      */
     class AntiVir
     {
    -	var $error;
    -	var $errors;
    -	var $output;
    -	var $db;
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +	/**
    +	 * @var string Used to return message
    +	 */
    +	public $output;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	/**
     	 *  Constructor
    @@ -46,6 +60,7 @@ class AntiVir
     		$this->db=$db;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Scan a file with antivirus.
     	 *  This function runs the command defined in setup. This antivirus command must return 0 if OK.
    @@ -56,6 +71,7 @@ class AntiVir
     	 */
     	function dol_avscan_file($file)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$return = 0;
    @@ -168,6 +184,4 @@ class AntiVir
     
     		return $ret;
     	}
    -
     }
    -
    diff --git a/htdocs/core/class/canvas.class.php b/htdocs/core/class/canvas.class.php
    index 6851c124743..cf830048cc0 100644
    --- a/htdocs/core/class/canvas.class.php
    +++ b/htdocs/core/class/canvas.class.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010-2011	Regis Houssin		<regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2011 		Laurent Destailleur	<eldy@users.sourceforge.net>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -28,19 +28,30 @@
      */
     class Canvas
     {
    -	var $db;
    -	var $error;
    -	var $errors=array();
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $actiontype;
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -    var $dirmodule;			// Module directory
    -    var $targetmodule;      // Module concerned by canvas (ex: thirdparty, contact, ...)
    -    var $canvas;            // Name of canvas (ex: company, individual, product, service, ...)
    -    var $card;              // Tab (sub-canvas)
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
    -    var $template_dir;			// Initialized by getCanvas with templates directory
    -    var $control;           	// Initialized by getCanvas with controller instance
    +	public $actiontype;
    +
    +    public $dirmodule;			// Module directory
    +    public $targetmodule;      // Module concerned by canvas (ex: thirdparty, contact, ...)
    +    public $canvas;            // Name of canvas (ex: company, individual, product, service, ...)
    +    public $card;              // Tab (sub-canvas)
    +
    +    public $template_dir;		// Initialized by getCanvas with templates directory
    +    public $control;           	// Initialized by getCanvas with controller instance
     
     
        /**
    @@ -122,6 +133,7 @@ class Canvas
             //print ' => template_dir='.$this->template_dir.'<br>';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 * 	Shared method for canvas to assign values for templates
     	 *
    @@ -132,6 +144,7 @@ class Canvas
     	 */
     	function assign_values(&$action='view', $id=0, $ref='')
     	{
    +        // phpcs:enable
     		if (method_exists($this->control,'assign_values')) $this->control->assign_values($action, $id, $ref);
     	}
     
    @@ -145,10 +158,11 @@ class Canvas
         {
             if (empty($this->template_dir)) return 0;
     
    -        if (file_exists($this->template_dir.($this->card?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php')) return 1;
    +        if (file_exists($this->template_dir.(!empty($this->card)?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php')) return 1;
             else return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Display a canvas page. This will include the template for output.
     	 *	Variables used by templates may have been defined or loaded before into the assign_values function.
    @@ -158,10 +172,11 @@ class Canvas
     	 */
     	function display_canvas($action)
     	{
    +        // phpcs:enable
     		global $db, $conf, $langs, $user, $canvas;
     		global $form, $formfile;
     
    -		include $this->template_dir.($this->card?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php';        // Include native PHP template
    +		include $this->template_dir.(!empty($this->card)?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php';        // Include native PHP template
     	}
     
     
    @@ -197,5 +212,4 @@ class Canvas
     			return $ret;
     		}
     	}
    -
     }
    diff --git a/htdocs/core/class/ccountry.class.php b/htdocs/core/class/ccountry.class.php
    index 7964510c91c..f07916a7511 100644
    --- a/htdocs/core/class/ccountry.class.php
    +++ b/htdocs/core/class/ccountry.class.php
    @@ -32,17 +32,38 @@
      */
     class Ccountry // extends CommonObject
     {
    -	var $db;							//!< To store db handler
    -	var $error;							//!< To return error code (or message)
    -	var $errors=array();				//!< To return several error codes (or messages)
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
     	//var $element='ccountry';			//!< Id that identify managed objects
     	//var $table_element='ccountry';	//!< Name of table without prefix where object is stored
     
    -    var $id;
    -	var $code;
    -	var $code_iso;
    -	var $label;
    -	var $active;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	public $code;
    +	public $code_iso;
    +
    +	/**
    +     * @var string Countries label
    +     */
    +    public $label;
    +
    +	public $active;
     
     
     
    @@ -55,7 +76,6 @@ class Ccountry // extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -312,5 +332,4 @@ class Ccountry // extends CommonObject
     			return 1;
     		}
     	}
    -
     }
    diff --git a/htdocs/core/class/comment.class.php b/htdocs/core/class/comment.class.php
    index 9aeebd575bf..b731eb77169 100644
    --- a/htdocs/core/class/comment.class.php
    +++ b/htdocs/core/class/comment.class.php
    @@ -1,23 +1,60 @@
     <?php
    +/*
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
     /**
      * 	Class to manage comment
      */
     class Comment extends CommonObject
     {
    -	public $element='comment';		//!< Id that identify managed objects
    -	public $table_element='comment';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='comment';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='comment';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element ='';
     
    -	public $fk_element;
     	public $element_type;
     
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
     
     	public $tms;
     
     	public $datec;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
     
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
     
     	public $import_key;
    @@ -323,9 +360,8 @@ class Comment extends CommonObject
     				$error++; $this->errors[]="Error ".$this->db->lasterror();
     				return -1;
     			}
    -
     		}
     
     		return count($this->comments);
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
    index 18e2817f040..92458831d0b 100644
    --- a/htdocs/core/class/commondocgenerator.class.php
    +++ b/htdocs/core/class/commondocgenerator.class.php
    @@ -1,10 +1,11 @@
     <?php
    -/* Copyright (C) 2003-2005	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2010	Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2004		Eric Seigne		<eric.seigne@ryxeo.com>
    - * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2015       	Marcos García           <marcosgdf@gmail.com>
    - * Copyright (C) 2016       	Charlie Benke           <charlie@patas-monkey.com>
    +/* Copyright (C) 2003-2005	Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2010	Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2004		Eric Seigne             <eric.seigne@ryxeo.com>
    + * Copyright (C) 2005-2012	Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2016       Charlie Benke           <charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -33,7 +34,19 @@
      */
     abstract class CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    /**
    +     * @var string[]    Array of error strings
    +     */
    +    public $errors = array();
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
     	protected $db;
     
     
    @@ -42,11 +55,13 @@ abstract class CommonDocGenerator
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	*/
    -	public function __construct($db) {
    -		$this->db = $db;
    -	}
    +    public function __construct($db)
    +    {
    +        $this->db = $db;
    +    }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Define array with couple subtitution key => subtitution value
          *
    @@ -56,6 +71,7 @@ abstract class CommonDocGenerator
          */
         function get_substitutionarray_user($user,$outputlangs)
         {
    +        // phpcs:enable
             global $conf;
     
             $logotouse=$conf->user->dir_output.'/'.get_exdir($user->id, 2, 0, 1, $user, 'user').'/'.$user->photo;
    @@ -83,6 +99,7 @@ abstract class CommonDocGenerator
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Define array with couple subtitution key => subtitution value
          *
    @@ -92,6 +109,7 @@ abstract class CommonDocGenerator
          */
         function get_substitutionarray_mysoc($mysoc,$outputlangs)
         {
    +        // phpcs:enable
             global $conf;
     
             if (empty($mysoc->forme_juridique) && ! empty($mysoc->forme_juridique_code))
    @@ -141,6 +159,7 @@ abstract class CommonDocGenerator
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Define array with couple subtitution key => subtitution value
          *
    @@ -150,6 +169,7 @@ abstract class CommonDocGenerator
          */
         function get_substitutionarray_thirdparty($object,$outputlangs)
         {
    +        // phpcs:enable
             global $conf;
     
             if (empty($object->country) && ! empty($object->country_code))
    @@ -220,6 +240,7 @@ abstract class CommonDocGenerator
     		return $array_thirdparty;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Define array with couple subtitution key => subtitution value
     	 *
    @@ -228,7 +249,9 @@ abstract class CommonDocGenerator
     	 * @param   array		$array_key	    Name of the key for return array
     	 * @return	array 						Array of substitution key->code
     	 */
    -	function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object') {
    +    function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object')
    +    {
    +        // phpcs:enable
     		global $conf;
     
     		if(empty($object->country) && ! empty($object->country_code))
    @@ -291,6 +314,7 @@ abstract class CommonDocGenerator
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Define array with couple subtitution key => subtitution value
          *
    @@ -299,6 +323,7 @@ abstract class CommonDocGenerator
          */
         function get_substitutionarray_other($outputlangs)
         {
    +        // phpcs:enable
         	global $conf;
     
         	$now=dol_now('gmt');	// gmt
    @@ -327,6 +352,7 @@ abstract class CommonDocGenerator
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Define array with couple substitution key => substitution value
     	 *
    @@ -337,6 +363,7 @@ abstract class CommonDocGenerator
     	 */
     	function get_substitutionarray_object($object,$outputlangs,$array_key='object')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sumpayed=$sumdeposit=$sumcreditnote='';
    @@ -473,20 +500,23 @@ abstract class CommonDocGenerator
     		return $resarray;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    -	 *	@param  array			$line				Array of lines
    +	 *	@param  Object			$line				Object line
     	 *	@param  Translate		$outputlangs        Lang object to use for output
     	 *  @return	array								Return a substitution array
     	 */
    -	function get_substitutionarray_lines($line,$outputlangs)
    +	function get_substitutionarray_lines($line, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$resarray= array(
     			'line_fulldesc'=>doc_getlinedesc($line,$outputlangs),
     			'line_product_ref'=>$line->product_ref,
    +			'line_product_ref_fourn'=>$line->ref_fourn, // for supplier doc lines
     			'line_product_label'=>$line->product_label,
     			'line_product_type'=>$line->product_type,
     			'line_desc'=>$line->desc,
    @@ -543,12 +573,13 @@ abstract class CommonDocGenerator
     			$tmpproduct = new Product($this->db);
     			$result = $tmpproduct->fetch($line->fk_product);
     			foreach($tmpproduct->array_options as $key=>$label)
    -				$resarray["line_".$key] = $label;
    +				$resarray["line_product_".$key] = $label;
     		}
     
     		return $resarray;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Define array with couple substitution key => substitution value
          *
    @@ -559,6 +590,7 @@ abstract class CommonDocGenerator
          */
         function get_substitutionarray_shipment($object,$outputlangs,$array_key='object')
         {
    +        // phpcs:enable
         	global $conf;
     		dol_include_once('/core/lib/product.lib.php');
     		$object->list_delivery_methods($object->shipping_method_id);
    @@ -610,8 +642,9 @@ abstract class CommonDocGenerator
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *	Define array with couple substitution key => substitution value
    +     *  Define array with couple substitution key => substitution value
          *
          *	@param  ExpeditionLigne	$line				Object line
          *	@param  Translate		$outputlangs        Lang object to use for output
    @@ -619,8 +652,9 @@ abstract class CommonDocGenerator
          */
         function get_substitutionarray_shipment_lines($line, $outputlangs)
         {
    -    	global $conf;
    -		dol_include_once('/core/lib/product.lib.php');
    +        // phpcs:enable
    +        global $conf;
    +        dol_include_once('/core/lib/product.lib.php');
     
             $resarray = array(
     	    	'line_fulldesc'=>doc_getlinedesc($line,$outputlangs),
    @@ -642,7 +676,7 @@ abstract class CommonDocGenerator
     	    	'line_volume'=>empty($line->volume) ? '' : $line->volume*$line->qty_shipped.' '.measuring_units_string($line->volume_units, 'volume'),
         	);
     
    -		// Retrieve extrafields
    +        // Retrieve extrafields
             $extrafieldkey = $line->element;
             $array_key = "line";
             require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
    @@ -656,6 +690,7 @@ abstract class CommonDocGenerator
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Define array with couple subtitution key => subtitution value
          *
    @@ -664,15 +699,17 @@ abstract class CommonDocGenerator
          * @param   boolean		$recursive    	Want to fetch child array or child object
          * @return	array						Array of substitution key->code
          */
    -    function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true) {
    +    function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true)
    +    {
    +        // phpcs:enable
             $array_other = array();
    -        if(!empty($object)) {
    +        if (!empty($object)) {
                 foreach($object as $key => $value) {
    -                if(!empty($value)) {
    -                    if(!is_array($value) && !is_object($value)) {
    +                if (!empty($value)) {
    +                    if (!is_array($value) && !is_object($value)) {
                             $array_other['object_'.$key] = $value;
                         }
    -                    if(is_array($value) && $recursive){
    +                    if (is_array($value) && $recursive) {
                             $array_other['object_'.$key] = $this->get_substitutionarray_each_var_object($value,$outputlangs,false);
                         }
                     }
    @@ -682,6 +719,7 @@ abstract class CommonDocGenerator
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Fill array with couple extrafield key => extrafield value
          *
    @@ -692,8 +730,9 @@ abstract class CommonDocGenerator
          *  @param  Translate		$outputlangs        Lang object to use for output
          *	@return	array								Substitution array
          */
    -	function fill_substitutionarray_with_extrafields($object,$array_to_fill,$extrafields,$array_key,$outputlangs)
    +    function fill_substitutionarray_with_extrafields($object,$array_to_fill,$extrafields,$array_key,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		foreach($extrafields->attribute_label as $key=>$label)
     		{
    @@ -735,11 +774,34 @@ abstract class CommonDocGenerator
     				$array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
     				$array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
     			}
    +			else if($extrafields->attribute_type[$key] == 'link')
    +			{
    +				$id = $object->array_options['options_'.$key];
    +				if ($id != "")
    +				{
    +					$param = $extrafields->attribute_param[$key];
    +					$param_list=array_keys($param['options']);              // $param_list='ObjectName:classPath'
    +					$InfoFieldList = explode(":", $param_list[0]);
    +					$classname=$InfoFieldList[0];
    +					$classpath=$InfoFieldList[1];
    +					if (! empty($classpath))
    +					{
    +						dol_include_once($InfoFieldList[1]);
    +						if ($classname && class_exists($classname))
    +						{
    +							$tmpobject = new $classname($this->db);
    +							$tmpobject->fetch($id);
    +							// completely replace the id with the linked object name
    +							$object->array_options['options_'.$key] = $tmpobject->name;
    +						}
    +					}
    +				}
    +			}
    +
     			$array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key => $object->array_options['options_'.$key]));
     		}
     
     		return $array_to_fill;
    -
     	}
     
     
    @@ -757,10 +819,232 @@ abstract class CommonDocGenerator
     	 */
         function printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
         {
    -	    if (empty($hidetop) || $hidetop==-1) $pdf->line($x, $y, $x+$l, $y);
    -	    $pdf->line($x+$l, $y, $x+$l, $y+$h);
    -	    if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h);
    -	    $pdf->line($x, $y+$h, $x, $y);
    +        if (empty($hidetop) || $hidetop==-1) $pdf->line($x, $y, $x+$l, $y);
    +        $pdf->line($x+$l, $y, $x+$l, $y+$h);
    +        if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h);
    +        $pdf->line($x, $y+$h, $x, $y);
    +    }
    +
    +
    +    /**
    +     *   	uasort callback function to Sort colums fields
    +     *
    +     *   	@param	array			$a    			PDF lines array fields configs
    +     *   	@param	array			$b    			PDF lines array fields configs
    +     *      @return	int								Return compare result
    +     */
    +    function columnSort($a, $b)
    +    {
    +        if(empty($a['rank'])){ $a['rank'] = 0; }
    +        if(empty($b['rank'])){ $b['rank'] = 0; }
    +        if ($a['rank'] == $b['rank']) {
    +            return 0;
    +        }
    +        return ($a['rank'] > $b['rank']) ? -1 : 1;
    +    }
    +
    +    /**
    +     *   	Prepare Array Column Field
    +     *
    +     *   	@param	object			$object				common object
    +     *   	@param	Translate		$outputlangs		langs
    +     *      @param	int				$hidedetails		Do not show line details
    +     *      @param	int				$hidedesc			Do not show desc
    +     *      @param	int				$hideref			Do not show ref
    +     *      @return	null
    +     */
    +    function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
    +        global $conf;
    +
    +        $this->defineColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    +
    +
    +        // Sorting
    +        uasort ( $this->cols, array( $this, 'columnSort' ) );
    +
    +        // Positionning
    +        $curX = $this->page_largeur-$this->marge_droite; // start from right
    +
    +        // Array witdh
    +        $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche;
    +
    +        // Count flexible column
    +        $totalDefinedColWidth = 0;
    +        $countFlexCol = 0;
    +        foreach ($this->cols as $colKey =>& $colDef)
    +        {
    +            if(!$this->getColumnStatus($colKey)) continue; // continue if desable
    +
    +            if(!empty($colDef['scale'])){
    +                // In case of column widht is defined by percentage
    +                $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100 );
    +            }
    +
    +            if(empty($colDef['width'])){
    +                $countFlexCol++;
    +            }
    +            else{
    +                $totalDefinedColWidth += $colDef['width'];
    +            }
    +        }
    +
    +        foreach ($this->cols as $colKey =>& $colDef)
    +        {
    +            // setting empty conf with default
    +            if(!empty($colDef['title'])){
    +                $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']);
    +            }
    +            else{
    +                $colDef['title'] = $this->defaultTitlesFieldsStyle;
    +            }
    +
    +            // setting empty conf with default
    +            if(!empty($colDef['content'])){
    +                $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']);
    +            }
    +            else{
    +                $colDef['content'] = $this->defaultContentsFieldsStyle;
    +            }
    +
    +            if($this->getColumnStatus($colKey))
    +            {
    +                // In case of flexible column
    +                if(empty($colDef['width'])){
    +                    $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol;
    +                }
    +
    +                // Set positions
    +                $lastX = $curX;
    +                $curX = $lastX - $colDef['width'];
    +                $colDef['xStartPos'] = $curX;
    +                $colDef['xEndPos']   = $lastX;
    +            }
    +        }
    +    }
    +
    +    /**
    +     *   	get column content width from column key
    +     *
    +     *   	@param	string			$colKey    		the column key
    +     *      @return	float      width in mm
    +     */
    +    function getColumnContentWidth($colKey)
    +    {
    +        $colDef = $this->cols[$colKey];
    +        return  $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1];
    +    }
    +
    +
    +    /**
    +     *   	get column content X (abscissa) left position from column key
    +     *
    +     *   	@param	string    $colKey    		the column key
    +     *      @return	float      X position in mm
    +     */
    +    function getColumnContentXStart($colKey)
    +    {
    +        $colDef = $this->cols[$colKey];
    +        return  $colDef['xStartPos'] + $colDef['content']['padding'][3];
    +    }
    +
    +    /**
    +     *   	get column position rank from column key
    +     *
    +     *   	@param	string		$colKey    		the column key
    +     *      @return	int         rank on success and -1 on error
    +     */
    +    function getColumnRank($colKey)
    +    {
    +        if(!isset($this->cols[$colKey]['rank'])) return -1;
    +        return  $this->cols[$colKey]['rank'];
    +    }
    +
    +    /**
    +     *   	get column position rank from column key
    +     *
    +     *   	@param	string		$newColKey    	the new column key
    +     *   	@param	array		$defArray    	a single column definition array
    +     *   	@param	string		$targetCol    	target column used to place the new column beside
    +     *   	@param	bool		$insertAfterTarget    	insert before or after target column ?
    +     *      @return	int         new rank on success and -1 on error
    +     */
    +    function insertNewColumnDef($newColKey, $defArray, $targetCol = false, $insertAfterTarget = false)
    +    {
    +        // prepare wanted rank
    +        $rank = -1;
    +
    +        // try to get rank from target column
    +        if(!empty($targetCol)){
    +            $rank = $this->getColumnRank($targetCol);
    +            if($rank>=0 && $insertAfterTarget){ $rank++; }
    +        }
    +
    +        // get rank from new column definition
    +        if($rank<0 && !empty($defArray['rank'])){
    +            $rank = $defArray['rank'];
    +        }
    +
    +        // error: no rank
    +        if($rank<0){ return -1; }
    +
    +        foreach ($this->cols as $colKey =>& $colDef)
    +        {
    +            if( $rank <= $colDef['rank'])
    +            {
    +                $colDef['rank'] = $colDef['rank'] + 1;
    +            }
    +        }
    +
    +        $defArray['rank'] = $rank;
    +        $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys
    +
    +        return $rank;
    +    }
    +
    +
    +    /**
    +     *   	print standard column content
    +     *
    +     *   	@param	PDF		    $pdf    	pdf object
    +     *   	@param	float		$curY    	curent Y position
    +     *   	@param	string		$colKey    	the column key
    +     *   	@param	string		$columnText   column text
    +     *      @return	int         new rank on success and -1 on error
    +     */
    +    function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '')
    +    {
    +        global $hookmanager;
    +
    +        $parameters=array(
    +            'object' => $object,
    +            'curY' => &$curY,
    +            'columnText' => $columnText,
    +            'colKey' => $colKey
    +        );
    +        $reshook=$hookmanager->executeHooks('printStdColumnContent',$parameters,$this);    // Note that $action and $object may have been modified by hook
    +        if ($reshook < 0) setEventMessages($hookmanager->error,$hookmanager->errors,'errors');
    +        if (!$reshook)
    +        {
    +            if(empty($columnText)) return;
    +            $pdf->SetXY($this->getColumnContentXStart($colKey),$curY); // Set curent position
    +            $colDef = $this->cols[$colKey];
    +            $pdf->MultiCell( $this->getColumnContentWidth($colKey),2, $columnText,'',$colDef['content']['align']);
    +        }
    +    }
    +
    +
    +    /**
    +     *   	get column status from column key
    +     *
    +     *   	@param	string			$colKey    		the column key
    +     *      @return	float      width in mm
    +     */
    +    function getColumnStatus($colKey)
    +    {
    +        if( !empty($this->cols[$colKey]['status'])){
    +            return true;
    +        }
    +        else  return  false;
         }
     }
    -
    diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
    index 9bab103d2e4..b5b363db923 100644
    --- a/htdocs/core/class/commoninvoice.class.php
    +++ b/htdocs/core/class/commoninvoice.class.php
    @@ -62,7 +62,7 @@ abstract class CommonInvoice extends CommonObject
         const TYPE_SITUATION = 5;
     
     	/**
    -	 * Draft
    +	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
     
    @@ -325,6 +325,7 @@ abstract class CommonInvoice extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return if an invoice can be deleted
     	 *	Rule is:
    @@ -339,6 +340,7 @@ abstract class CommonInvoice extends CommonObject
     	 */
     	function is_erasable()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		// We check if invoice is a temporary number (PROVxxxx)
    @@ -429,11 +431,11 @@ abstract class CommonInvoice extends CommonObject
     	{
     		global $langs;
             if ($this->type == CommonInvoice::TYPE_STANDARD) return $langs->trans("InvoiceStandard");
    -        if ($this->type == CommonInvoice::TYPE_REPLACEMENT) return $langs->trans("InvoiceReplacement");
    -        if ($this->type == CommonInvoice::TYPE_CREDIT_NOTE) return $langs->trans("InvoiceAvoir");
    -        if ($this->type == CommonInvoice::TYPE_DEPOSIT) return $langs->trans("InvoiceDeposit");
    -        if ($this->type == CommonInvoice::TYPE_PROFORMA) return $langs->trans("InvoiceProForma");           // Not used.
    -        if ($this->type == CommonInvoice::TYPE_SITUATION) return $langs->trans("InvoiceSituation");
    +        elseif ($this->type == CommonInvoice::TYPE_REPLACEMENT) return $langs->trans("InvoiceReplacement");
    +        elseif ($this->type == CommonInvoice::TYPE_CREDIT_NOTE) return $langs->trans("InvoiceAvoir");
    +        elseif ($this->type == CommonInvoice::TYPE_DEPOSIT) return $langs->trans("InvoiceDeposit");
    +        elseif ($this->type == CommonInvoice::TYPE_PROFORMA) return $langs->trans("InvoiceProForma");           // Not used.
    +        elseif ($this->type == CommonInvoice::TYPE_SITUATION) return $langs->trans("InvoiceSituation");
     		return $langs->trans("Unknown");
     	}
     
    @@ -449,6 +451,7 @@ abstract class CommonInvoice extends CommonObject
     		return $this->LibStatut($this->paye, $this->statut, $mode, $alreadypaid, $this->type);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return label of a status
     	 *
    @@ -461,6 +464,7 @@ abstract class CommonInvoice extends CommonObject
     	 */
     	function LibStatut($paye, $status, $mode=0, $alreadypaid=-1, $type=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('bills');
     
    @@ -471,10 +475,10 @@ abstract class CommonInvoice extends CommonObject
     			if (! $paye)
     			{
     				if ($status == 0) return $langs->trans('Bill'.$prefix.'StatusDraft');
    -				if (($status == 3 || $status == 2) && $alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusClosedUnpaid');
    -				if (($status == 3 || $status == 2) && $alreadypaid > 0) return $langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    -				if ($alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusNotPaid');
    -				return $langs->trans('Bill'.$prefix.'StatusStarted');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusClosedUnpaid');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid > 0) return $langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    +				elseif ($alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusNotPaid');
    +				else return $langs->trans('Bill'.$prefix.'StatusStarted');
     			}
     			else
     			{
    @@ -483,16 +487,16 @@ abstract class CommonInvoice extends CommonObject
     				else return $langs->trans('Bill'.$prefix.'StatusPaid');
     			}
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			$prefix='Short';
     			if (! $paye)
     			{
     				if ($status == 0) return $langs->trans('Bill'.$prefix.'StatusDraft');
    -				if (($status == 3 || $status == 2) && $alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusCanceled');
    -				if (($status == 3 || $status == 2) && $alreadypaid > 0) return $langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    -				if ($alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusNotPaid');
    -				return $langs->trans('Bill'.$prefix.'StatusStarted');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusCanceled');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid > 0) return $langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    +				elseif ($alreadypaid <= 0) return $langs->trans('Bill'.$prefix.'StatusNotPaid');
    +				else return $langs->trans('Bill'.$prefix.'StatusStarted');
     			}
     			else
     			{
    @@ -501,16 +505,16 @@ abstract class CommonInvoice extends CommonObject
     				else return $langs->trans('Bill'.$prefix.'StatusPaid');
     			}
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			$prefix='Short';
     			if (! $paye)
     			{
     				if ($status == 0) return img_picto($langs->trans('BillStatusDraft'),'statut0').' '.$langs->trans('Bill'.$prefix.'StatusDraft');
    -				if (($status == 3 || $status == 2) && $alreadypaid <= 0) return img_picto($langs->trans('StatusCanceled'),'statut5').' '.$langs->trans('Bill'.$prefix.'StatusCanceled');
    -				if (($status == 3 || $status == 2) && $alreadypaid > 0) return img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9').' '.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    -				if ($alreadypaid <= 0) return img_picto($langs->trans('BillStatusNotPaid'),'statut1').' '.$langs->trans('Bill'.$prefix.'StatusNotPaid');
    -				return img_picto($langs->trans('BillStatusStarted'),'statut3').' '.$langs->trans('Bill'.$prefix.'StatusStarted');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) return img_picto($langs->trans('StatusCanceled'),'statut5').' '.$langs->trans('Bill'.$prefix.'StatusCanceled');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid > 0) return img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9').' '.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    +				elseif ($alreadypaid <= 0) return img_picto($langs->trans('BillStatusNotPaid'),'statut1').' '.$langs->trans('Bill'.$prefix.'StatusNotPaid');
    +				else return img_picto($langs->trans('BillStatusStarted'),'statut3').' '.$langs->trans('Bill'.$prefix.'StatusStarted');
     			}
     			else
     			{
    @@ -519,16 +523,16 @@ abstract class CommonInvoice extends CommonObject
     				else return img_picto($langs->trans('BillStatusPaid'),'statut6').' '.$langs->trans('Bill'.$prefix.'StatusPaid');
     			}
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			$prefix='Short';
     			if (! $paye)
     			{
     				if ($status == 0) return img_picto($langs->trans('BillStatusDraft'),'statut0');
    -				if (($status == 3 || $status == 2) && $alreadypaid <= 0) return img_picto($langs->trans('BillStatusCanceled'),'statut5');
    -				if (($status == 3 || $status == 2) && $alreadypaid > 0) return img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9');
    -				if ($alreadypaid <= 0) return img_picto($langs->trans('BillStatusNotPaid'),'statut1');
    -				return img_picto($langs->trans('BillStatusStarted'),'statut3');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) return img_picto($langs->trans('BillStatusCanceled'),'statut5');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid > 0) return img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9');
    +				elseif ($alreadypaid <= 0) return img_picto($langs->trans('BillStatusNotPaid'),'statut1');
    +				else return img_picto($langs->trans('BillStatusStarted'),'statut3');
     			}
     			else
     			{
    @@ -537,16 +541,16 @@ abstract class CommonInvoice extends CommonObject
     				else return img_picto($langs->trans('BillStatusPaid'),'statut6');
     			}
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			$prefix='';
     			if (! $paye)
     			{
     				if ($status == 0) return img_picto($langs->trans('BillStatusDraft'),'statut0').' '.$langs->trans('BillStatusDraft');
    -				if (($status == 3 || $status == 2) && $alreadypaid <= 0) return img_picto($langs->trans('BillStatusCanceled'),'statut5').' '.$langs->trans('Bill'.$prefix.'StatusCanceled');
    -				if (($status == 3 || $status == 2) && $alreadypaid > 0) return img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9').' '.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    -				if ($alreadypaid <= 0) return img_picto($langs->trans('BillStatusNotPaid'),'statut1').' '.$langs->trans('BillStatusNotPaid');
    -				return img_picto($langs->trans('BillStatusStarted'),'statut3').' '.$langs->trans('BillStatusStarted');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) return img_picto($langs->trans('BillStatusCanceled'),'statut5').' '.$langs->trans('Bill'.$prefix.'StatusCanceled');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid > 0) return img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9').' '.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially');
    +				elseif ($alreadypaid <= 0) return img_picto($langs->trans('BillStatusNotPaid'),'statut1').' '.$langs->trans('BillStatusNotPaid');
    +				else return img_picto($langs->trans('BillStatusStarted'),'statut3').' '.$langs->trans('BillStatusStarted');
     			}
     			else
     			{
    @@ -555,21 +559,21 @@ abstract class CommonInvoice extends CommonObject
     				else return img_picto($langs->trans('BillStatusPaid'),'statut6').' '.$langs->trans('BillStatusPaid');
     			}
     		}
    -		if ($mode == 5 || $mode == 6)
    +		elseif ($mode == 5 || $mode == 6)
     		{
     			$prefix='';
     			if ($mode == 5) $prefix='Short';
     			if (! $paye)
     			{
     				if ($status == 0) return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusDraft').' </span>'.img_picto($langs->trans('BillStatusDraft'),'statut0');
    -				if (($status == 3 || $status == 2) && $alreadypaid <= 0) return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusCanceled').' </span>'.img_picto($langs->trans('BillStatusCanceled'),'statut5');
    -				if (($status == 3 || $status == 2) && $alreadypaid > 0) return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially').' </span>'.img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9');
    -				if ($alreadypaid <= 0)
    +				elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusCanceled').' </span>'.img_picto($langs->trans('BillStatusCanceled'),'statut5');
    +				elseif (($status == 3 || $status == 2) && $alreadypaid > 0) return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusClosedPaidPartially').' </span>'.img_picto($langs->trans('BillStatusClosedPaidPartially'),'statut9');
    +				elseif ($alreadypaid <= 0)
     				{
     				    if ($type == self::TYPE_CREDIT_NOTE) return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusNotRefunded').' </span>'.img_picto($langs->trans('StatusNotRefunded'),'statut1');
     				    return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusNotPaid').' </span>'.img_picto($langs->trans('BillStatusNotPaid'),'statut1');
     				}
    -				return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusStarted').' </span>'.img_picto($langs->trans('BillStatusStarted'),'statut3');
    +				else return '<span class="xhideonsmartphone">'.$langs->trans('Bill'.$prefix.'StatusStarted').' </span>'.img_picto($langs->trans('BillStatusStarted'),'statut3');
     			}
     			else
     			{
    @@ -580,21 +584,25 @@ abstract class CommonInvoice extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoi une date limite de reglement de facture en fonction des
    -	 *	conditions de reglements de la facture et date de facturation
    +	 *	conditions de reglements de la facture et date de facturation.
     	 *
     	 *	@param      integer	$cond_reglement   	Condition of payment (code or id) to use. If 0, we use current condition.
    -	 *	@return     date     			       	Date limite de reglement si ok, <0 si ko
    +	 *  @return     date     			       	Date limite de reglement si ok, <0 si ko
     	 */
     	function calculate_date_lim_reglement($cond_reglement=0)
     	{
    +        // phpcs:enable
     		if (! $cond_reglement) $cond_reglement=$this->cond_reglement_code;
     		if (! $cond_reglement) $cond_reglement=$this->cond_reglement_id;
     
    -		$cdr_nbjour=0; $cdr_type=0; $cdr_decalage=0;
    +		$cdr_nbjour=0;
    +        $cdr_type=0;
    +        $cdr_decalage=0;
     
    -		$sqltemp = 'SELECT c.type_cdr,c.nbjour,c.decalage';
    +		$sqltemp = 'SELECT c.type_cdr, c.nbjour, c.decalage';
     		$sqltemp.= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c';
     		if (is_numeric($cond_reglement)) $sqltemp.= " WHERE c.rowid=".$cond_reglement;
     		else {
    @@ -623,12 +631,18 @@ abstract class CommonInvoice extends CommonObject
     
     		/* Definition de la date limite */
     
    -		// 1 : ajout du nombre de jours
    -		$datelim = $this->date + ($cdr_nbjour * 3600 * 24);
    -
    -		// 2 : application de la regle "fin de mois"
    -		if ($cdr_type == 1)
    +		// 0 : ajout du nombre de jours
    +		if ($cdr_type == 0)
     		{
    +			$datelim = $this->date + ($cdr_nbjour * 3600 * 24);
    +
    +			$datelim += ($cdr_decalage * 3600 * 24);
    +		}
    +		// 1 : application de la regle "fin de mois"
    +		elseif ($cdr_type == 1)
    +		{
    +			$datelim = $this->date + ($cdr_nbjour * 3600 * 24);
    +
     			$mois=date('m', $datelim);
     			$annee=date('Y', $datelim);
     			if ($mois == 12)
    @@ -643,23 +657,24 @@ abstract class CommonInvoice extends CommonObject
     			// On se deplace au debut du mois suivant, et on retire un jour
     			$datelim=dol_mktime(12,0,0,$mois,1,$annee);
     			$datelim -= (3600 * 24);
    -		}
    -		elseif($cdr_type == 2 && !empty($cdr_nbjour)) // Application de la règle, le N du mois courant ou suivant
    -		{
     
    -			$date_piece = dol_mktime(0,0,0,date('m', $this->date),date('d', $this->date),date('Y', $this->date)); // Sans les heures minutes et secondes
    -			$date_lim_current = dol_mktime(0,0,0,date('m', $this->date),$cdr_nbjour,date('Y', $this->date)); // Sans les heures minutes et secondes
    -			$date_lim_next = strtotime(date('Y-m-d', $date_lim_current).' +1month');
    +			$datelim += ($cdr_decalage * 3600 * 24);
    +		}
    +		// 2 : application de la règle, le N du mois courant ou suivant
    +		elseif ($cdr_type == 2 && !empty($cdr_decalage))
    +		{
    +			$datelim = $this->date + ($cdr_nbjour * 3600 * 24);
    +
    +			$date_piece = dol_mktime(0, 0, 0, date('m', $datelim),date('d', $datelim),date('Y', $datelim)); // Sans les heures minutes et secondes
    +			$date_lim_current = dol_mktime(0, 0, 0, date('m', $datelim), $cdr_decalage, date('Y', $datelim)); // Sans les heures minutes et secondes
    +			$date_lim_next = dol_time_plus_duree($date_lim_current, 1, 'm');	// Add 1 month
     
     			$diff = $date_piece - $date_lim_current;
     
    -			if($diff < 0) $datelim = $date_lim_current;
    +			if ($diff < 0) $datelim = $date_lim_current;
     			else $datelim = $date_lim_next;
    -
     		}
    -
    -		// 3 : application du decalage
    -		$datelim += ($cdr_decalage * 3600 * 24);
    +		else return 'Bad value for type_cdr in database for record cond_reglement = '.$cond_reglement;
     
     		return $datelim;
     	}
    @@ -776,4 +791,3 @@ abstract class CommonInvoiceLine extends CommonObjectLine
     		$this->db = $db;
     	}
     }
    -
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index d4102873dae..aa318a48bcc 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -1,11 +1,9 @@
     <?php
     /* Copyright (C) 2006-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2013 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2010-2013 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2012      Christophe Battarel  <christophe.battarel@altairis.fr>
      * Copyright (C) 2010-2015 Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2012-2013 Christophe Battarel  <christophe.battarel@altairis.fr>
    - * Copyright (C) 2011-2018 Philippe Grand	    <philippe.grand@atoo-net.com>
    + * Copyright (C) 2011-2018 Philippe Grand       <philippe.grand@atoo-net.com>
      * Copyright (C) 2012-2015 Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2012-2015 Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
    @@ -13,8 +11,9 @@
      * Copyright (C) 2016      Bahfir abbes         <dolipar@dolipar.org>
      * Copyright (C) 2017      ATM Consulting       <support@atm-consulting.fr>
      * Copyright (C) 2017      Nicolas ZABOURI      <info@inovea-conseil.com>
    - * Copyright (C) 2017      Rui Strecht		    <rui.strecht@aliartalentos.com>
    - * Copyright (C) 2018      Frederic France      <frederic.france@netlogic.fr>
    + * Copyright (C) 2017      Rui Strecht          <rui.strecht@aliartalentos.com>
    + * Copyright (C) 2018      Frédéric France      <frederic.france@netlogic.fr>
    + * Copyright (C) 2018      Josep Lluís Amador   <joseplluis@lliuretic.cat>
      *
      * 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
    @@ -64,19 +63,19 @@ abstract class CommonObject
     	public $errors=array();
     
     	/**
    -	 * @var string
    +	 * @var string ID to identify managed object
     	 */
     	public $element;
     
     	/**
    -	 * @var string
    +	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element;
     
     	/**
    -	 * @var
    +	 * @var int    Name of subtable line
     	 */
    -	public $table_element_line;
    +	public $table_element_line='';
     
     	/**
     	 * @var string		Key value used to track if data is coming from import wizard
    @@ -169,6 +168,7 @@ abstract class CommonObject
     	 * @see fetch_origin()
     	 */
     	public $origin;
    +
     	/**
     	 * @var int 	The id of originating object
     	 * @see fetch_origin()
    @@ -399,6 +399,12 @@ abstract class CommonObject
     	public $firstname;
     	public $civility_id;
     
    +	// Dates
    +	public $date_creation;			// Date creation
    +	public $date_validation;		// Date validation
    +	public $date_modification;		// Date last change (tms field)
    +
    +
     
     	// No constructor as it is an abstract class
     
    @@ -609,12 +615,23 @@ abstract class CommonObject
     			$out.=dol_print_url($this->url,'_goout',0,1);
     			$outdone++;
     		}
    -		if (! empty($conf->skype->enabled))
    +		$out.='<div style="clear: both;">';
    +		if (! empty($conf->socialnetworks->enabled))
     		{
    -			$out.='<div style="clear: both;"></div>';
    -			if ($this->skype) $out.=dol_print_skype($this->skype,$this->id,$object->id,'AC_SKYPE');
    +			if ($this->skype) $out.=dol_print_socialnetworks($this->skype,$this->id,$object->id,'skype');
     			$outdone++;
     		}
    +		if (! empty($conf->socialnetworks->enabled))
    +		{
    +			if ($this->twitter) $out.=dol_print_socialnetworks($this->twitter,$this->id,$object->id,'twitter');
    +			$outdone++;
    +		}
    +		if (! empty($conf->socialnetworks->enabled))
    +		{
    +			if ($this->facebook) $out.=dol_print_socialnetworks($this->facebook,$this->id,$object->id,'facebook');
    +			$outdone++;
    +		}
    +		$out.='</div>';
     
     		$out.='<!-- END Part to show address block -->';
     
    @@ -714,6 +731,7 @@ abstract class CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Add a link between element $this->element and a contact
     	 *
    @@ -725,6 +743,7 @@ abstract class CommonObject
     	 */
     	function add_contact($fk_socpeople, $type_contact, $source='external',$notrigger=0)
     	{
    +        // phpcs:enable
     		global $user,$langs;
     
     
    @@ -836,6 +855,7 @@ abstract class CommonObject
     		} else return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Copy contact from one element to current
     	 *
    @@ -845,6 +865,7 @@ abstract class CommonObject
     	 */
     	function copy_linked_contact($objFrom, $source='internal')
     	{
    +        // phpcs:enable
     		$contacts = $objFrom->liste_contact(-1, $source);
     		foreach($contacts as $contact)
     		{
    @@ -857,6 +878,7 @@ abstract class CommonObject
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Update a link to contact line
     	 *
    @@ -868,6 +890,7 @@ abstract class CommonObject
     	 */
     	function update_contact($rowid, $statut, $type_contact_id=0, $fk_socpeople=0)
     	{
    +        // phpcs:enable
     		// Insert into database
     		$sql = "UPDATE ".MAIN_DB_PREFIX."element_contact set";
     		$sql.= " statut = ".$statut;
    @@ -886,6 +909,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Delete a link to contact line
     	 *
    @@ -895,6 +919,7 @@ abstract class CommonObject
     	 */
     	function delete_contact($rowid, $notrigger=0)
     	{
    +        // phpcs:enable
     		global $user;
     
     
    @@ -923,6 +948,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Delete all links between an object $this and all its contacts
     	 *
    @@ -932,6 +958,7 @@ abstract class CommonObject
     	 */
     	function delete_linked_contact($source='',$code='')
     	{
    +        // phpcs:enable
     		$temp = array();
     		$typeContact = $this->liste_type_contact($source,'',0,0,$code);
     
    @@ -958,6 +985,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Get array of all contacts for an object
     	 *
    @@ -965,10 +993,11 @@ abstract class CommonObject
     	 *    @param	string		$source		Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user)
     	 *    @param	int         $list       0:Return array contains all properties, 1:Return array contains just id
     	 *    @param    string      $code       Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
    -	 *    @return	array		            Array of contacts
    +	 *    @return	array|int		        Array of contacts, -1 if error
     	 */
     	function liste_contact($statut=-1,$source='external',$list=0,$code='')
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$tab=array();
    @@ -1063,9 +1092,9 @@ abstract class CommonObject
     			dol_print_error($this->db);
     			return -1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Return array with list of possible values for type of contacts
     	 *
    @@ -1078,6 +1107,7 @@ abstract class CommonObject
     	 */
     	function liste_type_contact($source='internal', $order='position', $option=0, $activeonly=0, $code='')
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if (empty($order)) $order='position';
    @@ -1179,6 +1209,7 @@ abstract class CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Load object contact with id=$this->contactid into $this->contact
     	 *
    @@ -1187,6 +1218,7 @@ abstract class CommonObject
     	 */
     	function fetch_contact($contactid=null)
     	{
    +        // phpcs:enable
     		if (empty($contactid)) $contactid=$this->contactid;
     
     		if (empty($contactid)) return 0;
    @@ -1198,6 +1230,7 @@ abstract class CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty
     	 *
    @@ -1206,6 +1239,7 @@ abstract class CommonObject
     	 */
     	function fetch_thirdparty($force_thirdparty_id=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (empty($this->socid) && empty($this->fk_soc) && empty($this->fk_thirdparty) && empty($force_thirdparty_id))
    @@ -1259,6 +1293,7 @@ abstract class CommonObject
     		return $this->fetch($result->rowid);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load data for barcode into properties ->barcode_type*
     	 *	Properties ->barcode_type that is id of barcode. Type is used to find other properties, but
    @@ -1268,6 +1303,7 @@ abstract class CommonObject
     	 */
     	function fetch_barcode()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		dol_syslog(get_class($this).'::fetch_barcode this->element='.$this->element.' this->barcode_type='.$this->barcode_type);
    @@ -1308,6 +1344,7 @@ abstract class CommonObject
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Load the project with id $this->fk_project into this->project
     	 *
    @@ -1315,6 +1352,7 @@ abstract class CommonObject
     	 */
     	function fetch_projet()
     	{
    +        // phpcs:enable
     		include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     
     		if (empty($this->fk_project) && ! empty($this->fk_projet)) $this->fk_project = $this->fk_projet;	// For backward compatibility
    @@ -1328,6 +1366,7 @@ abstract class CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Load the product with id $this->fk_product into this->product
     	 *
    @@ -1335,6 +1374,7 @@ abstract class CommonObject
     	 */
     	function fetch_product()
     	{
    +        // phpcs:enable
     		include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
     		if (empty($this->fk_product)) return 0;
    @@ -1346,6 +1386,7 @@ abstract class CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Load the user with id $userid into this->user
     	 *
    @@ -1354,12 +1395,14 @@ abstract class CommonObject
     	 */
     	function fetch_user($userid)
     	{
    +        // phpcs:enable
     		$user = new User($this->db);
     		$result=$user->fetch($userid);
     		$this->user = $user;
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Read linked origin object
     	 *
    @@ -1367,6 +1410,7 @@ abstract class CommonObject
     	 */
     	function fetch_origin()
     	{
    +        // phpcs:enable
     		if ($this->origin == 'shipping') $this->origin = 'expedition';
     		if ($this->origin == 'delivery') $this->origin = 'livraison';
     
    @@ -1526,6 +1570,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load properties id_previous and id_next by comparing $fieldid with $this->ref
     	 *
    @@ -1536,6 +1581,7 @@ abstract class CommonObject
     	 */
     	function load_previous_next_ref($filter, $fieldid, $nodbprefix=0)
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		if (! $this->table_element)
    @@ -1864,7 +1910,7 @@ abstract class CommonObject
     							case 'order_supplier':
     								$this->updateline(
     									$line->id, ($line->description?$line->description:$line->desc), $line->subprice, $line->qty, $line->remise_percent,
    -									$line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits,  $line->product_type, false,
    +									$line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, false,
     									$line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice
     								);
     								break;
    @@ -1879,7 +1925,6 @@ abstract class CommonObject
     								dol_syslog(get_class($this).'::setMulticurrencyRate no updateline defined', LOG_DEBUG);
     								break;
     						}
    -
     					}
     				}
     
    @@ -2026,7 +2071,6 @@ abstract class CommonObject
                 $this->db->commit();
                 return 1;
             }
    -
     	}
     
     
    @@ -2161,6 +2205,7 @@ abstract class CommonObject
     
     	// TODO: Move line related operations to CommonObjectLine?
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Save a new position (field rang) for details lines.
     	 *  You can choose to set position for lines with already a position or lines without any position defined.
    @@ -2172,6 +2217,7 @@ abstract class CommonObject
     	 */
     	function line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
     	{
    +        // phpcs:enable
     		if (! $this->table_element_line)
     		{
     			dol_syslog(get_class($this)."::line_order was called on objet with property table_element_line not defined",LOG_ERR);
    @@ -2280,6 +2326,7 @@ abstract class CommonObject
     		return $rows;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Update a line to have a lower rank
     	 *
    @@ -2289,6 +2336,7 @@ abstract class CommonObject
     	 */
     	function line_up($rowid, $fk_parent_line=true)
     	{
    +        // phpcs:enable
     		$this->line_order(false, 'ASC', $fk_parent_line);
     
     		// Get rang of line
    @@ -2298,6 +2346,7 @@ abstract class CommonObject
     		$this->updateLineUp($rowid, $rang);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Update a line to have a higher rank
     	 *
    @@ -2307,6 +2356,7 @@ abstract class CommonObject
     	 */
     	function line_down($rowid, $fk_parent_line=true)
     	{
    +        // phpcs:enable
     		$this->line_order(false, 'ASC', $fk_parent_line);
     
     		// Get rang of line
    @@ -2341,6 +2391,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Update position of line with ajax (rang)
     	 *
    @@ -2349,6 +2400,7 @@ abstract class CommonObject
     	 */
     	function line_ajaxorder($rows)
     	{
    +        // phpcs:enable
     		$num = count($rows);
     		for ($i = 0 ; $i < $num ; $i++)
     		{
    @@ -2456,6 +2508,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Get max value used for position of line (rang)
     	 *
    @@ -2464,6 +2517,7 @@ abstract class CommonObject
     	 */
     	function line_max($fk_parent_line=0)
     	{
    +        // phpcs:enable
     		// Search the last rang with fk_parent_line
     		if ($fk_parent_line)
     		{
    @@ -2502,6 +2556,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update external ref of element
     	 *
    @@ -2510,6 +2565,7 @@ abstract class CommonObject
     	 */
     	function update_ref_ext($ref_ext)
     	{
    +        // phpcs:enable
     		if (! $this->table_element)
     		{
     			dol_syslog(get_class($this)."::update_ref_ext was called on objet with property table_element not defined", LOG_ERR);
    @@ -2533,6 +2589,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update note of element
     	 *
    @@ -2540,8 +2597,9 @@ abstract class CommonObject
     	 *  @param		string		$suffix		'', '_public' or '_private'
     	 *  @return     int      		   		<0 if KO, >0 if OK
     	 */
    -	function update_note($note,$suffix='')
    +	function update_note($note, $suffix='')
     	{
    +        // phpcs:enable
     		global $user;
     
     		if (! $this->table_element)
    @@ -2584,6 +2642,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Update public note (kept for backward compatibility)
     	 *
    @@ -2594,9 +2653,11 @@ abstract class CommonObject
     	 */
     	function update_note_public($note)
     	{
    +        // phpcs:enable
     		return $this->update_note($note,'_public');
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
     	 *  Must be called at end of methods addline or updateline.
    @@ -2609,7 +2670,8 @@ abstract class CommonObject
     	 */
     	function update_price($exclspec=0,$roundingadjust='none',$nodatabaseupdate=0,$seller=null)
     	{
    -		global $conf;
    +        // phpcs:enable
    +		global $conf, $hookmanager, $action;
     
     		// Some external module want no update price after a trigger because they have another method to calculate the total (ex: with an extrafield)
     		$MODULE = "";
    @@ -2700,7 +2762,10 @@ abstract class CommonObject
     				$obj = $this->db->fetch_object($resql);
     
     				// Note: There is no check on detail line and no check on total, if $forcedroundingmode = 'none'
    -				if ($forcedroundingmode == '0')	// Check if data on line are consistent. This may solve lines that were not consistent because set with $forcedroundingmode='auto'
    +				$parameters=array('fk_element' => $obj->rowid);
    +				$reshook = $hookmanager->executeHooks('changeRoundingMode', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
    +
    +				if (empty($reshook) && $forcedroundingmode == '0')	// Check if data on line are consistent. This may solve lines that were not consistent because set with $forcedroundingmode='auto'
     				{
     					$localtax_array=array($obj->localtax1_type,$obj->localtax1_tx,$obj->localtax2_type,$obj->localtax2_tx);
     					$tmpcal=calcul_price_total($obj->qty, $obj->up, $obj->remise_percent, $obj->vatrate, $obj->localtax1_tx, $obj->localtax2_tx, 0, 'HT', $obj->info_bits, $obj->product_type, $seller, $localtax_array, (isset($obj->situation_percent) ? $obj->situation_percent : 100), $multicurrency_tx);
    @@ -2749,7 +2814,6 @@ abstract class CommonObject
     								$this->total_ttc -= $diff;
     								$total_tva_by_vats[$obj->vatrate] -= $diff;
     								$total_ttc_by_vats[$obj->vatrate] -= $diff;
    -
     					}
     				}
     
    @@ -2832,6 +2896,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Add objects linked in llx_element_element.
     	 *
    @@ -2842,6 +2907,7 @@ abstract class CommonObject
     	 */
     	function add_object_linked($origin=null, $origin_id=null)
     	{
    +        // phpcs:enable
     		$origin = (! empty($origin) ? $origin : $this->origin);
     		$origin_id = (! empty($origin_id) ? $origin_id : $this->origin_id);
     
    @@ -2879,7 +2945,9 @@ abstract class CommonObject
     	}
     
     	/**
    -	 *	Fetch array of objects linked to current object. Links are loaded into this->linkedObjects array and this->linkedObjectsIds
    +	 *	Fetch array of objects linked to current object (object of enabled modules only). Links are loaded into
    +	 *		this->linkedObjectsIds array and
    +	 *		this->linkedObjects array if $loadalsoobjects = 1
     	 *  Possible usage for parameters:
     	 *  - all parameters empty -> we look all link to current object (current object can be source or target)
     	 *  - source id+type -> will get target list linked to source
    @@ -2887,17 +2955,18 @@ abstract class CommonObject
     	 *  - source id+type + target type -> will get target list of the type
     	 *  - target id+type + target source -> will get source list of the type
     	 *
    -	 *	@param	int		$sourceid		Object source id (if not defined, id of object)
    -	 *	@param  string	$sourcetype		Object source type (if not defined, element name of object)
    -	 *	@param  int		$targetid		Object target id (if not defined, id of object)
    -	 *	@param  string	$targettype		Object target type (if not defined, elemennt name of object)
    -	 *	@param  string	$clause			'OR' or 'AND' clause used when both source id and target id are provided
    -	 *  @param  int		$alsosametype	0=Return only links to object that differs from source. 1=Include also link to objects of same type.
    -	 *  @param  string	$orderby		SQL 'ORDER BY' clause
    -	 *	@return int						<0 if KO, >0 if OK
    +	 *	@param	int		$sourceid			Object source id (if not defined, id of object)
    +	 *	@param  string	$sourcetype			Object source type (if not defined, element name of object)
    +	 *	@param  int		$targetid			Object target id (if not defined, id of object)
    +	 *	@param  string	$targettype			Object target type (if not defined, elemennt name of object)
    +	 *	@param  string	$clause				'OR' or 'AND' clause used when both source id and target id are provided
    +	 *  @param  int		$alsosametype		0=Return only links to object that differs from source type. 1=Include also link to objects of same type.
    +	 *  @param  string	$orderby			SQL 'ORDER BY' clause
    +	 *  @param	int		$loadalsoobjects	Load also array this->linkedObjects (Use 0 to increase performances)
    +	 *	@return int							<0 if KO, >0 if OK
     	 *  @see	add_object_linked, updateObjectLinked, deleteObjectLinked
     	 */
    -	function fetchObjectLinked($sourceid=null,$sourcetype='',$targetid=null,$targettype='',$clause='OR',$alsosametype=1,$orderby='sourcetype')
    +	function fetchObjectLinked($sourceid=null,$sourcetype='',$targetid=null,$targettype='',$clause='OR',$alsosametype=1,$orderby='sourcetype',$loadalsoobjects=1)
     	{
     		global $conf;
     
    @@ -2926,10 +2995,10 @@ abstract class CommonObject
     		$targettype = (! empty($targettype) ? $targettype : $this->element);
     
     		/*if (empty($sourceid) && empty($targetid))
    -        {
    -        	dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR);
    -        	return -1;
    -        }*/
    +		 {
    +		 dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR);
    +		 return -1;
    +		 }*/
     
     		// Links between objects are stored in table element_element
     		$sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype';
    @@ -2991,7 +3060,8 @@ abstract class CommonObject
     
     			if (! empty($this->linkedObjectsIds))
     			{
    -				foreach($this->linkedObjectsIds as $objecttype => $objectids)       // $objecttype is a module name ('facture', 'mymodule', ...) or a module name with a suffix ('project_task', 'mymodule_myobj', ...)
    +				$tmparray = $this->linkedObjectsIds;
    +				foreach($tmparray as $objecttype => $objectids)       // $objecttype is a module name ('facture', 'mymodule', ...) or a module name with a suffix ('project_task', 'mymodule_myobj', ...)
     				{
     					// Parse element/subelement (ex: project_task, cabinetmed_consultation, ...)
     					$module = $element = $subelement = $objecttype;
    @@ -3057,21 +3127,28 @@ abstract class CommonObject
     					// Here $module, $classfile and $classname are set
     					if ($conf->$module->enabled && (($element != $this->element) || $alsosametype))
     					{
    -						dol_include_once('/'.$classpath.'/'.$classfile.'.class.php');
    -						//print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname);
    -						if (class_exists($classname))
    +						if ($loadalsoobjects)
     						{
    -							foreach($objectids as $i => $objectid)	// $i is rowid into llx_element_element
    +							dol_include_once('/'.$classpath.'/'.$classfile.'.class.php');
    +							//print '/'.$classpath.'/'.$classfile.'.class.php '.class_exists($classname);
    +							if (class_exists($classname))
     							{
    -								$object = new $classname($this->db);
    -								$ret = $object->fetch($objectid);
    -								if ($ret >= 0)
    +								foreach($objectids as $i => $objectid)	// $i is rowid into llx_element_element
     								{
    -									$this->linkedObjects[$objecttype][$i] = $object;
    +									$object = new $classname($this->db);
    +									$ret = $object->fetch($objectid);
    +									if ($ret >= 0)
    +									{
    +										$this->linkedObjects[$objecttype][$i] = $object;
    +									}
     								}
     							}
     						}
     					}
    +					else
    +					{
    +						unset($this->linkedObjectsIds[$objecttype]);
    +					}
     				}
     			}
     			return 1;
    @@ -3593,6 +3670,7 @@ abstract class CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return incoterms informations
     	 *    TODO Use a cache for label get
    @@ -3601,6 +3679,7 @@ abstract class CommonObject
     	 */
     	function display_incoterms()
     	{
    +        // phpcs:enable
     		$out = '';
     		$this->libelle_incoterms = '';
     		if (!empty($this->fk_incoterms))
    @@ -3772,6 +3851,7 @@ abstract class CommonObject
     
     			print '<tr class="liste_titre nodrag nodrop">';
     
    +			// Adds a line numbering column
     			if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) print '<td class="linecolnum" align="center" width="5">&nbsp;</td>';
     
     			// Description
    @@ -4200,6 +4280,7 @@ abstract class CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Add resources to the current object : add entry into llx_element_resources
     	 *	Need $this->element & $this->id
    @@ -4212,6 +4293,7 @@ abstract class CommonObject
     	 */
     	function add_element_resource($resource_id, $resource_type, $busy=0, $mandatory=0)
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."element_resources (";
    @@ -4244,6 +4326,7 @@ abstract class CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Delete a link to resource line
     	 *
    @@ -4254,6 +4337,7 @@ abstract class CommonObject
     	 */
     	function delete_resource($rowid, $element, $notrigger=0)
     	{
    +        // phpcs:enable
     		global $user;
     
     		$this->db->begin();
    @@ -4544,7 +4628,6 @@ abstract class CommonObject
     				dol_print_error($this->db, "Error generating document for ".__CLASS__.". Error: ".$obj->error, $obj->errors);
     				return -1;
     			}
    -
     		}
     		else
     		{
    @@ -4620,13 +4703,13 @@ abstract class CommonObject
     		if (isset($conf->global->$keyforfieldname)) return $conf->global->$keyforfieldname;
     
     		// TODO Ad here a scan into table llx_overwrite_default with a filter on $this->element and $fieldname
    -
     	}
     
     
     	/* For triggers */
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Call trigger based on this instance.
     	 * Some context information may also be provided into array property this->context.
    @@ -4639,6 +4722,7 @@ abstract class CommonObject
     	 */
     	function call_trigger($trigger_name, $user)
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    @@ -4663,6 +4747,7 @@ abstract class CommonObject
     	/* Functions for extrafields */
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Function to get extra fields of an object into $this->array_options
     	 *  This method is in most cases called by method fetch of objects but you can call it separately.
    @@ -4673,6 +4758,7 @@ abstract class CommonObject
     	 */
     	function fetch_optionals($rowid=null, $optionsArray=null)
     	{
    +        // phpcs:enable
     		if (empty($rowid)) $rowid=$this->id;
     
     		// To avoid SQL errors. Probably not the better solution though
    @@ -5184,10 +5270,10 @@ abstract class CommonObject
     	 * @param  string  		$moreparam     To add more parameters on html input tag
     	 * @param  string  		$keysuffix     Prefix string to add into name and id of field (can be used to avoid duplicate names)
     	 * @param  string  		$keyprefix     Suffix string to add into name and id of field (can be used to avoid duplicate names)
    -	 * @param  string|int	$showsize      Value for css to define size. May also be a numeric.
    +	 * @param  string|int		$morecss       Value for css to define style/length of field. May also be a numeric.
     	 * @return string
     	 */
    -	function showInputField($val, $key, $value, $moreparam='', $keysuffix='', $keyprefix='', $showsize=0)
    +	function showInputField($val, $key, $value, $moreparam='', $keysuffix='', $keyprefix='', $morecss=0)
     	{
     		global $conf,$langs,$form;
     
    @@ -5197,38 +5283,51 @@ abstract class CommonObject
     			$form=new Form($this->db);
     		}
     
    +		$val=$this->fields[$key];
    +
    +		$out='';
    +        $type='';
    +        $param = array();
    +        $param['options']=array();
    +        $size =$this->fields[$key]['size'];
    +        // Because we work on extrafields
    +        if(preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)){
    +            $param['options']=array($reg[1].':'.$reg[2]=>'N');
    +            $type ='link';
    +        } elseif(preg_match('/^link:(.*):(.*)/i', $val['type'], $reg)) {
    +            $param['options']=array($reg[1].':'.$reg[2]=>'N');
    +            $type ='link';
    +        } elseif(preg_match('/^sellist:(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
    +            $param['options']=array($reg[1].':'.$reg[2].':'.$reg[3].':'.$reg[4]=>'N');
    +            $type ='sellist';
    +        } elseif(preg_match('/varchar\((\d+)\)/', $val['type'],$reg)) {
    +            $param['options']=array();
    +            $type ='varchar';
    +            $size=$reg[1];
    +        } elseif(preg_match('/varchar/', $val['type'])) {
    +            $param['options']=array();
    +            $type ='varchar';
    +        } elseif(is_array($this->fields[$key]['arrayofkeyval'])) {
    +            $param['options']=$this->fields[$key]['arrayofkeyval'];
    +            $type ='select';
    +        } else {
    +            $param['options']=array();
    +            $type =$this->fields[$key]['type'];
    +        }
    +
    +		$label=$this->fields[$key]['label'];
    +		//$elementtype=$this->fields[$key]['elementtype'];	// Seems not used
    +		$default=$this->fields[$key]['default'];
    +		$computed=$this->fields[$key]['computed'];
    +		$unique=$this->fields[$key]['unique'];
    +		$required=$this->fields[$key]['required'];
    +
    +		$langfile=$this->fields[$key]['langfile'];
    +		$list=$this->fields[$key]['list'];
    +		$hidden=abs($this->fields[$key]['visible'])!=1?1:0;
    +
     		$objectid = $this->id;
     
    -		$label= $val['label'];
    -		$type = $val['type'];
    -		$size = $val['css'];
    -
    -		// Convert var to be able to share same code than showInputField of extrafields
    -		if (preg_match('/varchar\((\d+)\)/', $type, $reg))
    -		{
    -			$type = 'varchar';		// convert varchar(xx) int varchar
    -			$size = $reg[1];
    -		}
    -		elseif (preg_match('/varchar/', $type)) $type = 'varchar';		// convert varchar(xx) into varchar
    -		elseif (preg_match('/double/', $type)) $type = 'double';		// convert double(xx) into double
    -		if (is_array($val['arrayofkeyval'])) $type='select';
    -		if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) $type='link';
    -
    -		$default=$val['default'];
    -		$computed=$val['computed'];
    -		$unique=$val['unique'];
    -		$required=$val['required'];
    -		$param=$val['param'];
    -		if (is_array($val['arrayofkeyval'])) $param['options'] = $val['arrayofkeyval'];
    -		if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg))
    -		{
    -			$type='link';
    -			$param['options']=array($reg[1].':'.$reg[2]=>$reg[1].':'.$reg[2]);
    -		}
    -		$langfile=$val['langfile'];
    -		$list=$val['list'];
    -		$hidden=(abs($val['visible'])!=1 ? 1 : 0);
    -		$help=$val['help'];
     
     		if ($computed)
     		{
    @@ -5236,54 +5335,50 @@ abstract class CommonObject
     			else return '';
     		}
     
    +
     		// Use in priority showsize from parameters, then $val['css'] then autodefine
    -		if (empty($showsize) && ! empty($val['css']))
    +		if (empty($morecss) && ! empty($val['css']))
     		{
     			$showsize = $val['css'];
     		}
    -		if (empty($showsize))
    +		if (empty($morecss))
     		{
     			if ($type == 'date')
     			{
    -				//$showsize=10;
    -				$showsize = 'minwidth100imp';
    +				$morecss = 'minwidth100imp';
     			}
     			elseif ($type == 'datetime')
     			{
    -				//$showsize=19;
    -				$showsize = 'minwidth200imp';
    +				$morecss = 'minwidth200imp';
     			}
    -			elseif (in_array($type,array('int','double','price')))
    +			elseif (in_array($type,array('int','integer','price')) || preg_match('/^double(\([0-9],[0-9]\)){0,1}/',$type))
     			{
    -				//$showsize=10;
    -				$showsize = 'maxwidth75';
    -			}
    -			elseif ($type == 'url')
    +				$morecss = 'maxwidth75';
    +                        }elseif ($type == 'url')
     			{
    -				$showsize='minwidth400';
    +				$morecss='minwidth400';
     			}
     			elseif ($type == 'boolean')
     			{
    -				$showsize='';
    +				$morecss='';
     			}
     			else
     			{
     				if (round($size) < 12)
     				{
    -					$showsize = 'minwidth100';
    +					$morecss = 'minwidth100';
     				}
     				else if (round($size) <= 48)
     				{
    -					$showsize = 'minwidth200';
    +					$morecss = 'minwidth200';
     				}
     				else
     				{
    -					//$showsize=48;
    -					$showsize = 'minwidth400';
    +					$morecss = 'minwidth400';
     				}
     			}
     		}
    -		//var_dump($showsize.' '.$size);
    +
     		if (in_array($type,array('date','datetime')))
     		{
     			$tmp=explode(',',$size);
    @@ -5291,37 +5386,51 @@ abstract class CommonObject
     
     			$showtime = in_array($type,array('datetime')) ? 1 : 0;
     
    -			// Do not show current date when field not required (see select_date() method)
    +			// Do not show current date when field not required (see selectDate() method)
     			if (!$required && $value == '') $value = '-1';
     
     			// TODO Must also support $moreparam
    -			$out = $form->select_date($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, ($keyprefix != 'search_' ? 1 : 0), 1, 0, 1);
    +			$out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
     		}
     		elseif (in_array($type,array('int','integer')))
     		{
     			$tmp=explode(',',$size);
     			$newsize=$tmp[0];
    -			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
    +			$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$newsize.'" value="'.dol_escape_htmltag($value).'"'.($moreparam?$moreparam:'').'>';
     		}
     		elseif (preg_match('/varchar/', $type))
     		{
    -			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$size.'" value="'.dol_escape_htmltag($value).'"'.($moreparam?$moreparam:'').'>';
    +			$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" maxlength="'.$size.'" value="'.dol_escape_htmltag($value).'"'.($moreparam?$moreparam:'').'>';
     		}
     		elseif (in_array($type, array('mail', 'phone', 'url')))
     		{
    -			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
    +			$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
     		}
     		elseif ($type == 'text')
     		{
    -			require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    -			$doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,0,ROWS_5,'90%');
    -			$out=$doleditor->Create(1);
    +			if (! preg_match('/search_/', $keyprefix))		// If keyprefix is search_ or search_options_, we must just use a simple text field
    +			{
    +				require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    +				$doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,false,ROWS_5,'90%');
    +				$out=$doleditor->Create(1);
    +			}
    +			else
    +			{
    +				$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
    +			}
     		}
     		elseif ($type == 'html')
     		{
    -			require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    -			$doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_5,'90%');
    -			$out=$doleditor->Create(1);
    +			if (! preg_match('/search_/', $keyprefix))		// If keyprefix is search_ or search_options_, we must just use a simple text field
    +			{
    +				require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    +				$doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_5,'90%');
    +				$out=$doleditor->Create(1);
    +			}
    +			else
    +			{
    +				$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.dol_escape_htmltag($value).'" '.($moreparam?$moreparam:'').'>';
    +			}
     		}
     		elseif ($type == 'boolean')
     		{
    @@ -5331,21 +5440,21 @@ abstract class CommonObject
     			} else {
     				$checked=' value="1" ';
     			}
    -			$out='<input type="checkbox" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
    +			$out='<input type="checkbox" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
     		}
     		elseif ($type == 'price')
     		{
     			if (!empty($value)) {		// $value in memory is a php numeric, we format it into user number format.
     				$value=price($value);
     			}
    -			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> '.$langs->getCurrencySymbol($conf->currency);
    +			$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> '.$langs->getCurrencySymbol($conf->currency);
     		}
    -		elseif ($type == 'double')
    +		elseif (preg_match('/^double(\([0-9],[0-9]\)){0,1}/',$type))
     		{
     			if (!empty($value)) {		// $value in memory is a php numeric, we format it into user number format.
     				$value=price($value);
     			}
    -			$out='<input type="text" class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> ';
    +			$out='<input type="text" class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'> ';
     		}
     		elseif ($type == 'select')
     		{
    @@ -5356,8 +5465,8 @@ abstract class CommonObject
     				$out.= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
     			}
     
    -			$out.='<select class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
    -			if ((! isset($val['default'])) || ($val['notnull'] != 1)) $out.='<option value="0">&nbsp;</option>';
    +			$out.='<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
    +                if((! isset($this->fields[$key]['default'])) ||($this->fields[$key]['notnull']!=1))$out.='<option value="0">&nbsp;</option>';
     			foreach ($param['options'] as $key => $val)
     			{
     				if ((string) $key == '') continue;
    @@ -5378,11 +5487,13 @@ abstract class CommonObject
     				$out.= ajax_combobox($keyprefix.$key.$keysuffix, array(), 0);
     			}
     
    -			$out.='<select class="flat '.$showsize.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
    +			$out.='<select class="flat '.$morecss.' maxwidthonsmartphone" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'').'>';
     			if (is_array($param['options']))
     			{
     				$param_list=array_keys($param['options']);
     				$InfoFieldList = explode(":", $param_list[0]);
    +				$parentName='';
    +				$parentField='';
     				// 0 : tableName
     				// 1 : label field name
     				// 2 : key fields name (if differ of rowid)
    @@ -5467,8 +5578,9 @@ abstract class CommonObject
     						$obj = $this->db->fetch_object($resql);
     
     						// Several field into label (eq table:code|libelle:rowid)
    +						$notrans = false;
     						$fields_label = explode('|',$InfoFieldList[1]);
    -						if(is_array($fields_label))
    +						if (is_array($fields_label))
     						{
     							$notrans = true;
     							foreach ($fields_label as $field_toshow)
    @@ -5482,7 +5594,7 @@ abstract class CommonObject
     						}
     						$labeltoshow=dol_trunc($labeltoshow,45);
     
    -						if ($value==$obj->rowid)
    +						if ($value == $obj->rowid)
     						{
     							foreach ($fields_label as $field_toshow)
     							{
    @@ -5497,7 +5609,7 @@ abstract class CommonObject
     						}
     						else
     						{
    -							if(!$notrans)
    +							if (! $notrans)
     							{
     								$translabel=$langs->trans($obj->{$InfoFieldList[1]});
     								if ($translabel!=$obj->{$InfoFieldList[1]}) {
    @@ -5513,7 +5625,7 @@ abstract class CommonObject
     								$out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
     							}
     
    -							if (!empty($InfoFieldList[3]))
    +							if (!empty($InfoFieldList[3]) && $parentField)
     							{
     								$parent = $parentName.':'.$obj->{$parentField};
     							}
    @@ -5544,7 +5656,7 @@ abstract class CommonObject
     			$out='';
     			foreach ($param['options'] as $keyopt => $val)
     			{
    -				$out.='<input class="flat '.$showsize.'" type="radio" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'');
    +				$out.='<input class="flat '.$morecss.'" type="radio" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" '.($moreparam?$moreparam:'');
     				$out.=' value="'.$keyopt.'"';
     				$out.=' id="'.$keyprefix.$key.$keysuffix.'_'.$keyopt.'"';
     				$out.= ($value==$keyopt?'checked':'');
    @@ -5563,6 +5675,8 @@ abstract class CommonObject
     			if (is_array($param['options'])) {
     				$param_list = array_keys($param['options']);
     				$InfoFieldList = explode(":", $param_list[0]);
    +				$parentName='';
    +				$parentField='';
     				// 0 : tableName
     				// 1 : label field name
     				// 2 : key fields name (if differ of rowid)
    @@ -5636,6 +5750,7 @@ abstract class CommonObject
     						$labeltoshow = '';
     						$obj = $this->db->fetch_object($resql);
     
    +						$notrans = false;
     						// Several field into label (eq table:code|libelle:rowid)
     						$fields_label = explode('|', $InfoFieldList[1]);
     						if (is_array($fields_label)) {
    @@ -5659,7 +5774,6 @@ abstract class CommonObject
     							}
     
     							$data[$obj->rowid]=$labeltoshow;
    -
     						} else {
     							if (! $notrans) {
     								$translabel = $langs->trans($obj->{$InfoFieldList[1]});
    @@ -5676,7 +5790,7 @@ abstract class CommonObject
     									$data[$obj->rowid]=$labeltoshow;
     								}
     
    -								if (! empty($InfoFieldList[3])) {
    +								if (! empty($InfoFieldList[3]) && $parentField) {
     									$parent = $parentName . ':' . $obj->{$parentField};
     								}
     
    @@ -5688,23 +5802,21 @@ abstract class CommonObject
     					$this->db->free($resql);
     
     					$out=$form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
    -
     				} else {
     					print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
     				}
     			}
    -			$out .= '</select>';
     		}
     		elseif ($type == 'link')
     		{
     			$param_list=array_keys($param['options']);				// $param_list='ObjectName:classPath'
    -			$showempty=(($val['notnull'] == 1 && $val['default'] != '')?0:1);
    +			$showempty=(($required && $default != '')?0:1);
     			$out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty);
     		}
     		elseif ($type == 'password')
     		{
     			// If prefix is 'search_', field is used as a filter, we use a common text field.
    -			$out='<input type="'.($keyprefix=='search_'?'text':'password').'" class="flat '.$showsize.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
    +			$out='<input type="'.($keyprefix=='search_'?'text':'password').'" class="flat '.$morecss.'" name="'.$keyprefix.$key.$keysuffix.'" id="'.$keyprefix.$key.$keysuffix.'" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
     		}
     		elseif ($type == 'array')
     		{
    @@ -5751,7 +5863,6 @@ abstract class CommonObject
     		return $out;
     	}
     
    -
     	/**
     	 * Return HTML string to show a field into a page
     	 * Code very similar with showOutputField of extra fields
    @@ -6070,7 +6181,6 @@ abstract class CommonObject
     					}
     				}
     				$value='<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
    -
     			} else {
     				dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING);
     			}
    @@ -6087,6 +6197,7 @@ abstract class CommonObject
     				$InfoFieldList = explode(":", $param_list[0]);
     				$classname=$InfoFieldList[0];
     				$classpath=$InfoFieldList[1];
    +				$getnomurlparam=(empty($InfoFieldList[2]) ? 3 : $InfoFieldList[2]);
     				if (! empty($classpath))
     				{
     					dol_include_once($InfoFieldList[1]);
    @@ -6094,7 +6205,7 @@ abstract class CommonObject
     					{
     						$object = new $classname($this->db);
     						$object->fetch($value);
    -						$value=$object->getNomUrl(3);
    +						$value=$object->getNomUrl($getnomurlparam);
     					}
     				}
     				else
    @@ -6103,6 +6214,7 @@ abstract class CommonObject
     					return 'Error bad setup of extrafield';
     				}
     			}
    +			else $value='';
     		}
     		elseif ($type == 'text' || $type == 'html')
     		{
    @@ -6129,7 +6241,7 @@ abstract class CommonObject
     	 *
     	 * @param 	Extrafields $extrafields    Extrafield Object
     	 * @param 	string      $mode           Show output (view) or input (edit) for extrafield
    -	 * @param 	array       $params         Optional parameters
    +	 * @param 	array       $params         Optional parameters. Example: array('style'=>'class="oddeven"', 'colspan'=>$colspan)
     	 * @param 	string      $keysuffix      Suffix string to add after name and id of field (can be used to avoid duplicate names)
     	 * @param 	string      $keyprefix      Prefix string to add before name and id of field (can be used to avoid duplicate names)
     	 * @param	string		$onetrtd		All fields in same tr td
    @@ -6152,6 +6264,9 @@ abstract class CommonObject
     			$e = 0;
     			foreach($extrafields->attributes[$this->table_element]['label'] as $key=>$label)
     			{
    +				//Show only the key field in params
    +				if (is_array($params) && array_key_exists('onlykey',$params) && $key != $params['onlykey']) continue;
    +
     				$enabled = 1;
     				if ($enabled && isset($extrafields->attributes[$this->table_element]['list'][$key]))
     				{
    @@ -6438,6 +6553,7 @@ abstract class CommonObject
     		return $buyPrice;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show photos of an object (nbmax maximum), into several columns
     	 *
    @@ -6457,6 +6573,7 @@ abstract class CommonObject
     	 */
     	function show_photos($modulepart, $sdir, $size=0, $nbmax=0, $nbbyrow=5, $showfilename=0, $showaction=0, $maxHeight=120, $maxWidth=160, $nolink=0, $notitle=0, $usesharelink=0)
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		include_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php';
    @@ -6851,6 +6968,7 @@ abstract class CommonObject
     	 * Function to load data from a SQL pointer into properties of current object $this
     	 *
     	 * @param   stdClass    $obj    Contain data of object from database
    +     * @return void
     	 */
     	protected function setVarsFromFetchObj(&$obj)
     	{
    @@ -6914,7 +7032,8 @@ abstract class CommonObject
     	 * @param	array		$fieldsentry	Properties of field
     	 * @return 	string
     	 */
    -	protected function quote($value, $fieldsentry) {
    +    protected function quote($value, $fieldsentry)
    +    {
     		if (is_null($value)) return 'NULL';
     		else if (preg_match('/^(int|double|real)/i', $fieldsentry['type'])) return $this->db->escape("$value");
     		else return "'".$this->db->escape($value)."'";
    @@ -7229,7 +7348,7 @@ abstract class CommonObject
     		$comment = new Comment($this->db);
     		$result=$comment->fetchAllFor($this->element, $this->id);
     		if ($result<0) {
    -			$this->errors=array_merge($this->errors,$comment->errors);
    +			$this->errors=array_merge($this->errors, $comment->errors);
     			return -1;
     		} else {
     			$this->comments = $comment->comments;
    @@ -7247,4 +7366,19 @@ abstract class CommonObject
     		return count($this->comments);
     	}
     
    +    /**
    +     * Trim object parameters
    +     * @param string[] $parameters array of parameters to trim
    +     *
    +     * @return void
    +     */
    +    public function trimParameters($parameters)
    +    {
    +        if (!is_array($parameters)) return;
    +        foreach ($parameters as $parameter) {
    +            if (isset($this->$parameter)) {
    +                $this->$parameter = trim($this->$parameter);
    +            }
    +        }
    +    }
     }
    diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php
    index bed227eb408..91d4245ff88 100644
    --- a/htdocs/core/class/commonobjectline.class.php
    +++ b/htdocs/core/class/commonobjectline.class.php
    @@ -53,7 +53,7 @@ abstract class CommonObjectLine extends CommonObject
         /**
          *	Returns the translation key from units dictionary.
          *  A langs->trans() must be called on result to get translated value.
    -     *  
    +     *
          * 	@param	string $type Label type (long or short)
          *	@return	string|int <0 if ko, label if ok
          */
    @@ -94,4 +94,3 @@ abstract class CommonObjectLine extends CommonObject
     
     	// For the moment we use the extends on CommonObject until PHP min is 5.4 so use Traits.
     }
    -
    diff --git a/htdocs/core/class/commonorder.class.php b/htdocs/core/class/commonorder.class.php
    index b3e5033330d..2ea53a345d8 100644
    --- a/htdocs/core/class/commonorder.class.php
    +++ b/htdocs/core/class/commonorder.class.php
    @@ -144,6 +144,5 @@ abstract class CommonOrderLine extends CommonObjectLine
     	public $info_bits = 0;
     
     	public $special_code = 0;
    -
     }
     
    diff --git a/htdocs/core/class/commonstickergenerator.class.php b/htdocs/core/class/commonstickergenerator.class.php
    index 1091962f6ea..d5bf6f3317e 100644
    --- a/htdocs/core/class/commonstickergenerator.class.php
    +++ b/htdocs/core/class/commonstickergenerator.class.php
    @@ -1,10 +1,10 @@
     <?php
    -/* Copyright (C) 2003 Steve Dillon
    - * Copyright (C) 2003 Laurent Passebecq
    +/* Copyright (C) 2003      Steve Dillon
    + * Copyright (C) 2003      Laurent Passebecq
      * Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
      * Copyright (C) 2006-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2015 Francis Appels  <francis.appels@yahoo.com>
    + * Copyright (C) 2015      Francis Appels  <francis.appels@yahoo.com>
      *
      * 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
    @@ -61,9 +61,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/format_cards.lib.php';
      */
     abstract class CommonStickerGenerator
     {
    +	public $code;   // Code of format
     
    -	public $code;		// Code of format
    -	public $format;	// Array with informations
    +	/**
    +     * @var array format Array with informations
    +     */
    +    public $format;
     
     	// protected
     	var $_Avery_Name	= '';	// Nom du format de l'etiquette
    @@ -93,7 +96,8 @@ abstract class CommonStickerGenerator
     	{
     		$this->db = $db;
     	}
    -		
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Function to build PDF on disk, then output on HTTP strem.
     	 *
    @@ -104,6 +108,7 @@ abstract class CommonStickerGenerator
     	 *  @return int             				1=OK, 0=KO
     	 */
     	abstract function write_file($arrayofrecords,$outputlangs,$srctemplatepath,$outputdir='');
    +    // phpcs:enable
     
     	/**
     	 * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0)
    @@ -114,7 +119,8 @@ abstract class CommonStickerGenerator
     	 * @return  void
     	 */
     	abstract function addSticker(&$pdf,$outputlangs,$param);
    -	
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Methode qui permet de modifier la taille des caracteres
     	 * Cela modiera aussi l'espace entre chaque ligne
    @@ -125,13 +131,15 @@ abstract class CommonStickerGenerator
     	 */
     	function Set_Char_Size(&$pdf,$pt)
     	{
    +        // phpcs:enable
     		if ($pt > 3) {
     			$this->_Char_Size = $pt;
     			$this->_Line_Height = $this->_Get_Height_Chars($pt);
     			$pdf->SetFont('','',$pt);
     		}
    -	}	
    +	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * protected Print dot line
     	 *
    @@ -146,6 +154,7 @@ abstract class CommonStickerGenerator
     	 */
         function _Pointille(&$pdf,$x1=0,$y1=0,$x2=210,$y2=297,$epaisseur=1,$nbPointilles=15)
     	{
    +        // phpcs:enable
     		$pdf->SetLineWidth($epaisseur);
     		$length=abs($x1-$x2);
     		$hauteur=abs($y1-$y2);
    @@ -173,6 +182,7 @@ abstract class CommonStickerGenerator
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * protected Function realisant une croix aux 4 coins des cartes
     	 *
    @@ -187,6 +197,7 @@ abstract class CommonStickerGenerator
     	 */
     	function _Croix(&$pdf,$x1=0,$y1=0,$x2=210,$y2=297,$epaisseur=1,$taille=4)
     	{
    +        // phpcs:enable
     		$pdf->SetDrawColor(192,192,192);
     
     		$pdf->SetLineWidth($epaisseur);
    @@ -208,25 +219,28 @@ abstract class CommonStickerGenerator
     	}
     
     	/**
    -	 * protected Convert units (in to mm, mm to in)
    +	 * Convert units (in to mm, mm to in)
     	 * $src and $dest must be 'in' or 'mm'
     	 *
     	 * @param int       $value  value
    -	 * @param string    $src    from
    -	 * @param string    $dest   to
    +	 * @param string    $src    from ('in' or 'mm')
    +	 * @param string    $dest   to ('in' or 'mm')
     	 * @return float    value   value after conversion
     	 */
    -	function _Convert_Metric ($value, $src, $dest)
    +	private function convertMetric($value, $src, $dest)
     	{
     		if ($src != $dest) {
    -			$tab['in'] = 39.37008;
    -			$tab['mm'] = 1000;
    +			$tab = array(
    +				'in'=>39.37008,
    +				'mm'=>1000
    +			);
     			return $value * $tab[$dest] / $tab[$src];
    -		} else {
    -			return $value;
     		}
    +
    +		return $value;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * protected Give the height for a char size given.
     	 *
    @@ -235,6 +249,7 @@ abstract class CommonStickerGenerator
     	 */
     	function _Get_Height_Chars($pt)
     	{
    +        // phpcs:enable
     		// Tableau de concordance entre la hauteur des caracteres et de l'espacement entre les lignes
     		$_Table_Hauteur_Chars = array(6=>2, 7=>2.5, 8=>3, 9=>3.5, 10=>4, 11=>6, 12=>7, 13=>8, 14=>9, 15=>10);
     		if (in_array($pt, array_keys($_Table_Hauteur_Chars))) {
    @@ -244,6 +259,7 @@ abstract class CommonStickerGenerator
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * protected Set format
     	 *
    @@ -251,20 +267,20 @@ abstract class CommonStickerGenerator
     	 * @param    string    $format  Format
     	 * @return   void
     	 */
    -	function _Set_Format(&$pdf, $format)  
    +	function _Set_Format(&$pdf, $format)
     	{
    -		$this->_Metric 	= $format['metric'];
    -		$this->_Avery_Name 	= $format['name'];
    -		$this->_Avery_Code	= $format['code'];
    -		$this->_Margin_Left	= $this->_Convert_Metric($format['marginLeft'], $this->_Metric, $this->_Metric_Doc);
    -		$this->_Margin_Top	= $this->_Convert_Metric($format['marginTop'], $this->_Metric, $this->_Metric_Doc);
    -		$this->_X_Space 	= $this->_Convert_Metric($format['SpaceX'], $this->_Metric, $this->_Metric_Doc);
    -		$this->_Y_Space 	= $this->_Convert_Metric($format['SpaceY'], $this->_Metric, $this->_Metric_Doc);
    -		$this->_X_Number 	= $format['NX'];
    -		$this->_Y_Number 	= $format['NY'];
    -		$this->_Width 	= $this->_Convert_Metric($format['width'], $this->_Metric, $this->_Metric_Doc);
    -		$this->_Height	= $this->_Convert_Metric($format['height'], $this->_Metric, $this->_Metric_Doc);
    +        // phpcs:enable
    +		$this->_Metric = $format['metric'];
    +		$this->_Avery_Name = $format['name'];
    +		$this->_Avery_Code = $format['code'];
    +		$this->_Margin_Left	= $this->convertMetric($format['marginLeft'], $this->_Metric, $this->_Metric_Doc);
    +		$this->_Margin_Top = $this->convertMetric($format['marginTop'], $this->_Metric, $this->_Metric_Doc);
    +		$this->_X_Space = $this->convertMetric($format['SpaceX'], $this->_Metric, $this->_Metric_Doc);
    +		$this->_Y_Space = $this->convertMetric($format['SpaceY'], $this->_Metric, $this->_Metric_Doc);
    +		$this->_X_Number = $format['NX'];
    +		$this->_Y_Number = $format['NY'];
    +		$this->_Width = $this->convertMetric($format['width'], $this->_Metric, $this->_Metric_Doc);
    +		$this->_Height = $this->convertMetric($format['height'], $this->_Metric, $this->_Metric_Doc);
     		$this->Set_Char_Size($pdf, $format['font-size']);
     	}
    -
     }
    diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php
    index ae6a73a0973..fc7f6792274 100644
    --- a/htdocs/core/class/conf.class.php
    +++ b/htdocs/core/class/conf.class.php
    @@ -35,8 +35,12 @@ class Conf
     	/** \public */
     	//! To store properties found in conf file
     	var $file;
    -	//! Object with database handler
    -	var $db;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
     	//! To store properties found into database
     	var $global;
     	//! To store browser info
    @@ -178,7 +182,7 @@ class Conf
     							if (is_array($arrValue) && ! empty($arrValue)) $value = $arrValue;
     							else if (in_array($partname,array('login','menus','substitutions','triggers','tpl'))) $value = '/'.$modulename.'/core/'.$partname.'/';
     							else if (in_array($partname,array('models','theme'))) $value = '/'.$modulename.'/';
    -							else if (in_array($partname,array('sms'))) $value = $modulename;
    +							else if (in_array($partname,array('sms'))) $value = '/'.$modulename.'/';
     							else if ($value == 1) $value = '/'.$modulename.'/core/modules/'.$partname.'/';	// ex: partname = societe
     							$this->modules_parts[$partname] = array_merge($this->modules_parts[$partname], array($modulename => $value));	// $value may be a string or an array
     						}
    @@ -679,7 +683,6 @@ class Conf
     				$this->loghandlers[$handler] = $loghandlerinstance;
     			}
     		}
    -
     	}
     }
     
    diff --git a/htdocs/core/class/coreobject.class.php b/htdocs/core/class/coreobject.class.php
    index 1456fb991c2..5129ac54ece 100644
    --- a/htdocs/core/class/coreobject.class.php
    +++ b/htdocs/core/class/coreobject.class.php
    @@ -1,6 +1,6 @@
     <?php
     /* EXPERIMENTAL
    - * 
    + *
      * Copyright (C) 2016		ATM Consulting			<support@atm-consulting.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -22,7 +22,7 @@
      *	\ingroup    core
      *	\brief      File of class to manage all object. Might be replace or merge into commonobject
      */
    - 
    +
     require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
     
     class CoreObject extends CommonObject
    @@ -54,7 +54,7 @@ class CoreObject extends CommonObject
     		$this->id = 0;
     		$this->datec = 0;
     		$this->tms = 0;
    -		
    +
     		if (!empty($this->fields))
     		{
     			foreach ($this->fields as $field=>$info)
    @@ -68,14 +68,13 @@ class CoreObject extends CommonObject
     
                 $this->to_delete=false;
                 $this->is_clone=false;
    -			
    +
     			return true;
     		}
     		else
             {
     			return false;
     		}
    -			
     	}
     
         /**
    @@ -110,7 +109,7 @@ class CoreObject extends CommonObject
         	if($res>0) {
         		if ($loadChild) $this->fetchChild();
         	}
    -    	
    +
         	return $res;
     	}
     
    @@ -133,14 +132,14 @@ class CoreObject extends CommonObject
     				if($object->{$key} === $id) return $k;
     			}
     		}
    -	
    +
     		$k = count($this->{$tabName});
    -	
    +
     		$className = ucfirst($tabName);
     		$this->{$tabName}[$k] = new $className($this->db);
     		if($id>0 && $key==='id' && $try_to_load)
     		{
    -			$this->{$tabName}[$k]->fetch($id); 
    +			$this->{$tabName}[$k]->fetch($id);
     		}
     
     		return $k;
    @@ -171,6 +170,8 @@ class CoreObject extends CommonObject
     
         /**
          * Function to fetch children objects
    +     *
    +     * @return void
          */
         public function fetchChild()
         {
    @@ -207,6 +208,7 @@ class CoreObject extends CommonObject
          * Function to update children data
          *
          * @param   User    $user   user object
    +     * @return void
          */
     	public function saveChild(User &$user)
         {
    @@ -220,7 +222,7 @@ class CoreObject extends CommonObject
     					foreach($this->{$className} as $i => &$object)
     					{
     						$object->{$this->fk_element} = $this->id;
    -						
    +
     						$object->update($user);
     						if($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete==true) unset($this->{$className}[$i]);
     					}
    @@ -268,7 +270,6 @@ class CoreObject extends CommonObject
                 $this->db->rollback();
                 return -1;
             }
    -
     	}
     
         /**
    @@ -434,5 +435,4 @@ class CoreObject extends CommonObject
     
     		return 1;
     	}
    -
     }
    diff --git a/htdocs/core/class/cstate.class.php b/htdocs/core/class/cstate.class.php
    index ae2adde87d4..4320446d7b5 100644
    --- a/htdocs/core/class/cstate.class.php
    +++ b/htdocs/core/class/cstate.class.php
    @@ -32,16 +32,44 @@
      */
     class Cstate // extends CommonObject
     {
    -	var $db;							//!< To store db handler
    -	var $error;							//!< To return error code (or message)
    -	var $errors=array();				//!< To return several error codes (or messages)
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
     	//var $element='cstate';			//!< Id that identify managed objects
     	//var $table_element='cstate';	    //!< Name of table without prefix where object is stored
     
    -    var $id;
    -	var $code_departement;
    -	var $nom;
    -	var $active;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	public $code_departement;
    +
    +	/**
    +	 * @var string
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='';
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name='';
    +
    +	public $active;
     
     
     
    @@ -54,7 +82,6 @@ class Cstate // extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -301,5 +328,4 @@ class Cstate // extends CommonObject
     			return 1;
     		}
     	}
    -
     }
    diff --git a/htdocs/core/class/ctypent.class.php b/htdocs/core/class/ctypent.class.php
    index b3bb750bd80..db8ed461727 100644
    --- a/htdocs/core/class/ctypent.class.php
    +++ b/htdocs/core/class/ctypent.class.php
    @@ -27,17 +27,33 @@
      */
     class Ctypent // extends CommonObject
     {
    -	var $db;							//!< To store db handler
    -	var $error;							//!< To return error code (or message)
    -	var $errors=array();				//!< To return several error codes (or messages)
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
     	//var $element='ctypent';			//!< Id that identify managed objects
     	//var $table_element='ctypent';	//!< Name of table without prefix where object is stored
     
    -    var $id;
    -	var $code;
    -	var $libelle;
    -	var $active;
    -	var $module;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	public $code;
    +	public $libelle;
    +	public $active;
    +	public $module;
     
     
     
    @@ -50,7 +66,6 @@ class Ctypent // extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -317,5 +332,4 @@ class Ctypent // extends CommonObject
     			return 1;
     		}
     	}
    -
     }
    diff --git a/htdocs/core/class/ctyperesource.class.php b/htdocs/core/class/ctyperesource.class.php
    index a5a6ea879ce..f4e74128747 100644
    --- a/htdocs/core/class/ctyperesource.class.php
    +++ b/htdocs/core/class/ctyperesource.class.php
    @@ -19,7 +19,7 @@
      */
     
     /**
    - * \file    resource/ctyperesource.class.php
    + * \file    htdocs/core/class/ctyperesource.class.php
      * \ingroup resource
      */
     
    @@ -36,6 +36,7 @@ class Ctyperesource
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'ctyperesource';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
    @@ -46,15 +47,14 @@ class Ctyperesource
     	 */
     	public $lines = array();
     
    -	/**
    -	 */
    -
     	public $code;
    -	public $label;
    -	public $active;
     
     	/**
    -	 */
    +     * @var string Type resource label
    +     */
    +    public $label;
    +
    +	public $active;
     
     
     	/**
    @@ -127,15 +127,15 @@ class Ctyperesource
     		if (!$error) {
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     
    -			if (!$notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action to call a trigger.
    +			// Uncomment this and change MYOBJECT to your own tag if you
    +			// want this action to call a trigger.
    +			//if (!$notrigger) {
     
    -				//// Call triggers
    -				//$result=$this->call_trigger('MYOBJECT_CREATE',$user);
    -				//if ($result < 0) $error++;
    -				//// End call triggers
    -			}
    +			//  // Call triggers
    +			//  $result=$this->call_trigger('MYOBJECT_CREATE',$user);
    +			//  if ($result < 0) $error++;
    +			//  // End call triggers
    +			//}
     		}
     
     		// Commit or rollback
    @@ -188,8 +188,6 @@ class Ctyperesource
     				$this->code = $obj->code;
     				$this->label = $obj->label;
     				$this->active = $obj->active;
    -
    -
     			}
     
     			// Retrieve all extrafields for invoice
    @@ -269,8 +267,6 @@ class Ctyperesource
     				$line->code = $obj->code;
     				$line->label = $obj->label;
     				$line->active = $obj->active;
    -
    -
     			}
     			$this->db->free($resql);
     
    @@ -331,15 +327,15 @@ class Ctyperesource
     			dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
     		}
     
    -		if (!$error && !$notrigger) {
    -			// Uncomment this and change MYOBJECT to your own tag if you
    -			// want this action calls a trigger.
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action calls a trigger.
    +		//if (!$error && !$notrigger) {
     
    -			//// Call triggers
    -			//$result=$this->call_trigger('MYOBJECT_MODIFY',$user);
    -			//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    -			//// End call triggers
    -		}
    +		//  // Call triggers
    +		//  $result=$this->call_trigger('MYOBJECT_MODIFY',$user);
    +		//  if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    +		//  // End call triggers
    +		//}
     
     		// Commit or rollback
     		if ($error) {
    @@ -369,17 +365,15 @@ class Ctyperesource
     
     		$this->db->begin();
     
    -		if (!$error) {
    -			if (!$notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action calls a trigger.
    +		// Uncomment this and change MYOBJECT to your own tag if you
    +		// want this action calls a trigger.
    +		//if (!$error && !$notrigger) {
     
    -				//// Call triggers
    -				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
    -				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    -				//// End call triggers
    -			}
    -		}
    +		//  // Call triggers
    +		//  $result=$this->call_trigger('MYOBJECT_DELETE',$user);
    +		//  if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
    +		//  // End call triggers
    +		//}
     
     		// If you need to delete child tables to, you can insert them here
     
    @@ -468,7 +462,6 @@ class Ctyperesource
     		$this->label = '';
     		$this->active = '';
     	}
    -
     }
     
     /**
    @@ -480,16 +473,20 @@ class CtyperesourceLine
     	 * @var int ID
     	 */
     	public $id;
    +
     	/**
     	 * @var mixed Sample line property 1
     	 */
    -
     	public $code;
    -	public $label;
    +
    +	/**
    +     * @var string Type resource line label
    +     */
    +    public $label;
    +
     	public $active;
     
     	/**
     	 * @var mixed Sample line property 2
     	 */
    -
     }
    diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php
    index e3098911418..26a5dfe9fb1 100644
    --- a/htdocs/core/class/discount.class.php
    +++ b/htdocs/core/class/discount.class.php
    @@ -28,23 +28,66 @@
      */
     class DiscountAbsolute
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
    -    public $error;
     
    -    public $id;					// Id discount
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error;
    +
    +	/**
    +	 * @var string[]	Array of error strings
    +	 */
    +	public $errors=array();
    +
    +	/**
    +	 * @var int ID discount
    +	 */
    +	public $id;
    +
    +    /**
    +	 * @var int Thirdparty ID
    +	 */
         public $fk_soc;
    +
         public $discount_type;			// 0 => customer discount, 1 => supplier discount
         public $amount_ht;				//
         public $amount_tva;			//
         public $amount_ttc;			//
         public $tva_tx;				// Vat rate
    -    public $fk_user;				// Id utilisateur qui accorde la remise
    -    public $description;			// Description libre
    +
    +    /**
    +	 * @var int User ID Id utilisateur qui accorde la remise
    +	 */
    +	public $fk_user;
    +
    +    /**
    +	 * @var string description
    +	 */
    +	public $description;
    +
         public $datec;					// Date creation
    -    public $fk_facture_line;  		// Id invoice line when a discount is used into an invoice line (for absolute discounts)
    -    public $fk_facture;			    // Id invoice when a discount line is used into an invoice (for credit note)
    -    public $fk_facture_source;		// Id facture avoir a l'origine de la remise
    -    public $ref_facture_source;	    // Ref facture avoir a l'origine de la remise
    +
    +    /**
    +     * @var int ID invoice line when a discount is used into an invoice line (for absolute discounts)
    +     */
    +    public $fk_facture_line;
    +
    +    /**
    +     * @var int ID invoice when a discount line is used into an invoice (for credit note)
    +     */
    +    public $fk_facture;
    +
    +    /**
    +     * @var int ID credit note having caused the discount
    +     */
    +    public $fk_facture_source;
    +
    +    public $ref_facture_source;	    // Ref credit note having caused the discount
    +
         public $ref_invoice_supplier_source;
     
         /**
    @@ -343,6 +386,7 @@ class DiscountAbsolute
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Link the discount to a particular invoice line or a particular invoice.
          *	When discount is a global discount used as an invoice line, we link using rowidline.
    @@ -354,6 +398,7 @@ class DiscountAbsolute
          */
         function link_to_invoice($rowidline,$rowidinvoice)
         {
    +        // phpcs:enable
             // Check parameters
             if (! $rowidline && ! $rowidinvoice)
             {
    @@ -397,6 +442,7 @@ class DiscountAbsolute
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Link the discount to a particular invoice line or a particular invoice.
          *	Do not call this if discount is linked to a reconcialiated invoice
    @@ -405,6 +451,7 @@ class DiscountAbsolute
          */
         function unlink_invoice()
         {
    +        // phpcs:enable
             $sql ="UPDATE ".MAIN_DB_PREFIX."societe_remise_except";
     		if(! empty($this->discount_type)) {
            		$sql.=" SET fk_invoice_supplier_line = NULL, fk_invoice_supplier = NULL";
    @@ -520,11 +567,11 @@ class DiscountAbsolute
         }
     
         /**
    -     *  Return amount (with tax) of all credit notes and deposits invoices used by invoice as a payment
    +     *  Return amount (with tax) of all credit notes invoices + excess received used by invoice as a payment
          *
          *	@param		CommonInvoice	  $invoice	    	Object invoice
     	 *	@param		int			      $multicurrency	Return multicurrency_amount instead of amount
    -     *	@return		int					        		<0 if KO, Sum of credit notes and deposits amount otherwise
    +     *	@return		int					        		<0 if KO, Sum of credit notes and excess received amount otherwise
          */
         function getSumCreditNotesUsed($invoice, $multicurrency=0)
         {
    diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php
    index 860d89afea8..548721be05f 100644
    --- a/htdocs/core/class/doleditor.class.php
    +++ b/htdocs/core/class/doleditor.class.php
    @@ -135,9 +135,9 @@ class DolEditor
                 $this->height				= $height;
                 $this->width				= $width;
         	}
    -
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Output edit area inside the HTML stream.
          *	Output depends on this->tool (fckeditor, ckeditor, textarea, ...)
    @@ -151,6 +151,7 @@ class DolEditor
          */
         function Create($noprint=0, $morejs='', $disallowAnyContent=true, $titlecontent='', $option='')
         {
    +        // phpcs:enable
         	global $conf,$langs;
     
         	$fullpage=false;
    @@ -345,6 +346,4 @@ class DolEditor
             if ($noprint) return $out;
             else print $out;
         }
    -
     }
    -
    diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php
    index b002c96f081..195bec09daf 100644
    --- a/htdocs/core/class/dolgraph.class.php
    +++ b/htdocs/core/class/dolgraph.class.php
    @@ -39,42 +39,46 @@
      */
     class DolGraph
     {
    -	var $type=array();			// Array with type of each series. Example: array('bars', 'lines', ...)
    -	var $mode='side';		    // Mode bars graph: side, depth
    +	public $type=array();			// Array with type of each series. Example: array('bars', 'lines', ...)
    +	public $mode='side';		    // Mode bars graph: side, depth
     	private $_library='jflot';	// Graphic library to use (jflot, artichow)
     
     	//! Array of data
    -	var $data;				// Data of graph: array(array('abs1',valA1,valB1), array('abs2',valA2,valB2), ...)
    -	var $title;				// Title of graph
    -	var $cssprefix='';		// To add into css styles
    -	var $width=380;
    -	var $height=200;
    -	var $MaxValue=0;
    -	var $MinValue=0;
    -	var $SetShading=0;
    +	public $data;				// Data of graph: array(array('abs1',valA1,valB1), array('abs2',valA2,valB2), ...)
    +	public $title;				// Title of graph
    +	public $cssprefix='';		// To add into css styles
    +	public $width=380;
    +	public $height=200;
    +	public $MaxValue=0;
    +	public $MinValue=0;
    +	public $SetShading=0;
     
    -	var $PrecisionY=-1;
    +	public $PrecisionY=-1;
     
    -	var $horizTickIncrement=-1;
    -	var $SetNumXTicks=-1;
    -	var $labelInterval=-1;
    +	public $horizTickIncrement=-1;
    +	public $SetNumXTicks=-1;
    +	public $labelInterval=-1;
     
    -	var $hideXGrid=false;
    -	var $hideYGrid=false;
    +	public $hideXGrid=false;
    +	public $hideYGrid=false;
     
    -	var $Legend=array();
    -	var $LegendWidthMin=0;
    -	var $showlegend=1;
    -	var $showpointvalue=1;
    -	var $showpercent=0;
    -	var $combine=0;				// 0.05 if you want to combine records < 5% into "other"
    -	var $graph;     			// Objet Graph (Artichow, Phplot...)
    -	var $error;
    +	public $Legend=array();
    +	public $LegendWidthMin=0;
    +	public $showlegend=1;
    +	public $showpointvalue=1;
    +	public $showpercent=0;
    +	public $combine=0;				// 0.05 if you want to combine records < 5% into "other"
    +	public $graph;     			// Objet Graph (Artichow, Phplot...)
     
    -	var $bordercolor;			// array(R,G,B)
    -	var $bgcolor;				// array(R,G,B)
    -	var $bgcolorgrid=array(255,255,255);			// array(R,G,B)
    -	var $datacolor;				// array(array(R,G,B),...)
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	public $bordercolor;			// array(R,G,B)
    +	public $bgcolor;				// array(R,G,B)
    +	public $bgcolorgrid=array(255,255,255);			// array(R,G,B)
    +	public $datacolor;				// array(array(R,G,B),...)
     
     	private $stringtoshow;      // To store string to output graph into HTML page
     
    @@ -124,6 +128,7 @@ class DolGraph
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set Y precision
     	 *
    @@ -132,10 +137,12 @@ class DolGraph
     	 */
     	function SetPrecisionY($which_prec)
     	{
    +        // phpcs:enable
     		$this->PrecisionY = $which_prec;
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
     	 *
    @@ -144,10 +151,12 @@ class DolGraph
     	 */
     	function SetHorizTickIncrement($xi)
     	{
    +        // phpcs:enable
     		$this->horizTickIncrement = $xi;
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
     	 *
    @@ -156,10 +165,12 @@ class DolGraph
     	 */
     	function SetNumXTicks($xt)
     	{
    +        // phpcs:enable
     		$this->SetNumXTicks = $xt;
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set label interval to reduce number of labels
     	 *
    @@ -168,10 +179,12 @@ class DolGraph
     	 */
     	function SetLabelInterval($x)
     	{
    +        // phpcs:enable
     		$this->labelInterval = $x;
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Hide X grid
     	 *
    @@ -180,10 +193,12 @@ class DolGraph
     	 */
     	function SetHideXGrid($bool)
     	{
    +        // phpcs:enable
     		$this->hideXGrid = $bool;
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Hide Y grid
     	 *
    @@ -192,10 +207,12 @@ class DolGraph
     	 */
     	function SetHideYGrid($bool)
     	{
    +        // phpcs:enable
     		$this->hideYGrid = $bool;
     		return true;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set y label
     	 *
    @@ -204,9 +221,11 @@ class DolGraph
     	 */
     	function SetYLabel($label)
     	{
    +        // phpcs:enable
     		$this->YLabel = $label;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set width
     	 *
    @@ -215,9 +234,11 @@ class DolGraph
     	 */
     	function SetWidth($w)
     	{
    +        // phpcs:enable
     		$this->width = $w;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set title
     	 *
    @@ -226,9 +247,11 @@ class DolGraph
     	 */
     	function SetTitle($title)
     	{
    +        // phpcs:enable
     		$this->title = $title;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set data
     	 *
    @@ -238,9 +261,11 @@ class DolGraph
     	 */
     	function SetData($data)
     	{
    +        // phpcs:enable
     		$this->data = $data;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set data
     	 *
    @@ -249,9 +274,11 @@ class DolGraph
     	 */
     	function SetDataColor($datacolor)
     	{
    +        // phpcs:enable
     		$this->datacolor = $datacolor;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set type
     	 *
    @@ -260,9 +287,11 @@ class DolGraph
     	 */
     	function SetType($type)
     	{
    +        // phpcs:enable
     		$this->type = $type;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set legend
     	 *
    @@ -271,9 +300,11 @@ class DolGraph
     	 */
     	function SetLegend($legend)
     	{
    +        // phpcs:enable
     		$this->Legend = $legend;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set min width
     	 *
    @@ -282,9 +313,11 @@ class DolGraph
     	 */
     	function SetLegendWidthMin($legendwidthmin)
     	{
    +        // phpcs:enable
     		$this->LegendWidthMin = $legendwidthmin;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set max value
     	 *
    @@ -293,9 +326,11 @@ class DolGraph
     	 */
     	function SetMaxValue($max)
     	{
    +        // phpcs:enable
     		$this->MaxValue = $max;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get max value
     	 *
    @@ -303,9 +338,11 @@ class DolGraph
     	 */
     	function GetMaxValue()
     	{
    +        // phpcs:enable
     		return $this->MaxValue;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set min value
     	 *
    @@ -314,9 +351,11 @@ class DolGraph
     	 */
     	function SetMinValue($min)
     	{
    +        // phpcs:enable
     		$this->MinValue = $min;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get min value
     	 *
    @@ -324,9 +363,11 @@ class DolGraph
     	 */
     	function GetMinValue()
     	{
    +        // phpcs:enable
     		return $this->MinValue;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set height
     	 *
    @@ -335,9 +376,11 @@ class DolGraph
     	 */
     	function SetHeight($h)
     	{
    +        // phpcs:enable
     		$this->height = $h;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set shading
     	 *
    @@ -346,9 +389,11 @@ class DolGraph
     	 */
     	function SetShading($s)
     	{
    +        // phpcs:enable
     		$this->SetShading = $s;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set shading
     	 *
    @@ -357,9 +402,11 @@ class DolGraph
     	 */
     	function SetCssPrefix($s)
     	{
    +        // phpcs:enable
     		$this->cssprefix = $s;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Reset bg color
     	 *
    @@ -367,9 +414,11 @@ class DolGraph
     	 */
     	function ResetBgColor()
     	{
    +        // phpcs:enable
     		unset($this->bgcolor);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Reset bgcolorgrid
     	 *
    @@ -377,6 +426,7 @@ class DolGraph
     	 */
     	function ResetBgColorGrid()
     	{
    +        // phpcs:enable
     		unset($this->bgcolorgrid);
     	}
     
    @@ -425,6 +475,7 @@ class DolGraph
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Define background color of complete image
     	 *
    @@ -433,6 +484,7 @@ class DolGraph
     	 */
     	function SetBgColor($bg_color = array(255,255,255))
     	{
    +        // phpcs:enable
     		global $theme_bgcolor,$theme_bgcoloronglet;
     
     		if (! is_array($bg_color))
    @@ -453,6 +505,7 @@ class DolGraph
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Define background color of grid
     	 *
    @@ -461,6 +514,7 @@ class DolGraph
     	 */
     	function SetBgColorGrid($bg_colorgrid = array(255,255,255))
     	{
    +        // phpcs:enable
     		global $theme_bgcolor,$theme_bgcoloronglet;
     
     		if (! is_array($bg_colorgrid))
    @@ -481,6 +535,7 @@ class DolGraph
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Reset data color
     	 *
    @@ -488,9 +543,11 @@ class DolGraph
     	 */
     	function ResetDataColor()
     	{
    +        // phpcs:enable
     		unset($this->datacolor);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get max value
     	 *
    @@ -498,6 +555,7 @@ class DolGraph
     	 */
     	function GetMaxValueInData()
     	{
    +        // phpcs:enable
     		$k = 0;
     		$vals = array();
     
    @@ -516,6 +574,7 @@ class DolGraph
     		return $vals[0];
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return min value of all data
     	 *
    @@ -523,6 +582,7 @@ class DolGraph
     	 */
     	function GetMinValueInData()
     	{
    +        // phpcs:enable
     		$k = 0;
     		$vals = array();
     
    @@ -541,6 +601,7 @@ class DolGraph
     		return $vals[0];
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return max value of all data
     	 *
    @@ -548,6 +609,7 @@ class DolGraph
     	 */
     	function GetCeilMaxValue()
     	{
    +        // phpcs:enable
     		$max = $this->GetMaxValueInData();
     		if ($max != 0) $max++;
     		$size=dol_strlen(abs(ceil($max)));
    @@ -564,6 +626,7 @@ class DolGraph
     		return $res;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return min value of all data
     	 *
    @@ -571,6 +634,7 @@ class DolGraph
     	 */
     	function GetFloorMinValue()
     	{
    +        // phpcs:enable
     		$min = $this->GetMinValueInData();
     		if ($min == '') $min=0;
     		if ($min != 0) $min--;
    @@ -618,6 +682,7 @@ class DolGraph
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 * Build a graph onto disk using Artichow library and return img string to it
     	 *
    @@ -627,6 +692,7 @@ class DolGraph
     	 */
     	private function draw_artichow($file,$fileurl)
     	{
    +        // phpcs:enable
     		global $artichow_defaultfont;
     
     		dol_syslog(get_class($this)."::draw_artichow this->type=".join(',',$this->type));
    @@ -638,7 +704,7 @@ class DolGraph
     		// Create graph
     		$classname='';
     		if (! isset($this->type[0]) || $this->type[0] == 'bars')  $classname='BarPlot';    // Only one type (first one) is supported by artichow
    -		else if ($this->type[0] == 'lines') $classname='LinePlot';
    +		else if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint') $classname='LinePlot';
     		else $classname='TypeUnknown';
     		include_once ARTICHOW_PATH.$classname.'.class.php';
     
    @@ -743,7 +809,7 @@ class DolGraph
     				$plot->SetYMin($this->MinValue);
     			}
     
    -			if ($this->type[0] == 'lines')
    +			if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint')
     			{
     				$color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
     				$colorbis=new Color(min($this->datacolor[$i][0]+20,255),min($this->datacolor[$i][1]+20,255),min($this->datacolor[$i][2]+20,255),60);
    @@ -774,8 +840,8 @@ class DolGraph
     			// solve a bug in Artichow with UTF8
     			if (count($this->Legend))
     			{
    -				if ($this->type[0] == 'bars')  $group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND);
    -				if ($this->type[0] == 'lines') $group->legend->add($plot, $this->Legend[$i], LEGEND_LINE);
    +				if ($this->type[0] == 'bars')  										$group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND);
    +				if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint')	$group->legend->add($plot, $this->Legend[$i], LEGEND_LINE);
     			}
     			$group->add($plot);
     
    @@ -797,6 +863,7 @@ class DolGraph
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 * Build a graph using JFlot library. Input when calling this method should be:
     	 *	$this->data  = array(array(0=>'labelxA',1=>yA),  array('labelxB',yB));
    @@ -813,8 +880,9 @@ class DolGraph
     	 * @param	string	$fileurl	Url path to show image if saved onto disk. Never used here.
     	 * @return	void
     	 */
    -	private function draw_jflot($file,$fileurl)
    +	private function draw_jflot($file, $fileurl)
     	{
    +        // phpcs:enable
     		global $artichow_defaultfont;
     
     		dol_syslog(get_class($this)."::draw_jflot this->type=".join(',',$this->type)." this->MaxValue=".$this->MaxValue);
    @@ -959,19 +1027,22 @@ class DolGraph
     		else
     		{
     			// Add code to support tooltips
    +		    // TODO: remove js css and use graph-tooltip-inner class instead by adding css in each themes
     			$this->stringtoshow.='
     			function showTooltip_'.$tag.'(x, y, contents) {
    -				$(\'<div id="tooltip_'.$tag.'">\' + contents + \'</div>\').css({
    +				$(\'<div class="graph-tooltip-inner" id="tooltip_'.$tag.'">\' + contents + \'</div>\').css({
     					position: \'absolute\',
     					display: \'none\',
    -					top: y + 5,
    -					left: x + 5,
    -					border: \'1px solid #ddd\',
    -					padding: \'2px\',
    -					\'background-color\': \'#ffe\',
    +					top: y + 10,
    +					left: x + 15,
    +					border: \'1px solid #000\',
    +					padding: \'5px\',
    +					\'background-color\': \'#000\',
    +					\'color\': \'#fff\',
    +					\'font-weight\': \'bold\',
     					width: 200,
     					opacity: 0.80
    -				}).appendTo("body").fadeIn(20);
    +				}).appendTo("body").fadeIn(100);
     			}
     
     			var previousPoint = null;
    @@ -1012,12 +1083,13 @@ class DolGraph
     				if ($i > $firstlot) $this->stringtoshow.=', '."\n";
     				$color=sprintf("%02x%02x%02x",$this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2]);
     				$this->stringtoshow.='{ ';
    -				if (! isset($this->type[$i]) || $this->type[$i] == 'bars') $this->stringtoshow.='bars: { show: true, align: "'.($i==$firstlot?'center':'left').'", barWidth: 0.5 }, ';
    -				if (isset($this->type[$i]) && $this->type[$i] == 'lines')  $this->stringtoshow.='lines: { show: true, fill: false }, ';
    +				if (! isset($this->type[$i]) || $this->type[$i] == 'bars') $this->stringtoshow.='bars: { lineWidth: 1, show: true, align: "'.($i==$firstlot?'center':'left').'", barWidth: 0.5 }, ';
    +				if (isset($this->type[$i]) && ($this->type[$i] == 'lines' || $this->type[$i] == 'linesnopoint')) $this->stringtoshow.='lines: { show: true, fill: false }, points: { show: '.($this->type[$i] == 'linesnopoint' ? 'false' : 'true').' }, ';
     				$this->stringtoshow.='color: "#'.$color.'", label: "'.(isset($this->Legend[$i]) ? dol_escape_js($this->Legend[$i]) : '').'", data: d'.$i.' }';
     				$i++;
     			}
    -			$this->stringtoshow.="\n".' ], { series: { stack: stack, lines: { fill: false, steps: steps }, bars: { barWidth: 0.6 } }'."\n";
    +			// shadowSize: 0 -> Drawing is faster without shadows
    +			$this->stringtoshow.="\n".' ], { series: { shadowSize: 0, stack: stack, lines: { fill: false, steps: steps }, bars: { barWidth: 0.6 } }'."\n";
     
     			// Xaxis
     			$this->stringtoshow.=', xaxis: { ticks: ['."\n";
    @@ -1036,11 +1108,10 @@ class DolGraph
     			// Background color
     			$color1=sprintf("%02x%02x%02x",$this->bgcolorgrid[0],$this->bgcolorgrid[0],$this->bgcolorgrid[2]);
     			$color2=sprintf("%02x%02x%02x",$this->bgcolorgrid[0],$this->bgcolorgrid[1],$this->bgcolorgrid[2]);
    -			$this->stringtoshow.=', grid: { hoverable: true, backgroundColor: { colors: ["#'.$color1.'", "#'.$color2.'"] } }'."\n";
    +			$this->stringtoshow.=', grid: { hoverable: true, backgroundColor: { colors: ["#'.$color1.'", "#'.$color2.'"] }, borderWidth: 1, borderColor: \'#eee\', tickColor  : \'#f3f3f3\' }'."\n";
     			//$this->stringtoshow.=', shadowSize: 20'."\n";    TODO Uncommet this
     			$this->stringtoshow.='});'."\n";
     			$this->stringtoshow.='}'."\n";
    -
     		}
     
     		$this->stringtoshow.='plotWithOptions_'.$tag.'();'."\n";
    @@ -1093,6 +1164,4 @@ class DolGraph
     		}
     		return 0;
     	}
    -
     }
    -
    diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php
    index 2499176b58b..f38afc67807 100644
    --- a/htdocs/core/class/dolreceiptprinter.class.php
    +++ b/htdocs/core/class/dolreceiptprinter.class.php
    @@ -1,6 +1,6 @@
     <?php
     /*
    - * Copyright (C) 2015       Frederic France     <frederic.france@free.fr>
    + * Copyright (C) 2015-2018  Frédéric France     <frederic.france@free.fr>
      *
      * 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
    @@ -45,7 +45,7 @@
      * <dol_cut_paper_partial>                          Cut ticket partially
      * <dol_open_drawer>                                Open cash drawer
      * <dol_activate_buzzer>                            Activate buzzer
    - * 
    + *
      * Code which can be placed everywhere
      * <dol_print_qrcode>                               Print QR Code
      * <dol_print_date>                                 Print date AAAA-MM-DD
    @@ -94,7 +94,7 @@
     
     require_once DOL_DOCUMENT_ROOT .'/includes/mike42/escpos-php/Escpos.php';
     
    - 
    +
     /**
      * Class to manage Receipt Printers
      */
    @@ -105,12 +105,25 @@ class dolReceiptPrinter extends Escpos
         const CONNECTOR_NETWORK_PRINT = 3;
         const CONNECTOR_WINDOWS_PRINT = 4;
         //const CONNECTOR_JAVA = 5;
    -    var $db;
    +
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
         var $tags;
         var $printer;
         var $template;
    -    var $error;
    -    var $errors;
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error='';
    +
    +    /**
    +     * @var string[] Error codes (or messages)
    +     */
    +    public $errors = array();
     
     
     
    @@ -191,7 +204,6 @@ class dolReceiptPrinter extends Escpos
                 'dol_print_if_customer_tax_number',
                 'dol_print_if_customer_account_balance_positive',
             );
    -
         }
     
         /**
    @@ -204,6 +216,7 @@ class dolReceiptPrinter extends Escpos
             global $conf;
             $error = 0;
             $line = 0;
    +        $obj = array();
             $sql = 'SELECT rowid, name, fk_type, fk_profile, parameter';
             $sql.= ' FROM '.MAIN_DB_PREFIX.'printer_receipt';
             $sql.= ' WHERE entity = '.$conf->entity;
    @@ -271,6 +284,7 @@ class dolReceiptPrinter extends Escpos
             global $conf;
             $error = 0;
             $line = 0;
    +        $obj = array();
             $sql = 'SELECT rowid, name, template';
             $sql.= ' FROM '.MAIN_DB_PREFIX.'printer_receipt_template';
             $sql.= ' WHERE entity = '.$conf->entity;
    @@ -300,16 +314,16 @@ class dolReceiptPrinter extends Escpos
         function selectTypePrinter($selected='', $htmlname='printertypeid')
         {
             global $langs;
    -        
    +
             $options = array(
                 1 => $langs->trans('CONNECTOR_DUMMY'),
                 2 => $langs->trans('CONNECTOR_FILE_PRINT'),
                 3 => $langs->trans('CONNECTOR_NETWORK_PRINT'),
                 4 => $langs->trans('CONNECTOR_WINDOWS_PRINT')
             );
    -        
    +
             $this->resprint = Form::selectarray($htmlname, $options, $selected);
    -        
    +
             return 0;
         }
     
    @@ -324,7 +338,7 @@ class dolReceiptPrinter extends Escpos
         function selectProfilePrinter($selected='', $htmlname='printerprofileid')
         {
             global $langs;
    -        
    +
             $options = array(
                 0 => $langs->trans('PROFILE_DEFAULT'),
                 1 => $langs->trans('PROFILE_SIMPLE'),
    @@ -332,12 +346,13 @@ class dolReceiptPrinter extends Escpos
                 3 => $langs->trans('PROFILE_P822D'),
                 4 => $langs->trans('PROFILE_STAR')
             );
    -        
    +
             $this->profileresprint = Form::selectarray($htmlname, $options, $selected);
             return 0;
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to Add a printer in db
          *
    @@ -349,6 +364,7 @@ class dolReceiptPrinter extends Escpos
          */
         function AddPrinter($name, $type, $profile, $parameter)
         {
    +        // phpcs:enable
             global $conf;
             $error = 0;
             $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'printer_receipt';
    @@ -362,6 +378,7 @@ class dolReceiptPrinter extends Escpos
             return $error;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to Update a printer in db
          *
    @@ -374,6 +391,7 @@ class dolReceiptPrinter extends Escpos
          */
         function UpdatePrinter($name, $type, $profile, $parameter, $printerid)
         {
    +        // phpcs:enable
             global $conf;
             $error = 0;
             $sql = 'UPDATE '.MAIN_DB_PREFIX.'printer_receipt';
    @@ -390,6 +408,7 @@ class dolReceiptPrinter extends Escpos
             return $error;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to Delete a printer from db
          *
    @@ -398,6 +417,7 @@ class dolReceiptPrinter extends Escpos
          */
         function DeletePrinter($printerid)
         {
    +        // phpcs:enable
             global $conf;
             $error = 0;
             $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'printer_receipt';
    @@ -410,6 +430,7 @@ class dolReceiptPrinter extends Escpos
             return $error;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to Update a printer template in db
          *
    @@ -420,6 +441,7 @@ class dolReceiptPrinter extends Escpos
          */
         function UpdateTemplate($name, $template, $templateid)
         {
    +        // phpcs:enable
             global $conf;
             $error = 0;
             $sql = 'UPDATE '.MAIN_DB_PREFIX.'printer_receipt_template';
    @@ -435,6 +457,7 @@ class dolReceiptPrinter extends Escpos
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to Send Test page to Printer
          *
    @@ -443,6 +466,7 @@ class dolReceiptPrinter extends Escpos
          */
         function SendTestToPrinter($printerid)
         {
    +        // phpcs:enable
             global $conf;
             $error = 0;
             $img = new EscposImage(DOL_DOCUMENT_ROOT .'/theme/common/dolibarr_logo_bw.png');
    @@ -460,7 +484,6 @@ class dolReceiptPrinter extends Escpos
                     $this->printer->cut();
                     //print '<pre>'.print_r($this->connector, true).'</pre>';
                     $this->printer->close();
    -
                 } catch (Exception $e) {
                     $this->errors[] = $e->getMessage();
                     $error++;
    @@ -469,6 +492,7 @@ class dolReceiptPrinter extends Escpos
             return $error;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to Print Receipt Ticket
          *
    @@ -479,6 +503,7 @@ class dolReceiptPrinter extends Escpos
          */
         function SendToPrinter($object, $templateid, $printerid)
         {
    +        // phpcs:enable
             global $conf;
             $error = 0;
             $ret = $this->loadTemplate($templateid);
    @@ -520,11 +545,11 @@ class dolReceiptPrinter extends Escpos
             $ret = $this->InitPrinter($printerid);
             if ($ret>0) {
                 setEventMessages($this->error, $this->errors, 'errors');
    -        } 
    -        else 
    +        }
    +        else
             {
                 $nboflines = count($vals);
    -            for ($line=0; $line < $nboflines; $line++) 
    +            for ($line=0; $line < $nboflines; $line++)
                 {
                     switch ($vals[$line]['tag']) {
                         case 'DOL_ALIGN_CENTER':
    @@ -595,7 +620,6 @@ class dolReceiptPrinter extends Escpos
                 // uncomment next line to see content sent to printer
                 //print '<pre>'.print_r($this->connector, true).'</pre>';
                 $this->printer->close();
    -
             }
             return $error;
         }
    @@ -632,6 +656,7 @@ class dolReceiptPrinter extends Escpos
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function Init Printer
          *
    @@ -640,6 +665,7 @@ class dolReceiptPrinter extends Escpos
          */
         function InitPrinter($printerid)
         {
    +        // phpcs:enable
             global $conf;
             $error=0;
             $sql = 'SELECT rowid, name, fk_type, fk_profile, parameter';
    diff --git a/htdocs/core/class/emailsenderprofile.class.php b/htdocs/core/class/emailsenderprofile.class.php
    index 7f34165030b..b30f79f0bba 100644
    --- a/htdocs/core/class/emailsenderprofile.class.php
    +++ b/htdocs/core/class/emailsenderprofile.class.php
    @@ -39,14 +39,17 @@ class EmailSenderProfile extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'emailsenderprofile';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'c_email_senderprofile';
    +
     	/**
     	 * @var array  Does emailsenderprofile support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * @var string String with name of icon for emailsenderprofile
     	 */
    @@ -85,9 +88,22 @@ class EmailSenderProfile extends CommonObject
     		'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-1, 'enabled'=>1, 'position'=>500, 'notnull'=>1,),
     		'active' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1),
     	);
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    -	public $label;
    +
    +	/**
    +     * @var string Email Sender Profile label
    +     */
    +    public $label;
    +
     	public $email;
     	public $date_creation;
     	public $tms;
    @@ -307,6 +323,7 @@ class EmailSenderProfile extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -318,38 +335,32 @@ class EmailSenderProfile extends CommonObject
     	{
     		global $langs;
     
    -		if ($mode == 0)
    -		{
    -			$prefix='';
    -			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    -		}
    -		if ($mode == 1)
    +		if ($mode == 0 || $mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
     			if ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    @@ -402,7 +413,6 @@ class EmailSenderProfile extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -420,7 +430,6 @@ class EmailSenderProfile extends CommonObject
     	{
     		$this->initAsSpecimenCommon();
     	}
    -
     }
     
     /**
    diff --git a/htdocs/core/class/events.class.php b/htdocs/core/class/events.class.php
    index abdbb1689f8..020998fa37a 100644
    --- a/htdocs/core/class/events.class.php
    +++ b/htdocs/core/class/events.class.php
    @@ -30,29 +30,55 @@
     
     
     /**
    - *	Events class
    + *  Events class
      */
     class Events // extends CommonObject
     {
    -	public $element='events';				//!< Id that identify managed objects
    -	public $table_element='events';		//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='events';
     
    -	var $id;
    -	var $db;
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='events';
     
    -	var $error;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $tms;
    -	var $type;
    -	var $entity;
    -	var $dateevent;
    -	var $description;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	public $tms;
    +	public $type;
    +
    +	/**
    +	 * @var int Entity
    +	 */
    +	public $entity;
    +
    +	public $dateevent;
    +
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
     
     	// List of all Audit/Security events supported by triggers
    -	var $eventstolog=array(
    -		array('id'=>'USER_LOGIN',             'test'=>1),
    +	public $eventstolog=array(
    +		/*array('id'=>'USER_LOGIN',             'test'=>1),
     		array('id'=>'USER_LOGIN_FAILED',      'test'=>1),
    -	    array('id'=>'USER_LOGOUT',            'test'=>1),
    +	    array('id'=>'USER_LOGOUT',            'test'=>1),*/
     		array('id'=>'USER_CREATE',            'test'=>1),
     		array('id'=>'USER_MODIFY',            'test'=>1),
     		array('id'=>'USER_NEW_PASSWORD',      'test'=>1),
    @@ -96,7 +122,6 @@ class Events // extends CommonObject
     	function __construct($db)
     	{
     		$this->db = $db;
    -		return 1;
     	}
     
     
    @@ -280,5 +305,4 @@ class Events // extends CommonObject
     		$this->dateevent=time();
     		$this->description='This is a specimen event';
     	}
    -
     }
    diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
    index 1840f62ca5d..9ebdbd22836 100644
    --- a/htdocs/core/class/extrafields.class.php
    +++ b/htdocs/core/class/extrafields.class.php
    @@ -9,6 +9,7 @@
      * Copyright (C) 2015       Charles-Fr BENKE        <charles.fr@benke.fr>
      * Copyright (C) 2016       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2017       Nicolas ZABOURI         <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -36,7 +37,10 @@
      */
     class ExtraFields
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	// type of element (for what object is the extrafield)
     	// @deprecated
    @@ -87,7 +91,11 @@ class ExtraFields
     	// New array to store extrafields definition
     	var $attributes;
     
    -	var $error;
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
     	var $errno;
     
     
    @@ -156,14 +164,14 @@ class ExtraFields
     	 *  @param  int				$alwayseditable		Is attribute always editable regardless of the document status
     	 *  @param	string			$perms				Permission to check
     	 *  @param	string			$list				Visibilty ('0'=never visible, '1'=visible on list+forms, '2'=list only, '3'=form only or 'eval string')
    -	 *  @param	int				$notused			Deprecated.
    +	 *  @param	string			$help				Text with help tooltip
     	 *  @param  string  		$computed           Computed value
     	 *  @param  string  		$entity    		 	Entity of extrafields (for multicompany modules)
     	 *  @param  string  		$langfile  		 	Language file
     	 *  @param  string  		$enabled  		 	Condition to have the field enabled or not
     	 *  @return int      							<=0 if KO, >0 if OK
     	 */
    -	function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list='-1', $notused=0, $computed='', $entity='', $langfile='', $enabled='1')
    +	function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list='-1', $help='', $computed='', $entity='', $langfile='', $enabled='1')
     	{
     		if (empty($attrname)) return -1;
     		if (empty($label)) return -1;
    @@ -174,13 +182,13 @@ class ExtraFields
     		// Create field into database except for separator type which is not stored in database
     		if ($type != 'separate')
     		{
    -			$result=$this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list, $computed);
    +			$result=$this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list, $computed, $help);
     		}
     		$err1=$this->errno;
     		if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
     		{
     			// Add declaration of field into table
    -			$result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $notused, $default_value, $computed, $entity, $langfile, $enabled);
    +			$result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled);
     			$err2=$this->errno;
     			if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
     			{
    @@ -285,6 +293,7 @@ class ExtraFields
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 *	Add description of a new optional attribute
     	 *
    @@ -300,7 +309,7 @@ class ExtraFields
     	 *  @param  int				$alwayseditable	Is attribute always editable regardless of the document status
     	 *  @param	string			$perms			Permission to check
     	 *  @param	string			$list			Visibily
    -	 *  @param	int				$notused		Deprecated.
    +	 *  @param	string			$help			Help on tooltip
     	 *  @param  string          $default        Default value (in database. use the default_value feature for default value on screen).
     	 *  @param  string          $computed       Computed value
     	 *  @param  string          $entity     	Entity of extrafields
    @@ -308,8 +317,9 @@ class ExtraFields
     	 *  @param  string  		$enabled  		Condition to have the field enabled or not
     	 *  @return	int								<=0 if KO, >0 if OK
     	 */
    -	private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list='-1', $notused=0, $default='', $computed='',$entity='', $langfile='', $enabled='1')
    +	private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list='-1', $help='', $default='', $computed='',$entity='', $langfile='', $enabled='1')
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		if ($elementtype == 'thirdparty') $elementtype='societe';
    @@ -357,7 +367,8 @@ class ExtraFields
     			$sql.= " fk_user_author,";
     			$sql.= " fk_user_modif,";
     			$sql.= " datec,";
    -			$sql.= " enabled";
    +			$sql.= " enabled,";
    +			$sql.= " help";
     			$sql.= " )";
     			$sql.= " VALUES('".$attrname."',";
     			$sql.= " '".$this->db->escape($label)."',";
    @@ -378,7 +389,8 @@ class ExtraFields
     			$sql .= " " . (is_object($user) ? $user->id : 0). ",";
     			$sql .= " " . (is_object($user) ? $user->id : 0). ",";
     			$sql .= "'" . $this->db->idate(dol_now()) . "',";
    -			$sql.= " ".($enabled?"'".$this->db->escape($enabled)."'":"1");
    +			$sql.= " ".($enabled?"'".$this->db->escape($enabled)."'":"1").",";
    +			$sql.= " ".($help?"'".$this->db->escape($help)."'":"null");
     			$sql.=')';
     
     			dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
    @@ -450,9 +462,9 @@ class ExtraFields
     		{
     			return 0;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 *	Delete description of an optional attribute
     	 *
    @@ -462,6 +474,7 @@ class ExtraFields
     	 */
     	private function delete_label($attrname, $elementtype='member')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if ($elementtype == 'thirdparty') $elementtype='societe';
    @@ -490,7 +503,6 @@ class ExtraFields
     		{
     			return 0;
     		}
    -
     	}
     
     	/**
    @@ -508,20 +520,21 @@ class ExtraFields
     	 *  @param  int		$alwayseditable		Is attribute always editable regardless of the document status
     	 *  @param	string	$perms				Permission to check
     	 *  @param	string	$list				Visibility
    -	 *  @param	int		$notused			Deprecated.
    +	 *  @param	string	$help				Help on tooltip
     	 *  @param  string  $default            Default value (in database. use the default_value feature for default value on screen).
     	 *  @param  string  $computed           Computed value
     	 *  @param  string  $entity	            Entity of extrafields
     	 *  @param	string	$langfile			Language file
     	 *  @param  string  $enabled  			Condition to have the field enabled or not
    +     *  @param  int     $totalizable        Is extrafield totalizable on list
     	 * 	@return	int							>0 if OK, <=0 if KO
     	 */
    -	function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $notused=0, $default='', $computed='', $entity='', $langfile='', $enabled='1')
    +	function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $help='', $default='', $computed='', $entity='', $langfile='', $enabled='1', $totalizable=0)
     	{
     		if ($elementtype == 'thirdparty') $elementtype='societe';
     		if ($elementtype == 'contact') $elementtype='socpeople';
     
    -		$table=$elementtype.'_extrafields';
    +        $table=$elementtype.'_extrafields';
     		if ($elementtype == 'categorie') $table='categories_extrafields';
     
     		if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
    @@ -566,7 +579,7 @@ class ExtraFields
     			{
     				if ($label)
     				{
    -					$result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$notused,$default,$computed,$entity,$langfile,$enabled);
    +					$result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$help,$default,$computed,$entity,$langfile,$enabled, $totalizable);
     				}
     				if ($result > 0)
     				{
    @@ -599,9 +612,9 @@ class ExtraFields
     		{
     			return 0;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 *  Modify description of personalized attribute
     	 *
    @@ -617,18 +630,20 @@ class ExtraFields
     	 *  @param  int		$alwayseditable		Is attribute always editable regardless of the document status
     	 *  @param	string	$perms				Permission to check
     	 *  @param	string	$list				Visiblity
    -	 *  @param	int		$notused			Deprecated.
    +	 *  @param	string	$help				Help on tooltip.
     	 *  @param  string  $default            Default value (in database. use the default_value feature for default value on screen).
     	 *  @param  string  $computed           Computed value
     	 *  @param  string  $entity     		Entity of extrafields
     	 *  @param	string	$langfile			Language file
     	 *  @param  string  $enabled  			Condition to have the field enabled or not
    -	 *  @return	int							<=0 if KO, >0 if OK
    +     *  @param  int     $totalizable        Is extrafield totalizable on list
    +     *  @return	int							<=0 if KO, >0 if OK
     	 */
    -	private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list='0',$notused=0,$default='',$computed='',$entity='',$langfile='',$enabled='1')
    +	private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list='0',$help='',$default='',$computed='',$entity='',$langfile='',$enabled='1', $totalizable=0)
     	{
    +        // phpcs:enable
     		global $conf, $user;
    -		dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$notused.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled);
    +		dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable);
     
     		// Clean parameters
     		if ($elementtype == 'thirdparty') $elementtype='societe';
    @@ -636,6 +651,9 @@ class ExtraFields
     
     		if (empty($pos)) $pos=0;
     		if (empty($list)) $list='0';
    +        if (empty($totalizable)) {
    +            $totalizable = 0;
    +        }
     		if (empty($required)) $required=0;
     		if (empty($unique)) $unique=0;
     		if (empty($alwayseditable)) $alwayseditable=0;
    @@ -690,12 +708,14 @@ class ExtraFields
     			$sql.= " alwayseditable,";
     			$sql.= " param,";
     			$sql.= " list,";
    +            $sql.= " totalizable,";
     			$sql.= " fielddefault,";
     			$sql.= " fieldcomputed,";
     			$sql.= " fk_user_author,";
     			$sql.= " fk_user_modif,";
     			$sql.= " datec,";
    -			$sql.= " enabled";
    +			$sql.= " enabled,";
    +			$sql.= " help";
     			$sql.= ") VALUES (";
     			$sql.= "'".$attrname."',";
     			$sql.= " ".($entity===''?$conf->entity:$entity).",";
    @@ -711,12 +731,14 @@ class ExtraFields
     			$sql.= " '".$this->db->escape($alwayseditable)."',";
     			$sql.= " '".$this->db->escape($params)."',";
     			$sql.= " '".$this->db->escape($list)."', ";
    +            $sql.= " ".$totalizable.",";
     			$sql.= " ".(($default!='')?"'".$this->db->escape($default)."'":"null").",";
     			$sql.= " ".($computed?"'".$this->db->escape($computed)."'":"null").",";
     			$sql .= " " . $user->id . ",";
     			$sql .= " " . $user->id . ",";
     			$sql .= "'" . $this->db->idate(dol_now()) . "',";
    -			$sql .= "'" . $this->db->escape($enabled). "'";
    +			$sql .= "'" . $this->db->escape($enabled). "',";
    +			$sql.= " ".($help?"'".$this->db->escape($help)."'":"null");
     			$sql.= ")";
     
     			$resql2=$this->db->query($sql);
    @@ -740,6 +762,7 @@ class ExtraFields
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ...
     	 *
    @@ -749,6 +772,7 @@ class ExtraFields
     	 */
     	function fetch_name_optionals_label($elementtype,$forceload=false)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (empty($elementtype)) return array();
    @@ -781,7 +805,7 @@ class ExtraFields
     		// We should not have several time this log. If we have, there is some optimization to do by calling a simple $object->fetch_optionals() that include cache management.
     		dol_syslog("fetch_name_optionals_label elementtype=".$elementtype);
     
    -		$sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,fielddefault,fieldcomputed,entity,enabled";
    +		$sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,totalizable,fielddefault,fieldcomputed,entity,enabled,help";
     		$sql.= " FROM ".MAIN_DB_PREFIX."extrafields";
     		$sql.= " WHERE entity IN (0,".$conf->entity.")";
     		if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'";	// Filed with object->table_element
    @@ -815,6 +839,7 @@ class ExtraFields
     					$this->attribute_perms[$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
     					$this->attribute_langfile[$tab->name]=$tab->langs;
     					$this->attribute_list[$tab->name]=$tab->list;
    +					$this->attribute_totalizable[$tab->name]=$tab->totalizable;
     					$this->attribute_entityid[$tab->name]=$tab->entity;
     					$this->attribute_entitylabel[$tab->name]=(empty($labelmulticompany[$tab->entity])?'Entity'.$tab->entity:$labelmulticompany[$tab->entity]);
     
    @@ -833,9 +858,11 @@ class ExtraFields
     					$this->attributes[$tab->elementtype]['perms'][$tab->name]=(strlen($tab->perms) == 0 ? 1 : $tab->perms);
     					$this->attributes[$tab->elementtype]['langfile'][$tab->name]=$tab->langs;
     					$this->attributes[$tab->elementtype]['list'][$tab->name]=$tab->list;
    +                    $this->attributes[$tab->elementtype]['totalizable'][$tab->name]=$tab->totalizable;
     					$this->attributes[$tab->elementtype]['entityid'][$tab->name]=$tab->entity;
     					$this->attributes[$tab->elementtype]['entitylabel'][$tab->name]=(empty($labelmulticompany[$tab->entity])?'Entity'.$tab->entity:$labelmulticompany[$tab->entity]);
     					$this->attributes[$tab->elementtype]['enabled'][$tab->name]=$tab->enabled;
    +					$this->attributes[$tab->elementtype]['help'][$tab->name]=$tab->help;
     
     					$this->attributes[$tab->elementtype]['loaded']=1;
     				}
    @@ -893,6 +920,8 @@ class ExtraFields
     			$perms=dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1);
     			$langfile=$this->attributes[$extrafieldsobjectkey]['langfile'][$key];
     			$list=dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1);
    +			$totalizable=$this->attributes[$extrafieldsobjectkey]['totalizable'][$key];
    +			$help=$this->attributes[$extrafieldsobjectkey]['help'][$key];
     			$hidden=(empty($list) ? 1 : 0);		// If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
     		}
     		else	// Old usage
    @@ -908,6 +937,7 @@ class ExtraFields
     			$param=$this->attribute_param[$key];
     			$langfile=$this->attribute_langfile[$key];
     			$list=$this->attribute_list[$key];
    +			$totalizable=$this->attribute_totalizable[$key];
     			$hidden=(empty($list) ? 1 : 0);		// If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller)
     		}
     
    @@ -967,11 +997,11 @@ class ExtraFields
     
     			$showtime = in_array($type,array('datetime')) ? 1 : 0;
     
    -			// Do not show current date when field not required (see select_date() method)
    +			// Do not show current date when field not required (see selectDate() method)
     			if (!$required && $value == '') $value = '-1';
     
     			// TODO Must also support $moreparam
    -			$out = $form->select_date($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 1, 0, 1);
    +			$out = $form->selectDate($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 0, 1);
     		}
     		elseif (in_array($type,array('int','integer')))
     		{
    @@ -1362,7 +1392,6 @@ class ExtraFields
     							}
     
     							$data[$obj->rowid]=$labeltoshow;
    -
     						} else {
     							if (! $notrans) {
     								$translabel = $langs->trans($obj->{$InfoFieldList[1]});
    @@ -1391,7 +1420,6 @@ class ExtraFields
     					$this->db->free($resql);
     
     					$out=$form->multiselectarray($keyprefix.$key.$keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
    -
     				} else {
     					print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
     				}
    @@ -1685,7 +1713,6 @@ class ExtraFields
     					}
     				}
     				$value='<div class="select2-container-multi-dolibarr" style="width: 90%;"><ul class="select2-choices-dolibarr">'.implode(' ', $toprint).'</ul></div>';
    -
     			} else {
     				dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING);
     			}
    @@ -1759,7 +1786,7 @@ class ExtraFields
     
     		$align='';
     
    -		if ($type == 'date')
    +        if ($type == 'date')
     		{
     			$align="center";
     		}
    @@ -1787,6 +1814,10 @@ class ExtraFields
     		{
     			$align="center";
     		}
    +		elseif ($type == 'price')
    +		{
    +			$align="right";
    +		}
     
     		return $align;
     	}
    diff --git a/htdocs/core/class/fiscalyear.class.php b/htdocs/core/class/fiscalyear.class.php
    index 987033d35e3..985d67d5cae 100644
    --- a/htdocs/core/class/fiscalyear.class.php
    +++ b/htdocs/core/class/fiscalyear.class.php
    @@ -16,7 +16,7 @@
      */
     
     /**
    - *      \file       htdocs/core/class/fiscalyear.php
    + *      \file       htdocs/core/class/fiscalyear.class.php
      *		\ingroup    fiscal year
      *		\brief      File of class to manage fiscal years
      */
    @@ -28,23 +28,54 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Fiscalyear extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='fiscalyear';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='accounting_fiscalyear';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line = '';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element = '';
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     
    -	var $rowid;
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
     
    -	var $label;
    -	var $date_start;
    -	var $date_end;
    -	var $datec;
    -	var $statut;		// 0=open, 1=closed
    -	var $entity;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $rowid;
     
    -	var $statuts=array();
    -	var $statuts_short=array();
    +	/**
    +     * @var string fiscal year label
    +     */
    +    public $label;
    +
    +	public $date_start;
    +	public $date_end;
    +	public $datec;
    +	public $statut;		// 0=open, 1=closed
    +
    +	/**
    +	 * @var int Entity
    +	 */
    +	public $entity;
    +
    +	public $statuts=array();
    +	public $statuts_short=array();
     
     	/**
     	 * Constructor
    @@ -56,9 +87,7 @@ class Fiscalyear extends CommonObject
     		$this->db = $db;
     
     		$this->statuts_short = array(0 => 'Opened', 1 => 'Closed');
    -        $this->statuts = array(0 => 'Opened', 1 => 'Closed');
    -
    -		return 1;
    +		$this->statuts = array(0 => 'Opened', 1 => 'Closed');
     	}
     
     	/**
    @@ -238,6 +267,7 @@ class Fiscalyear extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Give a label from a status
     	 *
    @@ -247,35 +277,36 @@ class Fiscalyear extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut8').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut8').' '.$langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    -			if ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut8');
    +			elseif ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut8');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut8').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==1 && ! empty($this->statuts_short[$statut])) return img_picto($langs->trans($this->statuts_short[$statut]),'statut8').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut==0 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
    -			if ($statut==1 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==1 && ! empty($this->statuts_short[$statut])) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
     		}
     	}
     
    @@ -323,5 +354,4 @@ class Fiscalyear extends CommonObject
     			dol_print_error($this->db);
     		}
     	}
    -
     }
    diff --git a/htdocs/core/class/genericobject.class.php b/htdocs/core/class/genericobject.class.php
    index c89b5c31fea..993d884c88b 100644
    --- a/htdocs/core/class/genericobject.class.php
    +++ b/htdocs/core/class/genericobject.class.php
    @@ -24,20 +24,18 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
     
     
     /**
    - *	Class of a generic business object
    + *  Class of a generic business object
      */
     
     class GenericObject extends CommonObject
     {
    -	/**
    -	 *	Constructor
    -	 *
    -	 *  @param		DoliDB		$db      Database handler
    -	 */
    -	function __construct($db)
    -	{
    -	    $this->db=$db;
    -	}
    -
    +    /**
    +     * Constructor
    +     *
    +     * @param       DoliDB      $db     Database handler
    +     */
    +    function __construct($db)
    +    {
    +        $this->db=$db;
    +    }
     }
    -
    diff --git a/htdocs/core/class/google.class.php b/htdocs/core/class/google.class.php
    index e923ec12252..615729ba9c3 100644
    --- a/htdocs/core/class/google.class.php
    +++ b/htdocs/core/class/google.class.php
    @@ -26,10 +26,17 @@
      */
     class GoogleAPI
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $key;
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	public $key;
     
     	/**
     	 * Constructor
    diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php
    index 439e31caae1..b078fdc0405 100644
    --- a/htdocs/core/class/hookmanager.class.php
    +++ b/htdocs/core/class/hookmanager.class.php
    @@ -29,9 +29,20 @@
      */
     class HookManager
     {
    -	var $db;
    -	var $error;
    -	var $errors=array();
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +	
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
         // Context hookmanager was created for ('thirdpartycard', 'thirdpartydao', ...)
         var $contextarray=array();
    @@ -272,5 +283,4 @@ class HookManager
     
             return ($error?-1:$resaction);
     	}
    -
     }
    diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
    index cebd49737e5..c30dcec6e01 100644
    --- a/htdocs/core/class/html.form.class.php
    +++ b/htdocs/core/class/html.form.class.php
    @@ -17,6 +17,7 @@
      * Copyright (C) 2012-2015  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2014       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
      * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -47,17 +48,30 @@
      */
     class Form
     {
    -	var $db;
    -	var $error;
    -	var $num;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    /**
    +     * @var string[]    Array of error strings
    +     */
    +    public $errors = array();
    +
    +	public $num;
     
     	// Cache arrays
    -	var $cache_types_paiements=array();
    -	var $cache_conditions_paiements=array();
    -	var $cache_availability=array();
    -	var $cache_demand_reason=array();
    -	var $cache_types_fees=array();
    -	var $cache_vatrates=array();
    +	public $cache_types_paiements=array();
    +	public $cache_conditions_paiements=array();
    +	public $cache_availability=array();
    +	public $cache_demand_reason=array();
    +	public $cache_types_fees=array();
    +	public $cache_vatrates=array();
     
     
     	/**
    @@ -202,11 +216,11 @@ class Form
     				}
     				else if ($typeofdata == 'day' || $typeofdata == 'datepicker')
     				{
    -					$ret.=$this->select_date($value,$htmlname,0,0,1,'form'.$htmlname,1,0,1);
    +					$ret.=$this->selectDate($value,$htmlname,0,0,1,'form'.$htmlname,1,0);
     				}
     				else if ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker')
     				{
    -					$ret.=$this->select_date($value,$htmlname,1,1,1,'form'.$htmlname,1,0,1);
    +					$ret.=$this->selectDate($value,$htmlname,1,1,1,'form'.$htmlname,1,0);
     				}
     				else if (preg_match('/^select;/',$typeofdata))
     				{
    @@ -645,6 +659,7 @@ class Form
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return combo list of activated countries, into language of user
     	 *
    @@ -653,14 +668,16 @@ class Form
     	 *  @param  string	$htmloption     	Options html on select object
     	 *  @param	integer	$maxlength			Max length for labels (0=no limit)
     	 *  @param	string	$morecss			More css class
    -	 *  @param	string	$usecodeaskey		'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key
    +	 *  @param	string	$usecodeaskey		''=Use id as key (default), 'code3'=Use code on 3 alpha as key, 'code2"=Use code on 2 alpha as key
     	 *  @param	int		$showempty			Show empty choice
    -	 *  @param	int		$disablefavorites	Disable favorites
    +	 *  @param	int		$disablefavorites	1=Disable favorites,
    +	 *  @param	int		$addspecialentries	1=Add dedicated entries for group of countries (like 'European Economic Community', ...)
     	 *  @return string           			HTML string with select
     	 */
    -	function select_country($selected='', $htmlname='country_id', $htmloption='', $maxlength=0, $morecss='minwidth300', $usecodeaskey='', $showempty=1, $disablefavorites=0)
    +	function select_country($selected='', $htmlname='country_id', $htmloption='', $maxlength=0, $morecss='minwidth300', $usecodeaskey='', $showempty=1, $disablefavorites=0, $addspecialentries=0)
     	{
    -		global $conf,$langs;
    +        // phpcs:enable
    +		global $conf,$langs,$mysoc;
     
     		$langs->load("dict");
     
    @@ -702,15 +719,31 @@ class Form
     				if (empty($disablefavorites)) array_multisort($favorite, SORT_DESC, $label, SORT_ASC, $countryArray);
     				else $countryArray = dol_sort_array($countryArray, 'label');
     
    +				if ($showempty)
    +				{
    +					$out.='<option value="">&nbsp;</option>'."\n";
    +				}
    +
    +				if ($addspecialentries)	// Add dedicated entries for groups of countries
    +				{
    +					//if ($showempty) $out.= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
    +					$out.= '<option value="special_allnotme"'.($selected == 'special_allnotme' ? ' selected' : '').'>'.$langs->trans("CountriesExceptMe", $langs->transnoentitiesnoconv("Country".$mysoc->country_code)).'</option>';
    +					$out.= '<option value="special_eec"'.($selected == 'special_eec' ? ' selected' : '').'>'.$langs->trans("CountriesInEEC").'</option>';
    +					if ($mysoc->isInEEC()) $out.= '<option value="special_eecnotme"'.($selected == 'special_eecnotme' ? ' selected' : '').'>'.$langs->trans("CountriesInEECExceptMe", $langs->transnoentitiesnoconv("Country".$mysoc->country_code)).'</option>';
    +					$out.= '<option value="special_noteec"'.($selected == 'special_noteec' ? ' selected' : '').'>'.$langs->trans("CountriesNotInEEC").'</option>';
    +					$out.= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
    +				}
    +
     				foreach ($countryArray as $row)
     				{
    -					if (empty($showempty) && empty($row['rowid'])) continue;
    +					//if (empty($showempty) && empty($row['rowid'])) continue;
    +					if (empty($row['rowid'])) continue;
     
     					if (empty($disablefavorites) && $row['favorite'] && $row['code_iso']) $atleastonefavorite++;
     					if (empty($row['favorite']) && $atleastonefavorite)
     					{
     						$atleastonefavorite=0;
    -						$out.= '<option value="" disabled class="selectoptiondisabledwhite">----------------------</option>';
    +						$out.= '<option value="" disabled class="selectoptiondisabledwhite">--------------</option>';
     					}
     					if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) )
     					{
    @@ -741,6 +774,7 @@ class Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return select list of incoterms
     	 *
    @@ -755,6 +789,7 @@ class Form
     	 */
     	function select_incoterms($selected='', $location_incoterms='', $page='', $htmlname='incoterm_id', $htmloption='', $forcecombo=1, $events=array())
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$langs->load("dict");
    @@ -833,6 +868,7 @@ class Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of types of lines (product or service)
     	 * 	Example: 0=product, 1=service, 9=other (for external module)
    @@ -846,6 +882,7 @@ class Form
     	 */
     	function select_type_of_lines($selected='',$htmlname='type',$showempty=0,$hidetext=0,$forceall=0)
     	{
    +        // phpcs:enable
     		global $db,$langs,$user,$conf;
     
     		// If product & services are enabled or both disabled.
    @@ -888,6 +925,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load into cache cache_types_fees, array of types of fees
     	 *
    @@ -895,6 +933,7 @@ class Form
     	 */
     	function load_cache_types_fees()
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$num = count($this->cache_types_fees);
    @@ -935,6 +974,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of types of notes
     	 *
    @@ -945,6 +985,7 @@ class Form
     	 */
     	function select_type_fees($selected='',$htmlname='type',$showempty=0)
     	{
    +        // phpcs:enable
     		global $user, $langs;
     
     		dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
    @@ -973,6 +1014,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return HTML code to select a company.
     	 *
    @@ -987,9 +1029,11 @@ class Form
     	 */
     	function select_thirdparty($selected='', $htmlname='socid', $filter='', $limit=20, $ajaxoptions=array(), $forcecombo=0)
     	{
    +        // phpcs:enable
        		return $this->select_thirdparty_list($selected,$htmlname,$filter,1,0,$forcecombo,array(),'',0, $limit);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Output html form to select a third party
     	 *
    @@ -1006,10 +1050,12 @@ class Form
     	 *	@param	string	$selected_input_value	Value of preselected input text (for use with ajax)
     	 *  @param	int		$hidelabel				Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
     	 *  @param	array	$ajaxoptions			Options for ajax_autocompleter
    +	 * 	@param  bool	$multiple				add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
     	 * 	@return	string							HTML string with select box for thirdparty.
     	 */
    -	function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='', $selected_input_value='', $hidelabel=1, $ajaxoptions=array())
    +	function select_company($selected='', $htmlname='socid', $filter='', $showempty='', $showtype=0, $forcecombo=0, $events=array(), $limit=0, $morecss='minwidth100', $moreparam='', $selected_input_value='', $hidelabel=1, $ajaxoptions=array(), $multiple=false)
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		$out='';
    @@ -1045,12 +1091,13 @@ class Form
     		else
     		{
     			// Immediate load of all database
    -			$out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam);
    +			$out.=$this->select_thirdparty_list($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, '', 0, $limit, $morecss, $moreparam, $multiple);
     		}
     
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Output html form to select a third party.
     	 *  Note, you must use the select_company to get the component to select a third party. This function must only be called by select_company.
    @@ -1067,27 +1114,42 @@ class Form
     	 *  @param	int		$limit			Limit number of answers
     	 *  @param	string	$morecss		Add more css styles to the SELECT component
     	 *	@param  string	$moreparam      Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
    +	 *	@param  bool	$multiple       add [] in the name of element and add 'multiple' attribut
     	 * 	@return	string					HTML string with
     	 */
    -	function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='')
    +	function select_thirdparty_list($selected='',$htmlname='socid',$filter='',$showempty='', $showtype=0, $forcecombo=0, $events=array(), $filterkey='', $outputmode=0, $limit=0, $morecss='minwidth100', $moreparam='', $multiple=false)
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		$out='';
     		$num=0;
     		$outarray=array();
     
    +		if ($selected === '') $selected = array();
    +		else if (!is_array($selected)) $selected = array($selected);
    +
     		// Clean $filter that may contains sql conditions so sql code
    -		if (function_exists('test_sql_and_script_inject')) {
    -			if (test_sql_and_script_inject($filter, 3)>0) {
    +		if (function_exists('testSqlAndScriptInject')) {
    +			if (testSqlAndScriptInject($filter, 3)>0) {
     				$filter ='';
     			}
     		}
     
     		// On recherche les societes
     		$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
    -		$sql.= " FROM ".MAIN_DB_PREFIX ."societe as s";
    +
    +		if ($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
    +			$sql .= " ,s.address, s.zip, s.town";
    +		 	$sql .= " , dictp.code as country_code";
    +		}
    +
    +		$sql.= " FROM (".MAIN_DB_PREFIX ."societe as s";
     		if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    +		$sql.= " )";
    +		if ($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
    +			$sql.= " LEFT OUTER JOIN ".MAIN_DB_PREFIX."c_country as dictp ON dictp.rowid=s.fk_pays";
    +		}
     		$sql.= " WHERE s.entity IN (".getEntity('societe').")";
     		if (! empty($user->socid)) $sql.= " AND s.rowid = ".$user->socid;
     		if ($filter) $sql.= " AND (".$filter.")";
    @@ -1130,7 +1192,7 @@ class Form
     			}
     
     			// Construct $out and $outarray
    -			$out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.'">'."\n";
    +			$out.= '<select id="'.$htmlname.'" class="flat'.($morecss?' '.$morecss:'').'"'.($moreparam?' '.$moreparam:'').' name="'.$htmlname.($multiple ? '[]' : '').'" '.($multiple ? 'multiple' : '').'>'."\n";
     
     			$textifempty='';
     			// Do not use textifempty = ' ' or '&nbsp;' here, or search on key will search on ' key'.
    @@ -1177,9 +1239,16 @@ class Form
     						if ($obj->client || $obj->fournisseur) $label.=')';
     					}
     
    +					if ($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST) {
    +						$label.='-'.$obj->address.'-'. $obj->zip.' '. $obj->town;
    +						if (!empty($obj->country_code)) {
    +							$label.= ' '. $langs->trans('Country'.$obj->country_code);
    +						}
    +					}
    +
     					if (empty($outputmode))
     					{
    -						if ($selected > 0 && $selected == $obj->rowid)
    +						if (in_array($obj->rowid,$selected))
     						{
     							$out.= '<option value="'.$obj->rowid.'" selected>'.$label.'</option>';
     						}
    @@ -1211,6 +1280,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Return HTML combo list of absolute discounts
     	 *
    @@ -1223,6 +1293,7 @@ class Form
     	 */
     	function select_remises($selected, $htmlname, $filter, $socid, $maxvalue=0)
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		// On recherche les remises
    @@ -1286,6 +1357,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of all contacts (for a third party or all)
     	 *
    @@ -1308,6 +1380,7 @@ class Form
     	 */
     	function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false, $moreparam='', $htmlid='')
     	{
    +        // phpcs:enable
     		print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid);
     		return $this->num;
     	}
    @@ -1326,19 +1399,23 @@ class Form
     	 *	@param	string		$moreclass		Add more class to class style
     	 *	@param	bool		$options_only	Return options only (for ajax treatment)
     	 *	@param	integer		$showsoc	    Add company into label
    -	 * 	@param	int			$forcecombo		Force to use combo box
    +	 * 	@param	int			$forcecombo		Force to use combo box (so no ajax beautify effect)
     	 *  @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	string		$moreparam		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
     	 *  @param	string		$htmlid			Html id to use instead of htmlname
    +	 *  @param	bool		$multiple		add [] in the name of element and add 'multiple' attribut
     	 *	@return	 int						<0 if KO, Nb of contact in list if OK
     	 */
    -	function selectcontacts($socid, $selected='', $htmlname='contactid', $showempty=0, $exclude='', $limitto='', $showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array(), $moreparam='', $htmlid='')
    +	function selectcontacts($socid, $selected='', $htmlname='contactid', $showempty=0, $exclude='', $limitto='', $showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array(), $moreparam='', $htmlid='', $multiple=false)
     	{
     		global $conf,$langs;
     
     		$langs->load('companies');
     
     		if (empty($htmlid)) $htmlid = $htmlname;
    +
    +		if ($selected === '') $selected = array();
    +		else if (!is_array($selected)) $selected = array($selected);
             $out='';
     
     		// On recherche les societes
    @@ -1363,9 +1440,9 @@ class Form
     				$out .= ajax_combobox($htmlid, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT);
     			}
     
    -			if ($htmlname != 'none' || $options_only) $out.= '<select class="flat'.($moreclass?' '.$moreclass:'').'" id="'.$htmlid.'" name="'.$htmlname.'" '.(!empty($moreparam) ? $moreparam : '').'>';
    -			if ($showempty == 1 || ($showempty == 3 && $num > 1)) $out.= '<option value="0"'.($selected=='0'?' selected':'').'>&nbsp;</option>';
    -			if ($showempty == 2) $out.= '<option value="0"'.($selected=='0'?' selected':'').'>'.$langs->trans("Internal").'</option>';
    +			if ($htmlname != 'none' || $options_only) $out.= '<select class="flat'.($moreclass?' '.$moreclass:'').'" id="'.$htmlid.'" name="'.$htmlname.($multiple ? '[]' : '').'" '.($multiple ? 'multiple' : '').' '.(!empty($moreparam) ? $moreparam : '').'>';
    +			if (($showempty == 1 || ($showempty == 3 && $num > 1)) && !$multiple) $out.= '<option value="0"'.(in_array(0,$selected)?' selected':'').'>&nbsp;</option>';
    +			if ($showempty == 2) $out.= '<option value="0"'.(in_array(0,$selected)?' selected':'').'>'.$langs->trans("Internal").'</option>';
     			$num = $this->db->num_rows($resql);
     			$i = 0;
     			if ($num)
    @@ -1373,7 +1450,6 @@ class Form
     				include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     				$contactstatic=new Contact($this->db);
     
    -				if (!is_array($selected)) $selected = array($selected);
     				while ($i < $num)
     				{
     					$obj = $this->db->fetch_object($resql);
    @@ -1423,7 +1499,7 @@ class Form
     			}
     			else
     			{
    -				$out.= '<option value="-1"'.($showempty==2?'':' selected').' disabled>';
    +				$out.= '<option value="-1"'.(($showempty==2 || $multiple) ? '' : ' selected').' disabled>';
     				$out.= ($socid != -1) ? ($langs->trans($socid?"NoContactDefinedForThirdParty":"NoContactDefined")) : $langs->trans('SelectAThirdPartyFirst');
     				$out.= '</option>';
     			}
    @@ -1442,6 +1518,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return select list of users
     	 *
    @@ -1459,9 +1536,11 @@ class Form
     	 */
     	function select_users($selected='',$htmlname='userid',$show_empty=0,$exclude=null,$disabled=0,$include='',$enableonly='',$force_entity='0')
     	{
    +        // phpcs:enable
     		print $this->select_dolusers($selected,$htmlname,$show_empty,$exclude,$disabled,$include,$enableonly,$force_entity);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return select list of users
     	 *
    @@ -1481,16 +1560,21 @@ class Form
     	 *  @param	string	$morecss		More css
     	 *  @param  int     $noactive       Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on).
     	 *  @param  int		$outputmode     0=HTML select string, 1=Array
    +	 *  @param  bool	$multiple       add [] in the name of element and add 'multiple' attribut
     	 * 	@return	string					HTML select string
     	 *  @see select_dolgroups
     	 */
    -	function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity='0', $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0, $outputmode=0)
    +	function select_dolusers($selected='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity='0', $maxlength=0, $showstatus=0, $morefilter='', $show_every=0, $enableonlytext='', $morecss='', $noactive=0, $outputmode=0, $multiple=false)
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		// If no preselected user defined, we take current user
     		if ((is_numeric($selected) && ($selected < -2 || empty($selected))) && empty($conf->global->SOCIETE_DISABLE_DEFAULT_SALESREPRESENTATIVE)) $selected=$user->id;
     
    +		if ($selected === '') $selected = array();
    +		else if (!is_array($selected)) $selected = array($selected);
    +
     		$excludeUsers=null;
     		$includeUsers=null;
     
    @@ -1526,7 +1610,7 @@ class Form
     			else $sql.= " WHERE u.entity IS NOT NULL";
     		}
     		else
    -	   {
    +		{
     			if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
     			{
     				$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug";
    @@ -1566,9 +1650,9 @@ class Form
     				$out .= ajax_combobox($htmlname);
     
     				// do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined
    -				$out.= '<select class="flat'.($morecss?' minwidth100 '.$morecss:' minwidth200').'" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>';
    -				if ($show_empty) $out.= '<option value="-1"'.((empty($selected) || $selected==-1)?' selected':'').'>&nbsp;</option>'."\n";
    -				if ($show_every) $out.= '<option value="-2"'.(($selected==-2)?' selected':'').'>-- '.$langs->trans("Everybody").' --</option>'."\n";
    +				$out.= '<select class="flat'.($morecss?' minwidth100 '.$morecss:' minwidth200').'" id="'.$htmlname.'" name="'.$htmlname.($multiple ? '[]' : '').'" '.($multiple ? 'multiple' : '').' '.($disabled?' disabled':'').'>';
    +				if ($show_empty && !$multiple) $out.= '<option value="-1"'.((empty($selected) || in_array(-1,$selected))?' selected':'').'>&nbsp;</option>'."\n";
    +				if ($show_every) $out.= '<option value="-2"'.((in_array(-2,$selected))?' selected':'').'>-- '.$langs->trans("Everybody").' --</option>'."\n";
     
     				$userstatic=new User($this->db);
     
    @@ -1583,7 +1667,7 @@ class Form
     					$disableline='';
     					if (is_array($enableonly) && count($enableonly) && ! in_array($obj->rowid,$enableonly)) $disableline=($enableonlytext?$enableonlytext:'1');
     
    -					if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid))
    +					if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && in_array($obj->rowid,$selected) ))
     					{
     						$out.= '<option value="'.$obj->rowid.'"';
     						if ($disableline) $out.= ' disabled';
    @@ -1665,6 +1749,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return select list of users. Selected users are stored into session.
     	 *  List of users are provided into $_SESSION['assignedtouser'].
    @@ -1689,6 +1774,7 @@ class Form
     	 */
     	function select_dolusers_forevent($action='', $htmlname='userid', $show_empty=0, $exclude=null, $disabled=0, $include='', $enableonly='', $force_entity='0', $maxlength=0, $showstatus=0, $morefilter='', $showproperties=0, $listofuserid=array(), $listofcontactid=array(), $listofotherid=array())
     	{
    +        // phpcs:enable
     		global $conf, $user, $langs;
     
     		$userstatic=new User($this->db);
    @@ -1753,6 +1839,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of products for customer in Ajax if Ajax activated or go to select_produits_list
     	 *
    @@ -1780,6 +1867,7 @@ class Form
     	 */
     	function select_produits($selected='', $htmlname='productid', $filtertype='', $limit=20, $price_level=0, $status=1, $finished=2, $selected_input_value='', $hidelabel=0, $ajaxoptions=array(), $socid=0, $showempty='1', $forcecombo=0, $morecss='', $hidepriceinlabel=0, $warehouseStatus='', $selected_combinations = array())
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		$price_level = (! empty($price_level) ? $price_level : 0);
    @@ -1895,6 +1983,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of products for a customer
     	 *
    @@ -1920,6 +2009,7 @@ class Form
     	 */
     	function select_produits_list($selected='',$htmlname='productid',$filtertype='',$limit=20,$price_level=0,$filterkey='',$status=1,$finished=2,$outputmode=0,$socid=0,$showempty='1',$forcecombo=0,$morecss='',$hidepriceinlabel=0, $warehouseStatus='')
     	{
    +        // phpcs:enable
     		global $langs,$conf,$user,$db;
     
     		$out='';
    @@ -1981,6 +2071,12 @@ class Form
     			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid";
     			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid";
     		}
    +		
    +		// include search in supplier ref
    +		if(!empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF))
    +		{
    +            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
    +		}
     
     		//Price by customer
     		if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
    @@ -2034,6 +2130,7 @@ class Form
     				if ($i > 0) $sql.=" AND ";
     				$sql.="(p.ref LIKE '".$db->escape($prefix.$crit)."%' OR p.label LIKE '".$db->escape($prefix.$crit)."%'";
     				if (! empty($conf->global->MAIN_MULTILANGS)) $sql.=" OR pl.label LIKE '".$db->escape($prefix.$crit)."%'";
    +				if (! empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF)) $sql.=" OR pfp.ref_fourn LIKE '".$db->escape($prefix.$crit)."%'";
     				$sql.=")";
     				$i++;
     			}
    @@ -2381,6 +2478,7 @@ class Form
     		$optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>$outprice_ht, 'price_ttc'=>$outprice_ttc, 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list)
     	 *
    @@ -2396,6 +2494,7 @@ class Form
     	 */
     	function select_produits_fournisseurs($socid, $selected='', $htmlname='productid', $filtertype='', $filtre='', $ajaxoptions=array(), $hidelabel=0, $alsoproductwithnosupplierprice=0)
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     		global $price_level, $status, $finished;
     
    @@ -2422,6 +2521,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of suppliers products
     	 *
    @@ -2439,6 +2539,7 @@ class Form
     	 */
     	function select_produits_fournisseurs_list($socid,$selected='',$htmlname='productid',$filtertype='',$filtre='',$filterkey='',$statut=-1,$outputmode=0,$limit=100,$alsoproductwithnosupplierprice=0)
     	{
    +        // phpcs:enable
     		global $langs,$conf,$db;
     
     		$out='';
    @@ -2651,6 +2752,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of suppliers prices for a product
     	 *
    @@ -2661,6 +2763,7 @@ class Form
     	 */
     	function select_product_fourn_price($productid, $htmlname='productfournpriceid', $selected_supplier='')
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		$langs->load('stocks');
    @@ -2762,6 +2865,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return list of delivery address
     	 *
    @@ -2773,7 +2877,8 @@ class Form
     	 */
     	function select_address($selected, $socid, $htmlname='address_id',$showempty=0)
     	{
    -		// On recherche les utilisateurs
    +        // phpcs:enable
    +		// looking for users
     		$sql = "SELECT a.rowid, a.label";
     		$sql .= " FROM ".MAIN_DB_PREFIX ."societe_address as a";
     		$sql .= " WHERE a.fk_soc = ".$socid;
    @@ -2814,6 +2919,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load into cache list of payment terms
     	 *
    @@ -2821,6 +2927,7 @@ class Form
     	 */
     	function load_cache_conditions_paiements()
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$num = count($this->cache_conditions_paiements);
    @@ -2861,6 +2968,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge dans cache la liste des délais de livraison possibles
     	 *
    @@ -2868,6 +2976,7 @@ class Form
     	 */
     	function load_cache_availability()
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$num = count($this->cache_availability);
    @@ -3031,6 +3140,7 @@ class Form
     		if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge dans cache la liste des types de paiements possibles
     	 *
    @@ -3038,6 +3148,7 @@ class Form
     	 */
     	function load_cache_types_paiements()
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$num=count($this->cache_types_paiements);
    @@ -3083,6 +3194,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Return list of payment modes.
     	 *      Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want.
    @@ -3098,6 +3210,7 @@ class Form
     	 */
     	function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='')
     	{
    +        // phpcs:enable
     		global $langs, $user, $conf;
     
     		dol_syslog(__METHOD__." selected=".$selected.", htmlname=".$htmlname, LOG_DEBUG);
    @@ -3127,6 +3240,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Return list of payment methods
     	 *
    @@ -3143,6 +3257,7 @@ class Form
     	 */
     	function select_types_paiements($selected='', $htmlname='paiementtype', $filtertype='', $format=0, $empty=1, $noadmininfo=0, $maxlength=0, $active=1, $morecss='')
     	{
    +        // phpcs:enable
     		global $langs,$user;
     
     		dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG);
    @@ -3408,6 +3523,7 @@ class Form
     		return $return;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return a HTML select list of bank accounts
     	 *
    @@ -3422,6 +3538,7 @@ class Form
     	 */
     	function select_comptes($selected='',$htmlname='accountid',$statut=0,$filtre='',$useempty=0,$moreattrib='',$showcurrency=0)
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		$langs->load("admin");
    @@ -3511,6 +3628,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return list of categories having choosed type
     	 *
    @@ -3525,6 +3643,7 @@ class Form
     	 */
     	function select_all_categories($type, $selected='', $htmlname="parent", $maxlength=64, $excludeafterid=0, $outputmode=0)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     		$langs->load("categories");
     
    @@ -3596,6 +3715,7 @@ class Form
     		return $output;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *     Show a confirmation HTML form or AJAX popup
     	 *
    @@ -3614,6 +3734,8 @@ class Form
     	 */
     	function form_confirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=170, $width=500)
     	{
    +        // phpcs:enable
    +        dol_syslog(__METHOD__ . ': using form_confirm is deprecated. Use formconfim instead.', LOG_WARNING);
     		print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
     	}
     
    @@ -3671,7 +3793,7 @@ class Form
     
     			// Now add questions
     			$more.='<table class="paddingtopbottomonly" width="100%">'."\n";
    -			$more.='<tr><td colspan="3">'.(! empty($formquestion['text'])?$formquestion['text']:'').'</td></tr>'."\n";
    +			if (! empty($formquestion['text'])) $more.='<tr><td colspan="2">'.$formquestion['text'].'</td></tr>'."\n";
     			foreach ($formquestion as $key => $input)
     			{
     				if (is_array($input) && ! empty($input))
    @@ -3682,29 +3804,28 @@ class Form
     
     					if ($input['type'] == 'text')
     					{
    -						$more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="text" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'"'.$moreattr.' /></td></tr>'."\n";
    +						$more.='<tr><td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>'.$input['label'].'</td><td align="left"><input type="text" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'"'.$moreattr.' /></td></tr>'."\n";
     					}
     					else if ($input['type'] == 'password')
     					{
    -						$more.='<tr><td>'.$input['label'].'</td><td colspan="2" align="left"><input type="password" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'"'.$moreattr.' /></td></tr>'."\n";
    +						$more.='<tr><td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>'.$input['label'].'</td><td align="left"><input type="password" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'"'.$size.' value="'.$input['value'].'"'.$moreattr.' /></td></tr>'."\n";
     					}
     					else if ($input['type'] == 'select')
     					{
    -						$more.='<tr><td>';
    -						if (! empty($input['label'])) $more.=$input['label'].'</td><td valign="top" colspan="2" align="left">';
    +						$more.='<tr><td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>';
    +						if (! empty($input['label'])) $more.=$input['label'].'</td><td class="tdtop" align="left">';
     						$more.=$this->selectarray($input['name'],$input['values'],$input['default'],1,0,0,$moreattr,0,0,0,'',$morecss);
     						$more.='</td></tr>'."\n";
     					}
     					else if ($input['type'] == 'checkbox')
     					{
     						$more.='<tr>';
    -						$more.='<td>'.$input['label'].' </td><td align="left">';
    +						$more.='<td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>'.$input['label'].' </td><td align="left">';
     						$more.='<input type="checkbox" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'"'.$moreattr;
     						if (! is_bool($input['value']) && $input['value'] != 'false' && $input['value'] != '0') $more.=' checked';
     						if (is_bool($input['value']) && $input['value']) $more.=' checked';
     						if (isset($input['disabled'])) $more.=' disabled';
     						$more.=' /></td>';
    -						$more.='<td align="left">&nbsp;</td>';
     						$more.='</tr>'."\n";
     					}
     					else if ($input['type'] == 'radio')
    @@ -3713,12 +3834,11 @@ class Form
     						foreach($input['values'] as $selkey => $selval)
     						{
     							$more.='<tr>';
    -							if ($i==0) $more.='<td class="tdtop">'.$input['label'].'</td>';
    -							else $more.='<td>&nbsp;</td>';
    -							$more.='<td width="20"><input type="radio" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'" value="'.$selkey.'"'.$moreattr;
    +							if ($i==0) $more.='<td'.(empty($input['tdclass'])?' class="tdtop"':(' class="tdtop '.$input['tdclass'].'"')).'>'.$input['label'].'</td>';
    +							else $more.='<td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>&nbsp;</td>';
    +							$more.='<td><input type="radio" class="flat'.$morecss.'" id="'.$input['name'].'" name="'.$input['name'].'" value="'.$selkey.'"'.$moreattr;
     							if ($input['disabled']) $more.=' disabled';
    -							$more.=' /></td>';
    -							$more.='<td align="left">';
    +							$more.=' /> ';
     							$more.=$selval;
     							$more.='</td></tr>'."\n";
     							$i++;
    @@ -3726,9 +3846,9 @@ class Form
     					}
     					else if ($input['type'] == 'date')
     					{
    -						$more.='<tr><td>'.$input['label'].'</td>';
    -						$more.='<td colspan="2" align="left">';
    -						$more.=$this->select_date($input['value'],$input['name'],0,0,0,'',1,0,1);
    +						$more.='<tr><td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>'.$input['label'].'</td>';
    +						$more.='<td align="left">';
    +						$more.=$this->selectDate($input['value'],$input['name'],0,0,0,'',1,0);
     						$more.='</td></tr>'."\n";
     						$formquestion[] = array('name'=>$input['name'].'day');
     						$formquestion[] = array('name'=>$input['name'].'month');
    @@ -3738,15 +3858,15 @@ class Form
     					}
     					else if ($input['type'] == 'other')
     					{
    -						$more.='<tr><td>';
    -						if (! empty($input['label'])) $more.=$input['label'].'</td><td colspan="2" align="left">';
    +						$more.='<tr><td'.(empty($input['tdclass'])?'':(' class="'.$input['tdclass'].'"')).'>';
    +						if (! empty($input['label'])) $more.=$input['label'].'</td><td align="left">';
     						$more.=$input['value'];
     						$more.='</td></tr>'."\n";
     					}
     
     					else if ($input['type'] == 'onecolumn')
     					{
    -						$more.='<tr><td colspan="3" align="left">';
    +						$more.='<tr><td colspan="2" align="left">';
     						$more.=$input['value'];
     						$more.='</td></tr>'."\n";
     					}
    @@ -3793,21 +3913,21 @@ class Form
     			$formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': '');
     			$formconfirm.= '</div>'."\n";
     
    -			$formconfirm.= "\n<!-- begin ajax form_confirm page=".$page." -->\n";
    +			$formconfirm.= "\n<!-- begin ajax formconfirm page=".$page." -->\n";
     			$formconfirm.= '<script type="text/javascript">'."\n";
     			$formconfirm.= 'jQuery(document).ready(function() {
                 $(function() {
                 	$( "#'.$dialogconfirm.'" ).dialog(
                 	{
                         autoOpen: '.($autoOpen ? "true" : "false").',';
    -					if ($newselectedchoice == 'no')
    -					{
    -						$formconfirm.='
    +			if ($newselectedchoice == 'no')
    +			{
    +				$formconfirm.='
     						open: function() {
                 				$(this).parent().find("button.ui-button:eq(2)").focus();
     						},';
    -					}
    -					$formconfirm.='
    +			}
    +			$formconfirm.='
                         resizable: false,
                         height: "'.$height.'",
                         width: "'.$width.'",
    @@ -3864,11 +3984,11 @@ class Form
                 });
                 });
                 </script>';
    -			$formconfirm.= "<!-- end ajax form_confirm -->\n";
    +			$formconfirm.= "<!-- end ajax formconfirm -->\n";
     		}
     		else
     		{
    -			$formconfirm.= "\n<!-- begin form_confirm page=".$page." -->\n";
    +			$formconfirm.= "\n<!-- begin formconfirm page=".$page." -->\n";
     
     			if (empty($disableformtag)) $formconfirm.= '<form method="POST" action="'.$page.'" class="notoptoleftroright">'."\n";
     
    @@ -3902,13 +4022,14 @@ class Form
     			if (empty($disableformtag)) $formconfirm.= "</form>\n";
     			$formconfirm.= '<br>';
     
    -			$formconfirm.= "<!-- end form_confirm -->\n";
    +			$formconfirm.= "<!-- end formconfirm -->\n";
     		}
     
     		return $formconfirm;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Show a form to select a project
     	 *
    @@ -3924,6 +4045,7 @@ class Form
     	 */
     	function form_project($page, $socid, $selected='', $htmlname='projectid', $discard_closed=0, $maxlength=20, $forcefocus=0, $nooutput=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -3967,6 +4089,7 @@ class Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show a form to select payment conditions
     	 *
    @@ -3978,6 +4101,7 @@ class Form
     	 */
     	function form_conditions_reglement($page, $selected='', $htmlname='cond_reglement_id', $addempty=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		if ($htmlname != "none")
     		{
    @@ -4000,6 +4124,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show a form to select a delivery delay
     	 *
    @@ -4011,6 +4136,7 @@ class Form
     	 */
     	function form_availability($page, $selected='', $htmlname='availability', $addempty=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		if ($htmlname != "none")
     		{
    @@ -4074,6 +4200,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Show a form + html select a date
     	 *
    @@ -4084,10 +4211,11 @@ class Form
     	 *    @param    int			$displaymin		Display minutes selector
     	 *    @param	int			$nooutput		1=No print output, return string
     	 *    @return	string
    -	 *    @see		select_date
    +	 *    @see		selectDate
     	 */
     	function form_date($page, $selected, $htmlname, $displayhour=0, $displaymin=0, $nooutput=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$ret='';
    @@ -4099,7 +4227,7 @@ class Form
     			$ret.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     			$ret.='<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
     			$ret.='<tr><td>';
    -			$ret.=$this->select_date($selected,$htmlname,$displayhour,$displaymin,1,'form'.$htmlname,1,0,1);
    +			$ret.=$this->selectDate($selected,$htmlname,$displayhour,$displaymin,1,'form'.$htmlname,1,0);
     			$ret.='</td>';
     			$ret.='<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
     			$ret.='</tr></table></form>';
    @@ -4115,6 +4243,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show a select form to choose a user
     	 *
    @@ -4127,6 +4256,7 @@ class Form
     	 */
     	function form_users($page, $selected='', $htmlname='userid', $exclude='', $include='')
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($htmlname != "none")
    @@ -4153,6 +4283,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Show form with payment mode
     	 *
    @@ -4165,6 +4296,7 @@ class Form
     	 */
     	function form_modes_reglement($page, $selected='', $htmlname='mode_reglement_id', $filtertype='', $active=1)
     	{
    +        // phpcs:enable
     		global $langs;
     		if ($htmlname != "none")
     		{
    @@ -4187,6 +4319,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Show form with multicurrency code
     	 *
    @@ -4197,6 +4330,7 @@ class Form
     	 */
     	function form_multicurrency_code($page, $selected='', $htmlname='multicurrency_code')
     	{
    +        // phpcs:enable
     		global $langs;
     		if ($htmlname != "none")
     		{
    @@ -4214,6 +4348,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Show form with multicurrency rate
     	 *
    @@ -4225,6 +4360,7 @@ class Form
     	 */
     	function form_multicurrency_rate($page, $rate='', $htmlname='multicurrency_tx', $currency='')
     	{
    +        // phpcs:enable
     		global $langs, $mysoc, $conf;
     
     		if ($htmlname != "none")
    @@ -4255,6 +4391,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show a select box with available absolute discounts
     	 *
    @@ -4272,6 +4409,7 @@ class Form
     	 */
     	function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter='', $maxvalue=0, $more='', $hidelist=0, $discount_type=0)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     		if ($htmlname != "none")
     		{
    @@ -4350,6 +4488,7 @@ class Form
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Show forms to select a contact
     	 *
    @@ -4361,6 +4500,7 @@ class Form
     	 */
     	function form_contacts($page, $societe, $selected='', $htmlname='contactid')
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		if ($htmlname != "none")
    @@ -4394,6 +4534,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Output html select to select thirdparty
     	 *
    @@ -4405,20 +4546,23 @@ class Form
     	 * 	@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.
     	 *  @return	void
     	 */
    -	function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array())
    +	function form_thirdparty($page, $selected='', $htmlname='socid', $filter='',$showempty=0, $showtype=0, $forcecombo=0, $events=array(), $nooutput=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
    +		$out = '';
     		if ($htmlname != "none")
     		{
    -			print '<form method="post" action="'.$page.'">';
    -			print '<input type="hidden" name="action" value="set_thirdparty">';
    -			print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    -			print $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events);
    -			print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    -			print '</form>';
    +			$out.='<form method="post" action="'.$page.'">';
    +			$out.= '<input type="hidden" name="action" value="set_thirdparty">';
    +			$out.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +			$out.= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events);
    +			$out.= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    +			$out.= '</form>';
     		}
     		else
     		{
    @@ -4427,15 +4571,19 @@ class Form
     				require_once DOL_DOCUMENT_ROOT .'/societe/class/societe.class.php';
     				$soc = new Societe($this->db);
     				$soc->fetch($selected);
    -				print $soc->getNomUrl($langs);
    +				$out.= $soc->getNomUrl($langs);
     			}
     			else
     			{
    -				print "&nbsp;";
    +				$out.= "&nbsp;";
     			}
     		}
    +
    +		if ($nooutput) return $out;
    +		else print $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Retourne la liste des devises, dans la langue de l'utilisateur
     	 *
    @@ -4445,6 +4593,7 @@ class Form
     	 */
     	function select_currency($selected='',$htmlname='currency_id')
     	{
    +        // phpcs:enable
     		print $this->selectCurrency($selected,$htmlname);
     	}
     
    @@ -4536,7 +4685,6 @@ class Form
     					$out.= '</option>';
     				}
     			}
    -
     		}
     
     		$out.= '</select>';
    @@ -4547,6 +4695,7 @@ class Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load into the cache vat rates of a country
     	 *
    @@ -4555,6 +4704,7 @@ class Form
     	 */
     	function load_cache_vatrates($country_code)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$num = count($this->cache_vatrates);
    @@ -4612,6 +4762,7 @@ class Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Output an HTML select vat rate.
     	 *  The name of this function should be selectVat. We keep bad name for compatibility purpose.
    @@ -4635,6 +4786,7 @@ class Form
     	 */
     	function load_tva($htmlname='tauxtva', $selectedrate='', $societe_vendeuse='', $societe_acheteuse='', $idprod=0, $info_bits=0, $type='', $options_only=false, $mode=0)
     	{
    +        // phpcs:enable
     		global $langs,$conf,$mysoc;
     
     		$langs->load('errors');
    @@ -4803,8 +4955,9 @@ class Form
     	}
     
     
    -	/**
    -	 *	Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
     	 *  Fields are preselected with :
     	 *            	- set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
     	 *            	- local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
    @@ -4823,18 +4976,52 @@ class Form
     	 *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
     	 *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another select_date field.
     	 *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
    -	 * 	@return	string|null						Nothing or string if nooutput is 1
    -	 *  @see	form_date, select_month, select_year, select_dayofweek
    +	 *  @return	string|null					Nothing or string if nooutput is 1
    +     *  @deprecated
    +	 *  @see    form_date, select_month, select_year, select_dayofweek
     	 */
    -	function select_date($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $nooutput=0, $disabled=0, $fullday='', $addplusone='', $adddateof='')
    +    function select_date($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $nooutput=0, $disabled=0, $fullday='', $addplusone='', $adddateof='')
    +    {
    +        // phpcs:enable
    +        $retstring = $this->selectDate($set_time, $prefix, $h, $m, $empty, $form_name, $d, $addnowlink, $disabled, $fullday, $addplusone, $adddateof);
    +        if (! empty($nooutput)) {
    +            return $retstring;
    +        }
    +        print $retstring;
    +        return;
    +    }
    +
    +    /**
    +     *  Show a HTML widget to input a date or combo list for day, month, years and optionaly hours and minutes.
    +	 *  Fields are preselected with :
    +	 *              - set_time date (must be a local PHP server timestamp or string date with format 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM')
    +	 *              - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
    +	 *              - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
    +	 *
    +	 *  @param  timestamp   $set_time       Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
    +	 *  @param	string		$prefix			Prefix for fields name
    +	 *  @param	int			$h				1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty
    +	 *	@param	int			$m				1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
    +	 *	@param	int			$empty			0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
    +	 *	@param	string		$form_name 		Not used
    +	 *	@param	int			$d				1=Show days, month, years
    +	 * 	@param	int			$addnowlink		Add a link "Now"
    +	 * 	@param 	int			$disabled		Disable input fields
    +	 *  @param  int			$fullday        When a checkbox with this html name is on, hour and day are set with 00:00 or 23:59
    +	 *  @param	string		$addplusone		Add a link "+1 hour". Value must be name of another selectDate field.
    +	 *  @param  datetime    $adddateof      Add a link "Date of invoice" using the following date.
    +	 * 	@return string                      Html for selectDate
    +	 *  @see    form_date, select_month, select_year, select_dayofweek
    +	 */
    +	function selectDate($set_time='', $prefix='re', $h=0, $m=0, $empty=0, $form_name="", $d=1, $addnowlink=0, $disabled=0, $fullday='', $addplusone='', $adddateof='')
     	{
     		global $conf,$langs;
     
     		$retstring='';
     
    -		if($prefix=='') $prefix='re';
    -		if($h == '') $h=0;
    -		if($m == '') $m=0;
    +		if ($prefix=='') $prefix='re';
    +		if ($h == '') $h=0;
    +		if ($m == '') $m=0;
     		$emptydate=0;
     		$emptyhours=0;
     		if ($empty == 1) { $emptydate=1; $emptyhours=1; }
    @@ -4894,7 +5081,6 @@ class Form
     		if (! empty($conf->use_javascript_ajax) && (empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR != "none")) {
     			$usecalendar = ((empty($conf->global->MAIN_POPUP_CALENDAR) || $conf->global->MAIN_POPUP_CALENDAR == 'eldy')?'jquery':$conf->global->MAIN_POPUP_CALENDAR);
     		}
    -		//if (! empty($conf->browser->phone)) $usecalendar='combo';
     
     		if ($d)
     		{
    @@ -5173,12 +5359,10 @@ class Form
     			$retstring.=' - <button class="dpInvisibleButtons datenowlink" id="dateofinvoice" type="button" name="_dateofinvoice" value="now" onclick="jQuery(\'#re\').val(\''.dol_print_date($adddateof,'day').'\');jQuery(\'#reday\').val(\''.$tmparray['mday'].'\');jQuery(\'#remonth\').val(\''.$tmparray['mon'].'\');jQuery(\'#reyear\').val(\''.$tmparray['year'].'\');">'.$langs->trans("DateInvoice").'</a>';
     		}
     
    -		if (! empty($nooutput)) return $retstring;
    -
    -		print $retstring;
    -		return;
    +		return $retstring;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to show a form to select a duration on a page
     	 *
    @@ -5194,6 +5378,7 @@ class Form
     	 */
     	function select_duration($prefix, $iSecond='', $disabled=0, $typehour='select', $minunderhours=0, $nooutput=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$retstring='';
    @@ -5592,7 +5777,7 @@ class Form
     	 *  @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 if caller request 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)
    +	 *  @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 selectArrayFilter, ajax_combobox in ajax.lib.php
     	 */
    @@ -5694,7 +5879,7 @@ class Form
     	 *  @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 if caller request 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)
    +	 *  @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
     	 */
    @@ -5811,55 +5996,76 @@ class Form
     	 *  @param	int		$width			Force width of select box. May be used only when using jquery couch. Example: 250, 95%
     	 *  @param	string	$moreattrib		Add more options on select component. Example: 'disabled'
     	 *  @param	string	$elemtype		Type of element we show ('category', ...)
    +	 *  @param	string	$placeholder	String to use as placeholder
    +	 *  @param	int		$addjscombo		Add js combo
     	 *	@return	string					HTML multiselect string
     	 *  @see selectarray
     	 */
    -	static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='',$elemtype='')
    +	static function multiselectarray($htmlname, $array, $selected=array(), $key_in_label=0, $value_as_key=0, $morecss='', $translate=0, $width=0, $moreattrib='', $elemtype='', $placeholder='', $addjscombo=1)
     	{
     		global $conf, $langs;
     
     		$out = '';
     
    +
     		// Add code for jquery to use multiselect
     		if (! empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) || defined('REQUIRE_JQUERY_MULTISELECT'))
     		{
    -			$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
    -   			$out.="\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' -->
    -    			<script type="text/javascript">
    -	    			function formatResult(record) {'."\n";
    -						if ($elemtype == 'category')
    -						{
    -							$out.='	//return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> <a href="'.DOL_URL_ROOT.'/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
    -								  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
    -						}
    -						else
    -						{
    -							$out.='return record.text;';
    -						}
    -			$out.= '	};
    -    				function formatSelection(record) {'."\n";
    -						if ($elemtype == 'category')
    -						{
    -							$out.='	//return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> <a href="'.DOL_URL_ROOT.'/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
    -								  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
    -						}
    -						else
    -						{
    -							$out.='return record.text;';
    -						}
    -			$out.= '	};
    -	    			$(document).ready(function () {
    -    					$(\'#'.$htmlname.'\').'.$tmpplugin.'({
    -    						dir: \'ltr\',
    -							// Specify format function for dropdown item
    -							formatResult: formatResult,
    -    					 	templateResult: formatResult,		/* For 4.0 */
    -							// Specify format function for selected item
    -							formatSelection: formatSelection,
    -    					 	templateResult: formatSelection		/* For 4.0 */
    -    					});
    -    				});
    -    			</script>';
    +			$out.="\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id '.$htmlname.' -->
    +						<script type="text/javascript">'."\n";
    +			if ($addjscombo == 1)
    +			{
    +				$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
    +				$out.=	'function formatResult(record) {'."\n";
    +				if ($elemtype == 'category')
    +				{
    +					$out.='	//return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> <a href="'.DOL_URL_ROOT.'/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
    +									  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
    +				}
    +				else
    +				{
    +					$out.='return record.text;';
    +				}
    +				$out.=	'};'."\n";
    +				$out.=	'function formatSelection(record) {'."\n";
    +				if ($elemtype == 'category')
    +				{
    +					$out.='	//return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> <a href="'.DOL_URL_ROOT.'/categories/viewcat.php?type=0&id=\'+record.id+\'">\'+record.text+\'</a></span>\';
    +									  	return \'<span><img src="'.DOL_URL_ROOT.'/theme/eldy/img/object_category.png'.'"> \'+record.text+\'</span>\';';
    +				}
    +				else
    +				{
    +					$out.='return record.text;';
    +				}
    +				$out.=	'};'."\n";
    +				$out.=	'$(document).ready(function () {
    +							$(\'#'.$htmlname.'\').'.$tmpplugin.'({
    +								dir: \'ltr\',
    +								// Specify format function for dropdown item
    +								formatResult: formatResult,
    +							 	templateResult: formatResult,		/* For 4.0 */
    +								// Specify format function for selected item
    +								formatSelection: formatSelection,
    +							 	templateResult: formatSelection		/* For 4.0 */
    +							});
    +						});'."\n";
    +			}
    +			elseif ($addjscombo == 2)
    +			{
    +				// Add other js lib
    +				// ...
    +				$out.= '$(document).ready(function () {
    +							$(\'#'.$htmlname.'\').multiSelect({
    +								containerHTML: \'<div class="multi-select-container">\',
    +								menuHTML: \'<div class="multi-select-menu">\',
    +								buttonHTML: \'<span class="multi-select-button '.$morecss.'">\',
    +								menuItemHTML: \'<label class="multi-select-menuitem">\',
    +								activeClass: \'multi-select-container--open\',
    +								noneText: \''.$placeholder.'\'
    +							});
    +						})';
    +			}
    +			$out.=	'</script>';
     		}
     
     		// Try also magic suggest
    @@ -5937,7 +6143,7 @@ class Form
     		   }
     		   if ($val['label'])
     		   {
    -			   $lis.='<li><input type="checkbox" value="'.$key.'"'.(empty($val['checked'])?'':' checked="checked"').'/>'.dol_escape_htmltag($langs->trans($val['label'])).'</li>';
    +		   	$lis.='<li><input type="checkbox" id="checkbox'.$key.'" value="'.$key.'"'.(empty($val['checked'])?'':' checked="checked"').'/><label for="checkbox'.$key.'">'.dol_escape_htmltag($langs->trans($val['label'])).'</label></li>';
     			   $listcheckedstring.=(empty($val['checked'])?'':$key.',');
     		   }
     		}
    @@ -6345,7 +6551,7 @@ class Form
     	 *  @param	int      	$useempty		1=Add empty line
     	 *	@return	string						See option
     	 */
    -	function selectyesno($htmlname, $value='', $option=0, $disabled=false, $useempty='')
    +	function selectyesno($htmlname, $value='', $option=0, $disabled=false, $useempty=0)
     	{
     		global $langs;
     
    @@ -6377,6 +6583,7 @@ class Form
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of export templates
     	 *
    @@ -6388,7 +6595,7 @@ class Form
     	 */
     	function select_export_model($selected='',$htmlname='exportmodelid',$type='',$useempty=0)
     	{
    -
    +        // phpcs:enable
     		$sql = "SELECT rowid, label";
     		$sql.= " FROM ".MAIN_DB_PREFIX."export_model";
     		$sql.= " WHERE type = '".$type."'";
    @@ -6610,16 +6817,17 @@ class Form
     	 * 		@param	string		$imagesize		    'mini', 'small' or '' (original)
     	 *      @param  int         $addlinktofullsize  Add link to fullsize image
     	 *      @param  int         $cache              1=Accept to use image in cache
    +	 *      @param	string		$forcecapture		Force parameter capture on HTML input file element to ask a smartphone to allow to open camera to take photo. Auto if empty.
     	 * 	  	@return string    						HTML code to output photo
     	 */
    -	static function showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0)
    +	static function showphoto($modulepart, $object, $width=100, $height=0, $caneditfield=0, $cssclass='photowithmargin', $imagesize='', $addlinktofullsize=1, $cache=0, $forcecapture='')
     	{
     		global $conf,$langs;
     
     		$entity = (! empty($object->entity) ? $object->entity : $conf->entity);
     		$id = (! empty($object->id) ? $object->id : $object->rowid);
     
    -		$ret='';$dir='';$file='';$originalfile='';$altfile='';$email='';
    +		$ret='';$dir='';$file='';$originalfile='';$altfile='';$email='';$capture='';
     		if ($modulepart=='societe')
     		{
     			$dir=$conf->societe->multidir_output[$entity];
    @@ -6643,6 +6851,7 @@ class Form
     				$originalfile=get_exdir(0, 0, 0, 0, $object, 'contact').'/photos/'.$object->photo;
     			}
     			$email=$object->email;
    +			$capture='user';
     		}
     		else if ($modulepart=='userphoto')
     		{
    @@ -6656,6 +6865,7 @@ class Form
     			}
     			if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
     			$email=$object->email;
    +			$capture='user';
     		}
     		else if ($modulepart=='memberphoto')
     		{
    @@ -6669,6 +6879,7 @@ class Form
     			}
     			if (! empty($conf->global->MAIN_OLD_IMAGE_LINKS)) $altfile=$object->id.".jpg";	// For backward compatibility
     			$email=$object->email;
    +			$capture='user';
     		}
     		else
     		{
    @@ -6685,6 +6896,8 @@ class Form
     			$email=$object->email;
     		}
     
    +		if ($forcecapture) $capture = $forcecapture;
    +
     		if ($dir)
     		{
     			if ($file && file_exists($dir."/".$file))
    @@ -6741,16 +6954,16 @@ class Form
     				if ($object->photo) $ret.="<br>\n";
     				$ret.='<table class="nobordernopadding centpercent">';
     				if ($object->photo) $ret.='<tr><td><input type="checkbox" class="flat photodelete" name="deletephoto" id="photodelete"> '.$langs->trans("Delete").'<br><br></td></tr>';
    -				$ret.='<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"></td></tr>';
    +				$ret.='<tr><td class="tdoverflow"><input type="file" class="flat maxwidth200onsmartphone" name="photo" id="photoinput"'.($capture?' capture="'.$capture.'"':'').'></td></tr>';
     				$ret.='</table>';
     			}
    -
     		}
     		else dol_print_error('','Call of showphoto with wrong parameters modulepart='.$modulepart);
     
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return select list of groups
     	 *
    @@ -6762,11 +6975,13 @@ class Form
     	 *  @param  string	$include        Array list of groups id to include
     	 * 	@param	int		$enableonly		Array list of groups id to be enabled. All other must be disabled
     	 * 	@param	string	$force_entity	'0' or Ids of environment to force
    +	 * 	@param	bool	$multiple		add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
     	 *  @return	string
     	 *  @see select_dolusers
     	 */
    -	function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity='0')
    +	function select_dolgroups($selected='', $htmlname='groupid', $show_empty=0, $exclude='', $disabled=0, $include='', $enableonly='', $force_entity='0', $multiple=false)
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		// Permettre l'exclusion de groupes
    @@ -6774,6 +6989,8 @@ class Form
     		// Permettre l'inclusion de groupes
     		if (is_array($include))	$includeGroups = implode("','",$include);
     
    +		if (!is_array($selected)) $selected = array($selected);
    +
     		$out='';
     
     		// On recherche les groupes
    @@ -6805,13 +7022,13 @@ class Form
     			include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
     		   	$out .= ajax_combobox($htmlname);
     
    -			$out.= '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'"'.($disabled?' disabled':'').'>';
    +			$out.= '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.($multiple ? '[]' : '').'" '.($multiple ? 'multiple' : '').' '.($disabled?' disabled':'').'>';
     
     			$num = $this->db->num_rows($resql);
     			$i = 0;
     			if ($num)
     			{
    -				if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'>&nbsp;</option>'."\n";
    +				if ($show_empty && !$multiple) $out.= '<option value="-1"'.(in_array(-1,$selected)?' selected':'').'>&nbsp;</option>'."\n";
     
     				while ($i < $num)
     				{
    @@ -6821,7 +7038,7 @@ class Form
     
     					$out.= '<option value="'.$obj->rowid.'"';
     					if ($disableline) $out.= ' disabled';
    -					if ((is_object($selected) && $selected->id == $obj->rowid) || (! is_object($selected) && $selected == $obj->rowid))
    +					if ((is_object($selected[0]) && $selected[0]->id == $obj->rowid) || (! is_object($selected[0]) && in_array($obj->rowid,$selected) ))
     					{
     						$out.= ' selected';
     					}
    @@ -6839,7 +7056,7 @@ class Form
     			}
     			else
     			{
    -				if ($show_empty) $out.= '<option value="-1"'.($selected==-1?' selected':'').'></option>'."\n";
    +				if ($show_empty) $out.= '<option value="-1"'.(in_array(-1,$selected)?' selected':'').'></option>'."\n";
     				$out.= '<option value="" disabled>'.$langs->trans("NoUserGroupDefined").'</option>';
     			}
     			$out.= '</select>';
    @@ -6888,17 +7105,22 @@ class Form
                 	$("#checkallactions").click(function() {
                         if($(this).is(\':checked\')){
                             console.log("We check all");
    -                		$(".'.$cssclass.'").prop(\'checked\', true);
    +                		$(".'.$cssclass.'").prop(\'checked\', true).trigger(\'change\');
                         }
                         else
                         {
                             console.log("We uncheck all");
    -                		$(".'.$cssclass.'").prop(\'checked\', false);
    +                		$(".'.$cssclass.'").prop(\'checked\', false).trigger(\'change\');
                         }'."\n";
     		if ($calljsfunction) $out.='if (typeof initCheckForSelect == \'function\') { initCheckForSelect(0); } else { console.log("No function initCheckForSelect found. Call won\'t be done."); }';
     		$out.='         });
    -                });
    -            </script>';
    +
    +        	$(".checkforselect").change(function() {
    +				$(this).closest("tr").toggleClass("highlight", this.checked);
    +			});
    +
    + 	});
    +    </script>';
     
     		return $out;
     	}
    @@ -7090,6 +7312,4 @@ class Form
     
     		return $out;
     	}
    -
     }
    -
    diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php
    index 17e437f5223..5ffaf0463a6 100644
    --- a/htdocs/core/class/html.formaccounting.class.php
    +++ b/htdocs/core/class/html.formaccounting.class.php
    @@ -35,10 +35,17 @@ class FormAccounting extends Form
     
     	private $options_cache = array();
     
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +   /**
     	* Constructor
     	*
     	* @param		DoliDB		$db      Database handler
    @@ -48,6 +55,7 @@ class FormAccounting extends Form
     	    $this->db = $db;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return list of journals with label by nature
     	 *
    @@ -64,6 +72,7 @@ class FormAccounting extends Form
     	 */
     	function select_journal($selectid, $htmlname = 'journal', $nature=0, $showempty = 0, $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='', $disabledajaxcombo=0)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$out = '';
    @@ -129,6 +138,7 @@ class FormAccounting extends Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return list of accounting category.
          * 	Use mysoc->country_id or mysoc->country_code so they must be defined.
    @@ -143,6 +153,7 @@ class FormAccounting extends Form
          */
         function select_accounting_category($selected='',$htmlname='account_category', $useempty=0, $maxlen=0, $help=1, $allcountries=0)
         {
    +        // phpcs:enable
             global $db,$langs,$user,$mysoc;
     
             if (empty($mysoc->country_id) && empty($mysoc->country_code) && empty($allcountries))
    @@ -209,6 +220,7 @@ class FormAccounting extends Form
             print $out;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return select filter with date of transaction
     	 *
    @@ -216,7 +228,9 @@ class FormAccounting extends Form
     	 * @param string $selectedkey Value
     	 * @return string HTML edit field
     	 */
    -	function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '') {
    +    function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '')
    +    {
    +        // phpcs:enable
     		$options = array();
     
     		$sql = 'SELECT DISTINCT import_key from ' . MAIN_DB_PREFIX . 'accounting_bookkeeping';
    @@ -239,6 +253,7 @@ class FormAccounting extends Form
     		return Form::selectarray($htmlname, $options, $selectedkey);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return list of accounts with label by chart of accounts
     	 *
    @@ -254,6 +269,7 @@ class FormAccounting extends Form
     	 */
     	function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='')
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
    @@ -330,6 +346,7 @@ class FormAccounting extends Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return list of auxilary thirdparty accounts
     	 *
    @@ -339,7 +356,9 @@ class FormAccounting extends Form
     	 * @param string   $morecss        More css
     	 * @return string                  String with HTML select
     	 */
    -	function select_auxaccount($selectid, $htmlname='account_num_aux', $showempty=0, $morecss='maxwidth200') {
    +    function select_auxaccount($selectid, $htmlname='account_num_aux', $showempty=0, $morecss='maxwidth200')
    +    {
    +        // phpcs:enable
     
     		$aux_account = array();
     
    @@ -389,6 +408,7 @@ class FormAccounting extends Form
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return HTML combo list of years existing into book keepping
     	 *
    @@ -400,6 +420,7 @@ class FormAccounting extends Form
     	 */
     	function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
     	{
    +        // phpcs:enable
     	    global $conf;
     
     		$out_array = array();
    @@ -428,4 +449,3 @@ class FormAccounting extends Form
     		}
     	}
     }
    -
    diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php
    index 451ee0d700d..25a3973cbd8 100644
    --- a/htdocs/core/class/html.formactions.class.php
    +++ b/htdocs/core/class/html.formactions.class.php
    @@ -29,8 +29,15 @@
      */
     class FormActions
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**
    @@ -41,10 +48,10 @@ class FormActions
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Show list of action status
          *
    @@ -59,6 +66,7 @@ class FormActions
          */
         function form_select_status_action($formname, $selected, $canedit=1, $htmlname='complete', $showempty=0, $onlyselect=0, $morecss='maxwidth100')
         {
    +        // phpcs:enable
             global $langs,$conf;
     
             $listofstatus = array(
    @@ -306,6 +314,7 @@ class FormActions
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Output html select list of type of event
          *
    @@ -320,6 +329,7 @@ class FormActions
          */
         function select_type_actions($selected='', $htmlname='actioncode', $excludetype='', $onlyautoornot=0, $hideinfohelp=0, $multiselect=0, $nooutput=0)
         {
    +        // phpcs:enable
             global $langs,$user,$form,$conf;
     
             if (! is_object($form)) $form=new Form($db);
    @@ -359,5 +369,4 @@ class FormActions
             else print $out;
             return '';
         }
    -
     }
    diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php
    index fd0470c63f4..510b34c8f47 100644
    --- a/htdocs/core/class/html.formadmin.class.php
    +++ b/htdocs/core/class/html.formadmin.class.php
    @@ -41,9 +41,9 @@ class FormAdmin
     	function __construct($db)
     	{
     		$this->db = $db;
    -		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Return html select list with available languages (key='en_US', value='United States' for example)
     	 *
    @@ -55,11 +55,13 @@ class FormAdmin
     	 *      @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
    -	 *      @param      int         $showcode       Add language code into label
    +	 *      @param      int         $showcode       1=Add language code into label at begining, 2=Add language code into label at end
    +	 *      @param		int			$forcecombo		Force to use combo box (so no ajax beautify effect)
     	 *      @return		string						Return HTML select string with list of languages
    -	 */
    -	function select_language($selected='', $htmlname='lang_id', $showauto=0, $filter=null, $showempty='', $showwarning=0, $disabled=0, $morecss='', $showcode=0)
    +     */
    +	function select_language($selected='', $htmlname='lang_id', $showauto=0, $filter=null, $showempty='', $showwarning=0, $disabled=0, $morecss='', $showcode=0, $forcecombo=0)
     	{
    +		// phpcs:enable
     		global $langs;
     
     		$langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT,12);
    @@ -87,8 +89,9 @@ class FormAdmin
     
     		foreach ($langs_available as $key => $value)
     		{
    -		    $valuetoshow=$value;
    -		    if ($showcode) $valuetoshow=$key.' - '.$value;
    +			$valuetoshow=$value;
    +			if ($showcode == 1) $valuetoshow=$key.' - '.$value;
    +			if ($showcode == 2) $valuetoshow=$value.' ('.$key.')';
     
     			if ($filter && is_array($filter))
     			{
    @@ -109,12 +112,16 @@ class FormAdmin
     		$out.= '</select>';
     
     		// Make select dynamic
    -        include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
    -        $out.= ajax_combobox($htmlname);
    +		if (! $forcecombo)
    +		{
    +			include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
    +			$out.= ajax_combobox($htmlname);
    +		}
     
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *    Return list of available menus (eldy_backoffice, ...)
          *
    @@ -126,6 +133,7 @@ class FormAdmin
          */
         function select_menu($selected, $htmlname, $dirmenuarray, $moreattrib='')
         {
    +		// phpcs:enable
             global $langs,$conf;
     
             // Clean parameters
    @@ -204,6 +212,7 @@ class FormAdmin
     		print '</select>';
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return combo list of available menu families
          *
    @@ -214,6 +223,7 @@ class FormAdmin
          */
         function select_menu_families($selected, $htmlname, $dirmenuarray)
         {
    +		// phpcs:enable
     		global $langs,$conf;
     
             //$expdevmenu=array('smartphone_backoffice.php','smartphone_frontoffice.php');  // Menu to disable if $conf->global->MAIN_FEATURES_LEVEL is not set
    @@ -275,6 +285,7 @@ class FormAdmin
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return a HTML select list of timezones
          *
    @@ -284,6 +295,7 @@ class FormAdmin
          */
         function select_timezone($selected,$htmlname)
         {
    +		// phpcs:enable
     		global $langs,$conf;
     
             print '<select class="flat" id="'.$htmlname.'" name="'.$htmlname.'">';
    @@ -327,17 +339,19 @@ class FormAdmin
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *    	Return html select list with available languages (key='en_US', value='United States' for example)
    +	 *  Return html select list with available languages (key='en_US', value='United States' for example)
     	 *
    -	 *    	@param      string	$selected       Paper format pre-selected
    -	 *    	@param      string	$htmlname       Name of HTML select field
    -	 * 		@param		string	$filter			Value to filter on code
    -	 * 		@param		int		$showempty		Add empty value
    -	 * 		@return		string					Return HTML output
    +	 *  @param      string	$selected       Paper format pre-selected
    +	 *  @param      string	$htmlname       Name of HTML select field
    +	 * 	@param		string	$filter			Value to filter on code
    +	 * 	@param		int		$showempty		Add empty value
    +	 * 	@return		string					Return HTML output
     	 */
     	function select_paper_format($selected='',$htmlname='paperformat_id',$filter=0,$showempty=0)
     	{
    +		// phpcs:enable
     		global $langs;
     
     		$langs->load("dict");
    diff --git a/htdocs/core/class/html.formbank.class.php b/htdocs/core/class/html.formbank.class.php
    index 4ee00555b85..9cf60cc45b1 100644
    --- a/htdocs/core/class/html.formbank.class.php
    +++ b/htdocs/core/class/html.formbank.class.php
    @@ -29,8 +29,15 @@
      */
     class FormBank
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**
    diff --git a/htdocs/core/class/html.formbarcode.class.php b/htdocs/core/class/html.formbarcode.class.php
    index dba8c5d24e5..eb08aab6de7 100644
    --- a/htdocs/core/class/html.formbarcode.class.php
    +++ b/htdocs/core/class/html.formbarcode.class.php
    @@ -1,21 +1,22 @@
     <?php
    -/* Copyright (C) 2007-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2008-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
    -*
    -* 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 <http://www.gnu.org/licenses/>.
    -*
    -*/
    +/* Copyright (C) 2007-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2008-2012  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + *
    + */
     
     /**
      *      \file       htdocs/core/class/html.formbarcode.class.php
    @@ -28,19 +29,25 @@
      */
     class FormBarCode
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error='';
     
     
         /**
    -     *	Constructor
    +     *  Constructor
          *
    -     *	@param	DoliDB		$db		Database handler
    +     *  @param  DoliDB		$db		Database handler
          */
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -96,17 +103,35 @@ class FormBarCode
             return $select_encoder;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *	Return form to select type of barcode
    +     *  Print form to select type of barcode
          *
    -     *	@param	int		$selected          Id code pre-selected
    -     *  @param	string	$htmlname          Name of HTML select field
    -     *  @param  int		$useempty          Affiche valeur vide dans liste
    -     *  @return	void
    +     *  @param  int     $selected          Id code pre-selected
    +     *  @param  string  $htmlname          Name of HTML select field
    +     *  @param  int     $useempty          Affiche valeur vide dans liste
    +     *  @return void
    +     *  @deprecated
          */
    -    function select_barcode_type($selected='',$htmlname='barcodetype_id',$useempty=0)
    +    function select_barcode_type($selected='', $htmlname='barcodetype_id', $useempty=0)
         {
    -        global $langs,$conf;
    +        // phpcs:enable
    +        print $this->selectBarcodeType($selected, $htmlname, $useempty);
    +    }
    +
    +    /**
    +     *  Return html form to select type of barcode
    +     *
    +     *  @param  int     $selected          Id code pre-selected
    +     *  @param  string  $htmlname          Name of HTML select field
    +     *  @param  int     $useempty          Display empty value in select
    +     *  @return string
    +     */
    +    function selectBarcodeType($selected='', $htmlname='barcodetype_id', $useempty=0)
    +    {
    +        global $langs, $conf;
    +
    +        $out = '';
     
             $sql = "SELECT rowid, code, libelle";
             $sql.= " FROM ".MAIN_DB_PREFIX."c_barcode_type";
    @@ -115,46 +140,40 @@ class FormBarCode
             $sql.= " ORDER BY code";
     
             $result = $this->db->query($sql);
    -        if ($result)
    -        {
    +        if ($result) {
                 $num = $this->db->num_rows($result);
                 $i = 0;
     
    -            if ($useempty && $num > 0)
    -            {
    -                print '<select class="flat minwidth75imp" name="'.$htmlname.'" id="select_'.$htmlname.'">';
    -                print '<option value="0">&nbsp;</option>';
    -            }
    -            else
    -            {
    +            if ($useempty && $num > 0) {
    +                $out .= '<select class="flat minwidth75imp" name="' . $htmlname . '" id="select_' . $htmlname . '">';
    +                $out .= '<option value="0">&nbsp;</option>';
    +            } else {
                     $langs->load("errors");
    -                print '<select disabled class="flat minwidth75imp" name="'.$htmlname.'" id="select_'.$htmlname.'">';
    -                print '<option value="0" selected>'.$langs->trans('ErrorNoActivatedBarcode').'</option>';
    +                $out .= '<select disabled class="flat minwidth75imp" name="' . $htmlname . '" id="select_' . $htmlname . '">';
    +                $out .= '<option value="0" selected>' . $langs->trans('ErrorNoActivatedBarcode') . '</option>';
                 }
     
    -            while ($i < $num)
    -            {
    +            while ($i < $num) {
                     $obj = $this->db->fetch_object($result);
    -                if ($selected == $obj->rowid)
    -                {
    -                    print '<option value="'.$obj->rowid.'" selected>';
    +                if ($selected == $obj->rowid) {
    +                    $out .= '<option value="' . $obj->rowid . '" selected>';
    +                } else {
    +                    $out .= '<option value="' . $obj->rowid . '">';
                     }
    -                else
    -                {
    -                    print '<option value="'.$obj->rowid.'">';
    -                }
    -                print $obj->libelle;
    -                print '</option>';
    +                $out .= $obj->libelle;
    +                $out .= '</option>';
                     $i++;
                 }
    -            print "</select>";
    -            print ajax_combobox("select_".$htmlname);
    +            $out .= "</select>";
    +            $out .= ajax_combobox("select_".$htmlname);
             }
             else {
                 dol_print_error($this->db);
             }
    +        return $out;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Show form to select type of barcode
          *
    @@ -162,23 +181,37 @@ class FormBarCode
          *  @param  int			$selected    	Id condition preselected
          *  @param  string		$htmlname    	Nom du formulaire select
          *  @return	void
    +     *  @deprecated
          */
         function form_barcode_type($page, $selected='', $htmlname='barcodetype_id')
         {
    -        global $langs,$conf;
    -        if ($htmlname != "none")
    -        {
    -            print '<form method="post" action="'.$page.'">';
    -            print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    -            print '<input type="hidden" name="action" value="set'.$htmlname.'">';
    -            print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
    -            print '<tr><td>';
    -            $this->select_barcode_type($selected, $htmlname, 1);
    -            print '</td>';
    -            print '<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'">';
    -            print '</td></tr></table></form>';
    -        }
    +        // phpcs:enable
    +        print $this->formBarcodeType($page, $selected, $htmlname);
         }
     
    +    /**
    +     *  Return html form to select type of barcode
    +     *
    +     *  @param  string      $page           Page
    +     *  @param  int         $selected       Id condition preselected
    +     *  @param  string      $htmlname       Nom du formulaire select
    +     *  @return string
    +     */
    +    function formBarcodeType($page, $selected='', $htmlname='barcodetype_id')
    +    {
    +        global $langs, $conf;
    +        $out = '';
    +        if ($htmlname != "none") {
    +            $out .= '<form method="post" action="' . $page . '">';
    +            $out .= '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
    +            $out .= '<input type="hidden" name="action" value="set'.$htmlname.'">';
    +            $out .= '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
    +            $out .= '<tr><td>';
    +            $out .= $this->selectBarcodeType($selected, $htmlname, 1);
    +            $out .= '</td>';
    +            $out .= '<td align="left"><input type="submit" class="button" value="' . $langs->trans("Modify") . '">';
    +            $out .= '</td></tr></table></form>';
    +        }
    +        return $out;
    +    }
     }
    -
    diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php
    index 4c7c1891a7a..273a84cbc94 100644
    --- a/htdocs/core/class/html.formcompany.class.php
    +++ b/htdocs/core/class/html.formcompany.class.php
    @@ -31,10 +31,15 @@
      */
     class FormCompany
     {
    -	var $db;
    -	var $error;
    -
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Constructor
    @@ -44,11 +49,10 @@ class FormCompany
     	function __construct($db)
     	{
     		$this->db = $db;
    -
    -		return 1;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Return list of labels (translated) of third parties type
     	 *
    @@ -58,6 +62,7 @@ class FormCompany
     	 */
     	function typent_array($mode=0, $filter='')
     	{
    +        // phpcs:enable
     		global $langs,$mysoc;
     
     		$effs = array();
    @@ -90,6 +95,7 @@ class FormCompany
     		return $effs;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoie la liste des types d'effectifs possibles (pas de traduction car nombre)
     	 *
    @@ -99,6 +105,7 @@ class FormCompany
     	 */
     	function effectif_array($mode=0, $filter='')
     	{
    +        // phpcs:enable
     		$effs = array();
     
     		$sql = "SELECT id, code, libelle";
    @@ -128,6 +135,7 @@ class FormCompany
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Affiche formulaire de selection des modes de reglement
     	 *
    @@ -139,6 +147,7 @@ class FormCompany
     	 */
     	function form_prospect_level($page, $selected='', $htmlname='prospect_level_id', $empty=0)
     	{
    +        // phpcs:enable
     		global $user, $langs;
     
     		print '<form method="post" action="'.$page.'">';
    @@ -177,6 +186,7 @@ class FormCompany
     		print '</form>';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Retourne la liste deroulante des departements/province/cantons tout pays confondu ou pour un pays donne.
     	 *   Dans le cas d'une liste tout pays confondus, l'affichage fait une rupture sur le pays.
    @@ -191,9 +201,11 @@ class FormCompany
     	 */
     	function select_departement($selected='',$country_codeid=0, $htmlname='state_id')
     	{
    +        // phpcs:enable
     		print $this->select_state($selected,$country_codeid, $htmlname);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Retourne la liste deroulante des departements/province/cantons tout pays confondu ou pour un pays donne.
     	 *    Dans le cas d'une liste tout pays confondus, l'affichage fait une rupture sur le pays.
    @@ -209,6 +221,7 @@ class FormCompany
     	 */
     	function select_state($selected='',$country_codeid=0, $htmlname='state_id')
     	{
    +        // phpcs:enable
     		global $conf,$langs,$user;
     
     		dol_syslog(get_class($this)."::select_departement selected=".$selected.", country_codeid=".$country_codeid,LOG_DEBUG);
    @@ -308,6 +321,7 @@ class FormCompany
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Retourne la liste deroulante des regions actives dont le pays est actif
     	 *   La cle de la liste est le code (il peut y avoir plusieurs entree pour
    @@ -320,6 +334,7 @@ class FormCompany
     	 */
     	function select_region($selected='',$htmlname='region_id')
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     		$langs->load("dict");
     
    @@ -374,6 +389,7 @@ class FormCompany
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return combo list with people title
     	 *
    @@ -384,6 +400,7 @@ class FormCompany
     	 */
     	function select_civility($selected='',$htmlname='civility_id',$morecss='maxwidth100')
     	{
    +        // phpcs:enable
     		global $conf,$langs,$user;
     		$langs->load("dict");
     
    @@ -430,6 +447,7 @@ class FormCompany
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Retourne la liste deroulante des formes juridiques tous pays confondus ou pour un pays donne.
     	 *    Dans le cas d'une liste tous pays confondu, on affiche une rupture sur le pays.
    @@ -443,9 +461,11 @@ class FormCompany
     	 */
     	function select_forme_juridique($selected='', $country_codeid=0, $filter='')
     	{
    +        // phpcs:enable
     		print $this->select_juridicalstatus($selected, $country_codeid, $filter);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Retourne la liste deroulante des formes juridiques tous pays confondus ou pour un pays donne.
     	 *    Dans le cas d'une liste tous pays confondu, on affiche une rupture sur le pays
    @@ -458,6 +478,7 @@ class FormCompany
     	 */
     	function select_juridicalstatus($selected='', $country_codeid=0, $filter='', $htmlname='forme_juridique_code')
     	{
    +        // phpcs:enable
     		global $conf,$langs,$user;
     		$langs->load("dict");
     
    @@ -740,6 +761,7 @@ class FormCompany
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return a select list with zip codes and their town
     	 *
    @@ -754,6 +776,7 @@ class FormCompany
     	 */
     	function select_ziptown($selected='', $htmlname='zipcode', $fields='', $fieldsize=0, $disableautocomplete=0, $moreattrib='',$morecss='')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$out='';
    @@ -771,6 +794,7 @@ class FormCompany
     		return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return HTML string to use as input of professional id into a HTML page (siren, siret, etc...)
          *
    @@ -783,6 +807,7 @@ class FormCompany
          */
         function get_input_id_prof($idprof,$htmlname,$preselected,$country_code,$morecss='maxwidth100onsmartphone quatrevingtpercent')
         {
    +        // phpcs:enable
             global $conf,$langs;
     
             $formlength=0;
    @@ -821,6 +846,7 @@ class FormCompany
             return $out;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return a HTML select with localtax values for thirdparties
          *
    @@ -831,10 +857,11 @@ class FormCompany
          */
         function select_localtax($local, $selected, $htmlname)
         {
    -    	$tax=get_localtax_by_third($local);
    +        // phpcs:enable
    +        $tax=get_localtax_by_third($local);
     
    -    	$num = $this->db->num_rows($tax);
    -    	$i = 0;
    +        $num = $this->db->num_rows($tax);
    +        $i = 0;
         	if ($num)
         	{
         		$valors=explode(":", $tax);
    @@ -861,6 +888,4 @@ class FormCompany
         		}
         	}
         }
    -
     }
    -
    diff --git a/htdocs/core/class/html.formcontract.class.php b/htdocs/core/class/html.formcontract.class.php
    index f4902e4912e..5bdb00cfc40 100644
    --- a/htdocs/core/class/html.formcontract.class.php
    +++ b/htdocs/core/class/html.formcontract.class.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2012-2013  Charles-Fr BENKE		<charles.fr@benke.fr>
    +/* Copyright (C) 2012-2018  Charlene BENKE	<charlie@patas-monkey.com>
      *
      * 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
    @@ -27,8 +27,15 @@
      */
     class FormContract
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**
    @@ -42,6 +49,7 @@ class FormContract
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show a combo list with contracts qualified for a third party
     	 *
    @@ -54,18 +62,29 @@ class FormContract
     	 */
     	function select_contract($socid=-1, $selected='', $htmlname='contrattid', $maxlength=16, $showempty=1)
     	{
    +        // phpcs:enable
     		global $db,$user,$conf,$langs;
     
     		$hideunselectables = false;
    -		if (! empty($conf->global->PROJECT_HIDE_UNSELECTABLES)) $hideunselectables = true;
    +		if (! empty($conf->global->CONTRACT_HIDE_UNSELECTABLES)) $hideunselectables = true;
     
     		// Search all contacts
     		$sql = 'SELECT c.rowid, c.ref, c.fk_soc, c.statut';
     		$sql.= ' FROM '.MAIN_DB_PREFIX .'contrat as c';
     		$sql.= " WHERE c.entity = ".$conf->entity;
     		//if ($contratListId) $sql.= " AND c.rowid IN (".$contratListId.")";
    +		if ($socid > 0)
    +		{
    +			// CONTRACT_ALLOW_TO_LINK_FROM_OTHER_COMPANY is 'all' or a list of ids separated by coma.
    +		    	if (empty($conf->global->CONTRACT_ALLOW_TO_LINK_FROM_OTHER_COMPANY))
    +			    $sql.= " AND (c.fk_soc=".$socid." OR c.fk_soc IS NULL)";
    +		    	else if ($conf->global->CONTRACT_ALLOW_TO_LINK_FROM_OTHER_COMPANY != 'all')
    +			{
    +		        	$sql.= " AND (c.fk_soc IN (".$socid.", ".$conf->global->CONTRACT_ALLOW_TO_LINK_FROM_OTHER_COMPANY.") ";
    +				$sql.= " OR c.fk_soc IS NULL)";
    +		    	}
    +		}
     		if ($socid == 0) $sql.= " AND (c.fk_soc = 0 OR c.fk_soc IS NULL)";
    -		if ($socid > 0)  $sql.= " AND (c.fk_soc=".$socid." OR c.fk_soc IS NULL)";
     		$sql.= " ORDER BY c.ref ";
     
     		dol_syslog(get_class($this)."::select_contract", LOG_DEBUG);
    @@ -98,12 +117,12 @@ class FormContract
     						else
     						{
     							$disabled=0;
    -							if (! $obj->statut > 0)
    +							if ( $obj->statut ==  0)
     							{
     								$disabled=1;
     								$labeltoshow.=' ('.$langs->trans("Draft").')';
     							}
    -							if ($socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
    +							if ( empty($conf->global->CONTRACT_ALLOW_TO_LINK_FROM_OTHER_COMPANY) &&  $socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
     							{
     								$disabled=1;
     								$labeltoshow.=' - '.$langs->trans("LinkedToAnotherCompany");
    @@ -130,14 +149,14 @@ class FormContract
     			}
     			print '</select>';
     			$db->free($resql);
    -			
    +
     			if (!empty($conf->use_javascript_ajax))
     			{
     				// Make select dynamic
     				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
     				print ajax_combobox($htmlname);
     			}
    -			
    +
     			return $num;
     		}
     		else
    @@ -146,7 +165,7 @@ class FormContract
     			return -1;
     		}
     	}
    -	
    +
     	/**
     	 *	Show a form to select a contract
     	 *
    @@ -156,12 +175,12 @@ class FormContract
     	 *	@param  string	$htmlname   Nom de la zone html
     	 *	@param	int		$maxlength	Maximum length of label
     	 *	@param	int		$showempty	Show empty line
    -	 *	@return int         		Nbr of project if OK, <0 if KO
    +	 *	@return int                 Nbr of project if OK, <0 if KO
     	 */
     	function formSelectContract($page, $socid=-1, $selected='', $htmlname='contrattid', $maxlength=16, $showempty=1)
     	{
    -	    global $langs;
    -	
    +        global $langs;
    +
             print "\n";
             print '<form method="post" action="'.$page.'">';
             print '<input type="hidden" name="action" value="setcontract">';
    @@ -169,6 +188,5 @@ class FormContract
             $this->select_contract($socid, $selected, $htmlname, $maxlength, $showempty);
             print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
             print '</form>';
    -	}	
    -	
    +    }
     }
    diff --git a/htdocs/core/class/html.formcron.class.php b/htdocs/core/class/html.formcron.class.php
    index 255868f02a5..94747481cb0 100644
    --- a/htdocs/core/class/html.formcron.class.php
    +++ b/htdocs/core/class/html.formcron.class.php
    @@ -28,8 +28,15 @@
      */
     class FormCron extends Form
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Constructor
    @@ -39,10 +46,10 @@ class FormCron extends Form
     	function __construct($db)
     	{
     		$this->db = $db;
    -		return 1;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Display On Off selector
     	 *
    @@ -53,6 +60,7 @@ class FormCron extends Form
     	 */
     	function select_typejob($htmlname,$selected=0,$readonly=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$langs->load('cron@cron');
    diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
    index 72e14fefdd6..5824d2ca5ec 100644
    --- a/htdocs/core/class/html.formfile.class.php
    +++ b/htdocs/core/class/html.formfile.class.php
    @@ -36,7 +36,11 @@ class FormFile
     {
     	private $db;
     
    +	/**
    +	 * @var string Error code (or message)
    +	 */
     	public $error;
    +
     	public $numoffiles;
     	public $infofiles;			// Used to return informations by function getDocumentsLink
     
    @@ -50,10 +54,10 @@ class FormFile
     	{
     		$this->db = $db;
     		$this->numoffiles=0;
    -		return 1;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show form to upload a new file.
     	 *
    @@ -75,6 +79,7 @@ class FormFile
     	 */
     	function form_attach_new_file($url, $title='', $addcancel=0, $sectionid=0, $perm=1, $size=50, $object='', $options='', $useajax=1, $savingdocmask='', $linkfiles=1, $htmlname='formuserfile', $accept='', $sectiondir='')
     	{
    +        // phpcs:enable
     		global $conf,$langs, $hookmanager;
     		$hookmanager->initHooks(array('formfile'));
     
    @@ -226,6 +231,7 @@ class FormFile
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Show the box with list of available documents for object
     	 *
    @@ -250,6 +256,7 @@ class FormFile
     	 */
     	function show_documents($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$notused=0,$noform=0,$param='',$title='',$buttonlabel='',$codelang='')
     	{
    +        // phpcs:enable
     		$this->numoffiles=0;
     		print $this->showdocuments($modulepart,$modulesubdir,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$notused,$noform,$param,$title,$buttonlabel,$codelang);
     		return $this->numoffiles;
    @@ -303,7 +310,7 @@ class FormFile
     		$param.= 'entity='.(!empty($object->entity)?$object->entity:$conf->entity);
     
     		$printer=0;
    -		if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport')))	// The direct print feature is implemented only for such elements
    +		if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport','livraison')))	// The direct print feature is implemented only for such elements
     		{
     			$printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
     		}
    @@ -672,7 +679,7 @@ class FormFile
     				$formadmin=new FormAdmin($this->db);
     				$defaultlang=$codelang?$codelang:$langs->getDefaultLang();
     				$morecss='maxwidth150';
    -				if (! empty($conf->browser->phone)) $morecss='maxwidth100';
    +				if ($conf->browser->layout == 'phone') $morecss='maxwidth100';
     				$out.= $formadmin->select_language($defaultlang, 'lang_id', 0, 0, 0, 0, 0, $morecss);
     			}
     			else
    @@ -711,7 +718,6 @@ class FormFile
     				$reshook = $hookmanager->executeHooks('formBuilddocOptions',$parameters,$GLOBALS['object']);
     				$out.= $hookmanager->resPrint;
     			}
    -
     		}
     
     		// Get list of files
    @@ -841,7 +847,6 @@ class FormFile
     			{
     				$out.='<tr><td colspan="'.(3+($addcolumforpicto?1:0)).'" class="opacitymedium">'.$langs->trans("None").'</td></tr>'."\n";
     			}
    -
     		}
     
     		if ($headershown)
    @@ -906,7 +911,7 @@ class FormFile
     		if (! empty($file_list))
     		{
     			$out='<dl class="dropdown inline-block">
    -    			<dt><a data-ajax="false" href="#" onClick="return false;">'.img_picto('', 'listlight', '', 0, 0, 0, '', 'valignbottom').'</a></dt>
    +    			<dt><a data-ajax="false" href="#" onClick="return false;">'.img_picto('', 'listlight', '', 0, 0, 0, '', 'valignmiddle').'</a></dt>
         			<dd><div class="multichoicedoc" style="position:absolute;left:100px;" ><ul class="ulselectedfields" style="display: none;">';
     			$tmpout='';
     
    @@ -973,6 +978,7 @@ class FormFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show list of documents in $filearray (may be they are all in same directory but may not)
     	 *  This also sync database if $upload_dir is defined.
    @@ -1004,6 +1010,7 @@ class FormFile
     	 */
     	function list_of_documents($filearray,$object,$modulepart,$param='',$forcedownload=0,$relativepath='',$permonobject=1,$useinecm=0,$textifempty='',$maxlength=0,$title='',$url='', $showrelpart=0, $permtoeditline=-1,$upload_dir='',$sortfield='',$sortorder='ASC', $disablemove=1, $addfilterfields=0)
     	{
    +        // phpcs:enable
     		global $user, $conf, $langs, $hookmanager;
     		global $sortfield, $sortorder, $maxheightmini;
     		global $dolibarr_main_url_root;
    @@ -1128,7 +1135,6 @@ class FormFile
     				//var_dump($sortfield.' - '.$sortorder);
     				if ($sortfield && $sortorder)	// If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
     				{
    -					//var_dump($sortfield);
     					$filearray=dol_sort_array($filearray, $sortfield, $sortorder);
     				}
     			}
    @@ -1151,7 +1157,7 @@ class FormFile
     					print '<!-- Line list_of_documents '.$key.' relativepath = '.$relativepath.' -->'."\n";
     					// Do we have entry into database ?
     					print '<!-- In database: position='.$filearray[$key]['position'].' -->'."\n";
    -					print '<tr id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'-AFTER'.$lastrowid.'POS'.($i+1)).'">';
    +					print '<tr class="oddeven" id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'AFTER'.$lastrowid.'POS'.($i+1)).'">';
     
     					// File name
     					print '<td class="minwith200">';
    @@ -1247,12 +1253,9 @@ class FormFile
     								if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1';
     
     								$fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:'');
    -								//if (! empty($object->ref))       $fulllink.='&hashn='.$object->ref;		// Hash of file path
    -								//elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label;		// Hash of file content
     
     								print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' ';
     								print '<input type="text" class="quatrevingtpercent" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
    -								//print ' <a href="'.$fulllink.'">'.$langs->trans("Download").'</a>';	// No target here
     							}
     							else
     							{
    @@ -1288,17 +1291,12 @@ class FormFile
     
     							if ($permtoeditline)
     							{
    -								print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
    +								$paramsectiondir=(in_array($modulepart, array('medias','ecm'))?'&section_dir='.urlencode($relativepath):'');
    +								print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$paramsectiondir.$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
     							}
     						}
     						if ($permonobject)
     						{
    -							/*
    -    						if ($file['level1name'] <> $object->id)
    -    							$filepath=$file['level1name'].'/'.$file['name'];
    -    						else
    -    							$filepath=$file['name'];
    -    						*/
     							$useajax=1;
     							if (! empty($conf->dol_use_jmobile)) $useajax=0;
     							if (empty($conf->use_javascript_ajax)) $useajax=0;
    @@ -1309,7 +1307,7 @@ class FormFile
     
     						if (empty($disablemove))
     						{
    -							if ($nboffiles > 1 && empty($conf->browser->phone)) {
    +							if ($nboffiles > 1 && $conf->browser->layout != 'phone') {
     								print '<td align="center" class="linecolmove tdlineupdown">';
     								if ($i > 0) {
     									print '<a class="lineupdown" href="'.$_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=up&amp;rowid='.$line->id.'">'.img_up('default',0,'imgupforline').'</a>';
    @@ -1320,7 +1318,7 @@ class FormFile
     								print '</td>';
     							}
     							else {
    -							   	print '<td align="center"'.((empty($conf->browser->phone) && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"').'>';
    +							   	print '<td align="center"'.(($conf->browser->layout != 'phone' && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"').'>';
     							   	print '</td>';
     							}
     					   }
    @@ -1370,6 +1368,7 @@ class FormFile
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show list of documents in a directory
     	 *
    @@ -1390,6 +1389,7 @@ class FormFile
     	 */
     	function list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload=0, $relativepath='', $permtodelete=1, $useinecm=0, $textifempty='', $maxlength=0, $url='', $addfilterfields=0)
     	{
    +        // phpcs:enable
     		global $user, $conf, $langs, $form;
     		global $sortfield, $sortorder;
     		global $search_doc_ref;
    @@ -1652,7 +1652,6 @@ class FormFile
     
     		// Include template
     		include DOL_DOCUMENT_ROOT.'/core/tpl/ajax/fileupload_view.tpl.php';
    -
     	}
     
     	/**
    @@ -1824,6 +1823,4 @@ class FormFile
     		}
     		return $out;
     	}
    -
     }
    -
    diff --git a/htdocs/core/class/html.formintervention.class.php b/htdocs/core/class/html.formintervention.class.php
    index b675ba6e674..ae35b74fad9 100644
    --- a/htdocs/core/class/html.formintervention.class.php
    +++ b/htdocs/core/class/html.formintervention.class.php
    @@ -27,8 +27,15 @@
      */
     class FormIntervention
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**
    @@ -42,6 +49,7 @@ class FormIntervention
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show a combo list with contracts qualified for a third party
     	 *
    @@ -54,6 +62,7 @@ class FormIntervention
     	 */
     	function select_interventions($socid=-1, $selected='', $htmlname='interventionid', $maxlength=16, $showempty=1)
     	{
    +        // phpcs:enable
     		global $db,$user,$conf,$langs;
     
     		$out='';
    diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
    index 99f14e973ca..a71a0a15da0 100644
    --- a/htdocs/core/class/html.formmail.class.php
    +++ b/htdocs/core/class/html.formmail.class.php
    @@ -1,9 +1,10 @@
     <?php
     /* Copyright (C) 2005-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2010-2011 Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2005-2012 Regis Houssin	    <regis.houssin@capnetworks.com>
    + * Copyright (C) 2010-2011 Juanjo Menent	    <jmenent@2byte.es>
      * Copyright (C) 2015-2017 Marcos García        <marcosgdf@gmail.com>
    - * Copyright (C) 2015-2017 Nicolas ZABOURI        <info@inovea-conseil.com>
    + * Copyright (C) 2015-2017 Nicolas ZABOURI      <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -35,58 +36,83 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/html.form.class.php';
      */
     class FormMail extends Form
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $withform;				// 1=Include HTML form tag and show submit button, 0=Do not include form tag and submit button, -1=Do not include form tag but include submit button
    +	public $withform;				// 1=Include HTML form tag and show submit button, 0=Do not include form tag and submit button, -1=Do not include form tag but include submit button
     
    -	var $fromname;
    -	var $frommail;
    -	var $replytoname;
    -	var $replytomail;
    -	var $toname;
    -	var $tomail;
    -	var $trackid;
    +	public $fromname;
    +	public $frommail;
    +
    +    /**
    +     * @var string user, company, robot
    +     */
    +    public $fromtype;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fromid;
    +
    +    /**
    +     * @var string thirdparty etc
    +     */
    +    public $totype;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $toid;
    +
    +    public $replytoname;
    +	public $replytomail;
    +	public $toname;
    +	public $tomail;
    +	public $trackid;
    +
    +	public $withsubstit;			// Show substitution array
    +	public $withfrom;
     
    -	var $withsubstit;			// Show substitution array
    -	var $withfrom;
     	/**
     	 * @var int
     	 * @deprecated Fill withto with array before calling method.
     	 * @see withto
     	 */
     	public $withtosocid;
    +
     	/**
     	 * @var int|int[]
     	 */
     	public $withto;				// Show recipient emails
    -	var $withtofree;			// Show free text for recipient emails
    -	var $withtocc;
    -	var $withtoccc;
    -	var $withtopic;
    -	var $withfile;				// 0=No attaches files, 1=Show attached files, 2=Can add new attached files
    -	var $withmaindocfile;		// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
    -	var $withbody;
     
    -	var $withfromreadonly;
    -	var $withreplytoreadonly;
    -	var $withtoreadonly;
    -	var $withtoccreadonly;
    -	var $withtocccreadonly;
    -	var $withtopicreadonly;
    -	var $withfilereadonly;
    -	var $withdeliveryreceipt;
    -	var $withcancel;
    -	var $withfckeditor;
    +	public $withtofree;			// Show free text for recipient emails
    +	public $withtocc;
    +	public $withtoccc;
    +	public $withtopic;
    +	public $withfile;				// 0=No attaches files, 1=Show attached files, 2=Can add new attached files
    +	public $withmaindocfile;		// 1=Add a checkbox "Attach also main document" for mass actions (checked by default), -1=Add checkbox (not checked by default)
    +	public $withbody;
     
    -	var $substit=array();
    -	var $substit_lines=array();
    -	var $param=array();
    +	public $withfromreadonly;
    +	public $withreplytoreadonly;
    +	public $withtoreadonly;
    +	public $withtoccreadonly;
    +	public $withtocccreadonly;
    +	public $withtopicreadonly;
    +	public $withfilereadonly;
    +	public $withdeliveryreceipt;
    +	public $withcancel;
    +	public $withfckeditor;
    +
    +	public $substit=array();
    +	public $substit_lines=array();
    +	public $param=array();
     
     	public $withtouser=array();
     	public $withtoccuser=array();
     
    -	var $error;
    -
     	public $lines_model;
     
     
    @@ -123,10 +149,9 @@ class FormMail extends Form
     		$this->withbodyreadonly=0;
     		$this->withdeliveryreceiptreadonly=0;
     		$this->withfckeditor=-1;	// -1 = Auto
    -
    -		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Clear list of attached files in send mail form (also stored in session)
     	 *
    @@ -134,6 +159,7 @@ class FormMail extends Form
     	 */
     	function clear_attached_files()
     	{
    +        // phpcs:enable
     		global $conf,$user;
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    @@ -148,6 +174,7 @@ class FormMail extends Form
     		unset($_SESSION["listofmimes".$keytoavoidconflict]);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Add a file into the list of attached files (stored in SECTION array)
     	 *
    @@ -158,6 +185,7 @@ class FormMail extends Form
     	 */
     	function add_attached_files($path, $file='', $type='')
     	{
    +        // phpcs:enable
     		$listofpaths=array();
     		$listofnames=array();
     		$listofmimes=array();
    @@ -180,6 +208,7 @@ class FormMail extends Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Remove a file from the list of attached files (stored in SECTION array)
     	 *
    @@ -188,6 +217,7 @@ class FormMail extends Form
     	 */
     	function remove_attached_files($keytodelete)
     	{
    +        // phpcs:enable
     		$listofpaths=array();
     		$listofnames=array();
     		$listofmimes=array();
    @@ -208,6 +238,7 @@ class FormMail extends Form
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return list of attached files (stored in SECTION array)
     	 *
    @@ -215,6 +246,7 @@ class FormMail extends Form
     	 */
     	function get_attached_files()
     	{
    +        // phpcs:enable
     		$listofpaths=array();
     		$listofnames=array();
     		$listofmimes=array();
    @@ -226,6 +258,7 @@ class FormMail extends Form
     		return array('paths'=>$listofpaths, 'names'=>$listofnames, 'mimes'=>$listofmimes);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show the form to input an email
     	 *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
    @@ -237,9 +270,11 @@ class FormMail extends Form
     	 */
     	function show_form($addfileaction='addfile',$removefileaction='removefile')
     	{
    +        // phpcs:enable
     		print $this->get_form($addfileaction,$removefileaction);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Get the form to input an email
     	 *  this->withfile: 0=No attaches files, 1=Show attached files, 2=Can add new attached files
    @@ -252,13 +287,13 @@ class FormMail extends Form
     	 */
     	function get_form($addfileaction='addfile', $removefileaction='removefile')
     	{
    +        // phpcs:enable
     		global $conf, $langs, $user, $hookmanager, $form;
     
     		if (! is_object($form)) $form=new Form($this->db);
     
    -		$langs->load("other");
    -		$langs->load("mails");
    -
    +		// Load translation files required by the page
    +        $langs->loadLangs(array('other', 'mails'));
     
     		// Clear temp files. Must be done at beginning, before call of triggers
     		if (GETPOST('mode','alpha') == 'init' || (GETPOST('modelmailselected','alpha') && GETPOST('modelmailselected','alpha') != '-1'))
    @@ -948,7 +983,7 @@ class FormMail extends Form
     					$url=getOnlinePaymentUrl(0, $typeforonlinepayment, $this->substit['__REF__']);
     					$paymenturl=$url;
     
    -					$validpaymentmethod = getValidOnlinePaymentMethods($paymentmethod);
    +					$validpaymentmethod = getValidOnlinePaymentMethods('');
     				}
     
     				if (count($validpaymentmethod) > 0 && $paymenturl)
    @@ -1394,7 +1429,6 @@ class FormMail extends Form
     
     		return $tmparray;
     	}
    -
     }
     
     
    @@ -1403,8 +1437,16 @@ class FormMail extends Form
      */
     class ModelMail
     {
    +	/**
    +	 * @var int ID
    +	 */
     	public $id;
    -	public $label;
    +
    +	/**
    +     * @var string Model mail label
    +     */
    +    public $label;
    +
     	public $topic;
     	public $content;
     	public $content_lines;
    diff --git a/htdocs/core/class/html.formmailing.class.php b/htdocs/core/class/html.formmailing.class.php
    index e3e6ce4cbf9..067692f5094 100644
    --- a/htdocs/core/class/html.formmailing.class.php
    +++ b/htdocs/core/class/html.formmailing.class.php
    @@ -23,11 +23,14 @@
     require_once DOL_DOCUMENT_ROOT .'/core/class/html.form.class.php';
     
     /**
    - *	Class to offer components to list and upload files
    + *  Class to offer components to list and upload files
      */
     class FormMailing extends Form
     {
    -	public $errors=array();
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
     	/**
     	 * Output a select with destinaries status
    @@ -37,7 +40,8 @@ class FormMailing extends Form
     	 * @param integer  $show_empty     Show empty option
     	 * @return string HTML select
     	 */
    -	public function selectDestinariesStatus($selectedid='',$htmlname='dest_status', $show_empty=0) {
    +    public function selectDestinariesStatus($selectedid='', $htmlname='dest_status', $show_empty=0)
    +    {
     
     		global $langs;
     		$langs->load("mails");
    @@ -54,5 +58,5 @@ class FormMailing extends Form
             $options = $options + $mailing->statut_dest;
     
             return Form::selectarray($htmlname, $options, $selectedid, 0, 0, 0, '', 1);
    -	}
    +    }
     }
    diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php
    index da8acce83d4..cdd827145b0 100644
    --- a/htdocs/core/class/html.formmargin.class.php
    +++ b/htdocs/core/class/html.formmargin.class.php
    @@ -28,8 +28,15 @@
      */
     class FormMargin
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**
    @@ -40,8 +47,6 @@ class FormMargin
         function __construct($db)
         {
             $this->db = $db;
    -
    -        return 1;
         }
     
     
    @@ -275,6 +280,5 @@ class FormMargin
     		print '</table>';
     		print '</div>';
     	}
    -
     }
     
    diff --git a/htdocs/core/class/html.formorder.class.php b/htdocs/core/class/html.formorder.class.php
    index 68fa96e03ee..781b3f76e4f 100644
    --- a/htdocs/core/class/html.formorder.class.php
    +++ b/htdocs/core/class/html.formorder.class.php
    @@ -100,6 +100,5 @@ class FormOrder extends Form
     
     		return 1;
     	}
    -
     }
     
    diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php
    index 69fe03ecaa1..d2800ce1906 100644
    --- a/htdocs/core/class/html.formother.class.php
    +++ b/htdocs/core/class/html.formother.class.php
    @@ -38,7 +38,11 @@
     class FormOther
     {
         private $db;
    -    public $error;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error;
     
     
         /**
    @@ -49,11 +53,10 @@ class FormOther
         function __construct($db)
         {
             $this->db = $db;
    -
    -        return 1;
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return HTML select list of export models
          *
    @@ -64,12 +67,13 @@ class FormOther
          *    @param    int		$fk_user          Utilisateur créant le modèle
          *    @return	void
          */
    -    function select_export_model($selected='',$htmlname='exportmodelid',$type='',$useempty=0, $fk_user=null)
    +    function select_export_model($selected='', $htmlname='exportmodelid', $type='', $useempty=0, $fk_user=null)
         {
    +        // phpcs:enable
             $sql = "SELECT rowid, label";
             $sql.= " FROM ".MAIN_DB_PREFIX."export_model";
             $sql.= " WHERE type = '".$type."'";
    -		if(!empty($fk_user))$sql.=" AND fk_user=".$fk_user;
    +		if (!empty($fk_user)) $sql.=" AND fk_user=".$fk_user;
             $sql.= " ORDER BY rowid";
             $result = $this->db->query($sql);
             if ($result)
    @@ -105,6 +109,7 @@ class FormOther
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return list of export models
          *
    @@ -114,8 +119,9 @@ class FormOther
          *    @param    int		$useempty          Affiche valeur vide dans liste
          *    @return	void
          */
    -    function select_import_model($selected='',$htmlname='importmodelid',$type='',$useempty=0)
    +    function select_import_model($selected='', $htmlname='importmodelid', $type='', $useempty=0)
         {
    +        // phpcs:enable
             $sql = "SELECT rowid, label";
             $sql.= " FROM ".MAIN_DB_PREFIX."import_model";
             $sql.= " WHERE type = '".$type."'";
    @@ -154,6 +160,7 @@ class FormOther
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return list of ecotaxes with label
          *
    @@ -161,8 +168,9 @@ class FormOther
          *    @param    string	$htmlname	Name of combo list
          *    @return	integer
          */
    -    function select_ecotaxes($selected='',$htmlname='ecotaxe_id')
    +    function select_ecotaxes($selected='', $htmlname='ecotaxe_id')
         {
    +        // phpcs:enable
             global $langs;
     
             $sql = "SELECT e.rowid, e.code, e.label, e.price, e.organization,";
    @@ -210,6 +218,7 @@ class FormOther
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return list of revenue stamp for country
          *
    @@ -218,8 +227,9 @@ class FormOther
          *    @param    string	$country_code   Country Code
          *    @return	string					HTML select list
          */
    -    function select_revenue_stamp($selected='',$htmlname='revenuestamp',$country_code='')
    +    function select_revenue_stamp($selected='', $htmlname='revenuestamp', $country_code='')
         {
    +        // phpcs:enable
         	global $langs;
     
         	$out='';
    @@ -267,6 +277,7 @@ class FormOther
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return a HTML select list to select a percent
          *
    @@ -281,6 +292,7 @@ class FormOther
          */
         function select_percent($selected=0,$htmlname='percent',$disabled=0,$increment=5,$start=0,$end=100,$showempty=0)
         {
    +        // phpcs:enable
             $return = '<select class="flat" name="'.$htmlname.'" '.($disabled?'disabled':'').'>';
             if ($showempty) $return.='<option value="-1"'.(($selected == -1 || $selected == '')?' selected':'').'>&nbsp;</option>';
     
    @@ -303,6 +315,7 @@ class FormOther
             return $return;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return select list for categories (to use in form search selectors)
          *
    @@ -317,6 +330,7 @@ class FormOther
          */
         function select_categories($type, $selected=0, $htmlname='search_categ', $nocateg=0, $showempty=1, $morecss='')
         {
    +        // phpcs:enable
             global $conf, $langs;
             require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
     
    @@ -363,6 +377,7 @@ class FormOther
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return select list for categories (to use in form search selectors)
          *
    @@ -376,6 +391,7 @@ class FormOther
          */
         function select_salesrepresentatives($selected,$htmlname,$user,$showstatus=0,$showempty=1,$morecss='')
         {
    +        // phpcs:enable
             global $conf,$langs;
             $langs->load('users');
     
    @@ -617,6 +633,7 @@ class FormOther
     		else print $textifnotdefined;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *		Output a HTML code to select a color
          *
    @@ -631,6 +648,7 @@ class FormOther
          */
         function select_color($set_color='', $prefix='f_color', $form_name='', $showcolorbox=1, $arrayofcolors='')
         {
    +        // phpcs:enable
         	print $this->selectColor($set_color, $prefix, $form_name, $showcolorbox, $arrayofcolors);
         }
     
    @@ -734,6 +752,7 @@ class FormOther
             return $out;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Creation d'un icone de couleur
          *
    @@ -746,6 +765,7 @@ class FormOther
          */
         function CreateColorIcon($color,$module,$name,$x='12',$y='12')
         {
    +        // phpcs:enable
             global $conf;
     
             $file = $conf->$module->dir_temp.'/'.$name.'.png';
    @@ -773,6 +793,7 @@ class FormOther
             ImageDestroy($image);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    	Return HTML combo list of week
          *
    @@ -783,15 +804,18 @@ class FormOther
          */
         function select_dayofweek($selected='',$htmlname='weekid',$useempty=0)
         {
    +        // phpcs:enable
             global $langs;
     
    -        $week = array(	0=>$langs->trans("Day0"),
    -        1=>$langs->trans("Day1"),
    -        2=>$langs->trans("Day2"),
    -        3=>$langs->trans("Day3"),
    -        4=>$langs->trans("Day4"),
    -        5=>$langs->trans("Day5"),
    -        6=>$langs->trans("Day6"));
    +        $week = array(
    +            0=>$langs->trans("Day0"),
    +            1=>$langs->trans("Day1"),
    +            2=>$langs->trans("Day2"),
    +            3=>$langs->trans("Day3"),
    +            4=>$langs->trans("Day4"),
    +            5=>$langs->trans("Day5"),
    +            6=>$langs->trans("Day6")
    +        );
     
             $select_week = '<select class="flat" name="'.$htmlname.'">';
             if ($useempty)
    @@ -815,6 +839,7 @@ class FormOther
             return $select_week;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *      Return HTML combo list of month
          *
    @@ -827,6 +852,7 @@ class FormOther
          */
         function select_month($selected='', $htmlname='monthid', $useempty=0, $longlabel=0, $morecss='')
         {
    +        // phpcs:enable
             global $langs;
     
             require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    @@ -856,6 +882,7 @@ class FormOther
             return $select_month;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return HTML combo list of years
          *
    @@ -872,6 +899,7 @@ class FormOther
          */
         function select_year($selected='',$htmlname='yearid',$useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='', $morecss='valignmiddle widthauto')
         {
    +        // phpcs:enable
             print $this->selectyear($selected,$htmlname,$useempty,$min_year,$max_year,$offset,$invert,$option,$morecss);
         }
     
    @@ -928,6 +956,7 @@ class FormOther
             return $out;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Show form to select address
          *
    @@ -941,6 +970,7 @@ class FormOther
          */
         function form_address($page, $selected, $socid, $htmlname='address_id', $origin='', $originid='')
         {
    +        // phpcs:enable
             global $langs,$conf;
             global $form;
     
    @@ -1012,7 +1042,7 @@ class FormOther
             		if (! empty($boxidactivatedforuser[$box->id])) continue;	// Already visible for user
             		$label=$langs->transnoentitiesnoconv($box->boxlabel);
             		//if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')';
    -        		if (preg_match('/graph/',$box->class) && empty($conf->browser->phone))
    +        		if (preg_match('/graph/',$box->class) && $conf->browser->layout != 'phone')
             		{
             			$label=$label.' <span class="fa fa-bar-chart"></span>';
             		}
    @@ -1119,8 +1149,8 @@ class FormOther
     
             if ($nbboxactivated)
             {
    -        	$langs->load("boxes");
    -			$langs->load("projects");
    +        	// Load translation files required by the page
    +            $langs->loadLangs(array("boxes","projects"));
     
             	$emptybox=new ModeleBoxes($db);
     
    @@ -1146,7 +1176,7 @@ class FormOther
                     }
                 }
     
    -            if (empty($conf->browser->phone))
    +            if ($conf->browser->layout != 'phone')
                 {
                 	$emptybox->box_id='A';
                 	$emptybox->info_box_head=array();
    @@ -1173,7 +1203,7 @@ class FormOther
                     }
                 }
     
    -            if (empty($conf->browser->phone))
    +            if ($conf->browser->layout != 'phone')
                 {
                 	$emptybox->box_id='B';
                 	$emptybox->info_box_head=array();
    @@ -1182,13 +1212,13 @@ class FormOther
                 }
     
                 $boxlistb.= "<!-- End box right container -->\n";
    -
             }
     
             return array('selectboxlist'=>count($boxactivated)?$selectboxlist:'', 'boxactivated'=>$boxactivated, 'boxlista'=>$boxlista, 'boxlistb'=>$boxlistb);
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return a HTML select list of a dictionary
          *
    @@ -1203,6 +1233,7 @@ class FormOther
          */
         function select_dictionary($htmlname,$dictionarytable,$keyfield='code',$labelfield='label',$selected='',$useempty=0,$moreattrib='')
         {
    +        // phpcs:enable
             global $langs, $conf;
     
             $langs->load("admin");
    @@ -1251,6 +1282,4 @@ class FormOther
                 dol_print_error($this->db);
             }
         }
    -
     }
    -
    diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php
    index 431beea3c73..bc62ebc7604 100644
    --- a/htdocs/core/class/html.formprojet.class.php
    +++ b/htdocs/core/class/html.formprojet.class.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (c) 2013 Florian Henry  <florian.henry@open-concept.pro>
      * Copyright (C) 2015 Marcos García  <marcosgdf@gmail.com>
    + * Copyright (C) 2018 Charlene Benke <charlie@patas-monkey.com>
      *
      * 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
    @@ -28,8 +29,15 @@
      */
     class FormProjets
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -40,9 +48,9 @@ class FormProjets
     	function __construct($db)
     	{
     		$this->db = $db;
    -		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Output a combo list with projects qualified for a third party / user
     	 *
    @@ -65,6 +73,7 @@ class FormProjets
     	 */
     	function select_projects($socid=-1, $selected='', $htmlname='projectid', $maxlength=16, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode = 0, $filterkey = '', $nooutput=0, $forceaddid=0, $morecss='', $htmlid='')
     	{
    +        // phpcs:enable
     		global $langs,$conf,$form;
     
     		$out='';
    @@ -110,6 +119,7 @@ class FormProjets
     		else return $out;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns an array with projects qualified for a third party
     	 *
    @@ -132,6 +142,7 @@ class FormProjets
     	 */
     	function select_projects_list($socid=-1, $selected='', $htmlname='projectid', $maxlength=24, $option_only=0, $show_empty=1, $discard_closed=0, $forcefocus=0, $disabled=0, $mode=0, $filterkey = '', $nooutput=0, $forceaddid=0, $htmlid='', $morecss='maxwidth500')
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs;
     
     		require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    @@ -139,10 +150,10 @@ class FormProjets
     		if (empty($htmlid)) $htmlid = $htmlname;
     
     		$out='';
    -        $outarray=array();
    +		$outarray=array();
     
     		$hideunselectables = false;
    -		if (! empty($conf->global->PROJECT_HIDE_UNSELECTABLES)) $hideunselectables = true;
    +		if (! empty($conf->global->CONTRACT_HIDE_UNSELECTABLES)) $hideunselectables = true;
     
     		$projectsListId = false;
     		if (empty($user->rights->projet->all->lire))
    @@ -317,7 +328,7 @@ class FormProjets
     		$out='';
     
     		$hideunselectables = false;
    -		if (! empty($conf->global->PROJECT_HIDE_UNSELECTABLES)) $hideunselectables = true;
    +		if (! empty($conf->global->CONTRACT_HIDE_UNSELECTABLES)) $hideunselectables = true;
     
     		if (empty($projectsListId))
     		{
    @@ -460,6 +471,7 @@ class FormProjets
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Build a HTML select list of element of same thirdparty to suggest to link them to project
     	 *
    @@ -467,19 +479,21 @@ class FormProjets
     	 *    @param	string		$socid				If of thirdparty to use as filter or 'id1,id2,...'
     	 *    @param	string		$morecss			More CSS
     	 *    @param    int         $limitonstatus      Add filters to limit length of list to opened status (for example to avoid ERR_RESPONSE_HEADERS_TOO_BIG on project/element.php page). TODO To implement
    +	 *    @param	string		$projectkey			Equivalent key  to fk_projet for actual table_element
     	 *    @return	int|string						The HTML select list of element or '' if nothing or -1 if KO
     	 */
    -	function select_element($table_element, $socid=0, $morecss='', $limitonstatus=-2)
    +	function select_element($table_element, $socid=0, $morecss='', $limitonstatus=-2,$projectkey="fk_projet")
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		if ($table_element == 'projet_task') return '';		// Special cas of element we never link to a project (already always done)
     
     		$linkedtothirdparty=false;
    -		if (! in_array($table_element, array('don','expensereport_det','expensereport','loan','stock_mouvement','chargesociales'))) $linkedtothirdparty=true;
    +		if (! in_array($table_element, array('don','expensereport_det','expensereport','loan','stock_mouvement','payment_salary','payment_various','chargesociales'))) $linkedtothirdparty=true;
     
     		$sqlfilter='';
    -		$projectkey="fk_projet";
    +
     		//print $table_element;
     		switch ($table_element)
     		{
    @@ -519,6 +533,9 @@ class FormProjets
     				$sql = 'SELECT t.rowid, t.label as ref';
     				$projectkey='fk_origin';
     				break;
    +			case "payment_salary":
    +				$sql = "SELECT t.rowid, t.num_payment as ref";	// TODO In a future fill and use real ref field
    +				break;
     			case "payment_various":
     				$sql = "SELECT t.rowid, t.num_payment as ref";
     				break;
    @@ -612,10 +629,16 @@ class FormProjets
     			if ($num > 0)
     			{
     				$sellist = '<select class="flat oppstatus'.($morecss?' '.$morecss:'').'" id="'.$htmlname.'" name="'.$htmlname.'">';
    -				if ($showempty) $sellist.= '<option value="-1">&nbsp;</option>';    // Without &nbsp, strange move of screen when switching value
    -				if ($showallnone) $sellist.= '<option value="all"'.($preselected == 'all'?' selected="selected"':'').'>--'.$langs->trans("OnlyOpportunitiesShort").'--</option>';
    -				if ($showallnone) $sellist.= '<option value="openedopp"'.($preselected == 'openedopp'?' selected="selected"':'').'>--'.$langs->trans("OpenedOpportunitiesShort").'--</option>';
    -				if ($showallnone) $sellist.= '<option value="none"'.($preselected == 'none'?' selected="selected"':'').'>--'.$langs->trans("NotAnOpportunityShort").'--</option>';
    +				if ($showempty) {
    +                    // Without &nbsp, strange move of screen when switching value
    +                    $sellist.= '<option value="-1">&nbsp;</option>';
    +                }
    +				if ($showallnone) {
    +                    $sellist.= '<option value="all"'.($preselected == 'all'?' selected="selected"':'').'>-- '.$langs->trans("OnlyOpportunitiesShort").' --</option>';
    +				    $sellist.= '<option value="openedopp"'.($preselected == 'openedopp'?' selected="selected"':'').'>-- '.$langs->trans("OpenedOpportunitiesShort").' --</option>';
    +				    $sellist.= '<option value="notopenedopp"'.($preselected == 'notopenedopp'?' selected="selected"':'').'>-- '.$langs->trans("NotOpenedOpportunitiesShort").' --</option>';
    +				    $sellist.= '<option value="none"'.($preselected == 'none'?' selected="selected"':'').'>-- '.$langs->trans("NotAnOpportunityShort").' --</option>';
    +                }
     				while ($i < $num)
     				{
     					$obj = $this->db->fetch_object($resql);
    @@ -656,5 +679,4 @@ class FormProjets
     			return -1;
     		}
     	}
    -
     }
    diff --git a/htdocs/core/class/html.formpropal.class.php b/htdocs/core/class/html.formpropal.class.php
    index 14e1a466275..c4ac522d98a 100644
    --- a/htdocs/core/class/html.formpropal.class.php
    +++ b/htdocs/core/class/html.formpropal.class.php
    @@ -27,8 +27,15 @@
      */
     class FormPropal
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +	
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -59,10 +66,10 @@ class FormPropal
     
             $prefix='';
             $listofstatus=array();
    -        if ($mode == 'supplier') 
    +        if ($mode == 'supplier')
             {
                 $prefix='SupplierProposalStatus';
    -            
    +
                 $langs->load("supplier_proposal");
                 $listofstatus=array(
                     0=>array('id'=>0, 'code'=>'PR_DRAFT'),
    @@ -75,7 +82,7 @@ class FormPropal
             else
             {
                 $prefix="PropalStatus";
    -            
    +
                 $sql = "SELECT id, code, label, active FROM ".MAIN_DB_PREFIX."c_propalst";
                 $sql .= " WHERE active = 1";
                 dol_syslog(get_class($this)."::selectProposalStatus", LOG_DEBUG);
    @@ -139,4 +146,3 @@ class FormPropal
             print '</select>';
         }
     }
    -
    diff --git a/htdocs/core/class/html.formsms.class.php b/htdocs/core/class/html.formsms.class.php
    index 6db6f200136..4ef6208723d 100644
    --- a/htdocs/core/class/html.formsms.class.php
    +++ b/htdocs/core/class/html.formsms.class.php
    @@ -1,20 +1,21 @@
     <?php
    -/* Copyright (C) 2005-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
    -*
    -* 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 <http://www.gnu.org/licenses/>.
    -*/
    +/* Copyright (C) 2005-2011  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2010       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
     
     /**
      *       \file       htdocs/core/class/html.formsms.class.php
    @@ -32,31 +33,42 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/html.form.class.php';
      */
     class FormSms
     {
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    var $fromname;
    -    var $fromsms;
    -    var $replytoname;
    -    var $replytomail;
    -    var $toname;
    -    var $tomail;
    +    public $fromname;
    +    public $fromsms;
    +    public $replytoname;
    +    public $replytomail;
    +    public $toname;
    +    public $tomail;
     
    -    var $withsubstit;			// Show substitution array
    -    var $withfrom;
    -    var $withto;
    -    var $withtopic;
    -    var $withbody;
    +    public $withsubstit;			// Show substitution array
    +    public $withfrom;
    +    public $withto;
    +    public $withtopic;
    +    public $withbody;
     
    -    var $withfromreadonly;
    -    var $withreplytoreadonly;
    -    var $withtoreadonly;
    -    var $withtopicreadonly;
    -    var $withcancel;
    +    public $withfromreadonly;
    +    public $withreplytoreadonly;
    +    public $withtoreadonly;
    +    public $withtopicreadonly;
    +    public $withcancel;
     
    -    var $substit=array();
    -    var $param=array();
    +    public $substit=array();
    +    public $param=array();
     
    -    var $error;
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error='';
    +
    +    /**
    +     * @var string[]	Array of error strings
    +     */
    +    public $errors=array();
     
     
         /**
    @@ -78,26 +90,25 @@ class FormSms
             $this->withtoreadonly=0;
             $this->withtopicreadonly=0;
             $this->withbodyreadonly=0;
    -
    -        return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Show the form to input an sms.
          *
    -     *	@param	string	$morecss        Class on first column td
    -     *  @param  int     $showform       Show form tags and submit button (recommanded is to use with value 0)
    +     *	@param	string	$morecss Class on first column td
    +     *  @param int $showform Show form tags and submit button (recommanded is to use with value 0)
          *	@return	void
          */
         function show_form($morecss='titlefield', $showform=1)
         {
    +     // phpcs:enable
             global $conf, $langs, $user, $form;
     
             if (! is_object($form)) $form=new Form($this->db);
     
    -        $langs->load("other");
    -        $langs->load("mails");
    -        $langs->load("sms");
    +        // Load translation files required by the page
    +        $langs->loadLangs(array('other', 'mails', 'sms'));
     
             $soc=new Societe($this->db);
             if (!empty($this->withtosocid) && $this->withtosocid > 0)
    @@ -354,6 +365,4 @@ function limitChars(textarea, limit, infodiv)
     
             print "<!-- End form SMS -->\n";
         }
    -
     }
    -
    diff --git a/htdocs/core/class/html.formsocialcontrib.class.php b/htdocs/core/class/html.formsocialcontrib.class.php
    index 83886e63af8..99e36878390 100644
    --- a/htdocs/core/class/html.formsocialcontrib.class.php
    +++ b/htdocs/core/class/html.formsocialcontrib.class.php
    @@ -27,8 +27,15 @@
      */
     class FormSocialContrib
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -41,9 +48,10 @@ class FormSocialContrib
     	    $this->db = $db;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *	Return list of social contributions.
    -     * 	Use mysoc->country_id or mysoc->country_code so they must be defined.
    +     *  Return list of social contributions.
    +     *  Use mysoc->country_id or mysoc->country_code so they must be defined.
          *
          *	@param	string	$selected       Preselected type
          *	@param  string	$htmlname       Name of field in form
    @@ -55,6 +63,7 @@ class FormSocialContrib
          */
         function select_type_socialcontrib($selected='',$htmlname='actioncode', $useempty=0, $maxlen=40, $help=1, $morecss='minwidth300')
         {
    +        // phpcs:enable
             global $conf,$db,$langs,$user,$mysoc;
     
             if (empty($mysoc->country_id) && empty($mysoc->country_code))
    @@ -113,6 +122,4 @@ class FormSocialContrib
                 dol_print_error($db,$db->lasterror());
             }
         }
    -
     }
    -
    diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php
    index 9c3daefd62a..6c4a9703014 100644
    --- a/htdocs/core/class/html.formticket.class.php
    +++ b/htdocs/core/class/html.formticket.class.php
    @@ -39,9 +39,16 @@ if (!class_exists('FormCompany')) {
      */
     class FormTicket
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
     
         public $track_id;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_user_create;
     
         public $message;
    @@ -80,7 +87,10 @@ class FormTicket
         public $substit = array();
         public $param = array();
     
    -    public $error;
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error;
     
     
         /**
    @@ -106,8 +116,6 @@ class FormTicket
             $this->withref = 0;
             $this->withextrafields = 0;         // Show extrafields or not
             //$this->withtopicreadonly=0;
    -
    -        return 1;
         }
     
         /**
    @@ -120,9 +128,8 @@ class FormTicket
         {
             global $conf, $langs, $user, $hookmanager;
     
    -        $langs->load("other");
    -        $langs->load("mails");
    -        $langs->load("ticket");
    +        // Load translation files required by the page
    +        $langs->loadLangs(array('other', 'mails', 'ticket'));
     
             $form = new Form($this->db);
             $formcompany = new FormCompany($this->db);
    @@ -722,8 +729,8 @@ class FormTicket
         {
             global $conf, $langs, $user, $mysoc;
     
    -        $langs->load("other");
    -        $langs->load("mails");
    +        // Load translation files required by the page
    +        $langs->loadLangs(array('other', 'mails'));
     
             $addfileaction = 'addfile';
     
    diff --git a/htdocs/core/class/html.formwebsite.class.php b/htdocs/core/class/html.formwebsite.class.php
    index fc863c4d069..f5feccd5860 100644
    --- a/htdocs/core/class/html.formwebsite.class.php
    +++ b/htdocs/core/class/html.formwebsite.class.php
    @@ -28,7 +28,11 @@
     class FormWebsite
     {
         private $db;
    -    public $error;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error;
     
     
         /**
    @@ -39,8 +43,6 @@ class FormWebsite
         function __construct($db)
         {
             $this->db = $db;
    -
    -        return 1;
         }
     
     
    @@ -201,5 +203,4 @@ class FormWebsite
     
         	return $out;
         }
    -
     }
    diff --git a/htdocs/core/class/infobox.class.php b/htdocs/core/class/infobox.class.php
    index 4125aa89eb9..1c5c733491c 100644
    --- a/htdocs/core/class/infobox.class.php
    +++ b/htdocs/core/class/infobox.class.php
    @@ -281,6 +281,5 @@ class InfoBox
                 return -1;
             }
         }
    -
     }
     
    diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php
    index 655969d73f6..51eafd3ef7a 100644
    --- a/htdocs/core/class/interfaces.class.php
    +++ b/htdocs/core/class/interfaces.class.php
    @@ -31,9 +31,17 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
      */
     class Interfaces
     {
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
     	var $dir;				// Directory with all core and external triggers files
    -    var $errors	= array();	// Array for errors
    +
    +    /**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
         /**
          *	Constructor
    @@ -45,6 +53,7 @@ class Interfaces
             $this->db = $db;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *   Function called when a Dolibarr business event occurs
          *   This function call all qualified triggers.
    @@ -58,6 +67,7 @@ class Interfaces
          */
         function run_triggers($action,$object,$user,$langs,$conf)
         {
    +        // phpcs:enable
             // Check parameters
             if (! is_object($object) || ! is_object($conf))	// Error
             {
    @@ -360,5 +370,4 @@ class Interfaces
             }
             return $triggers;
         }
    -
     }
    diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php
    index f54caacff8b..38f7a1f2f53 100644
    --- a/htdocs/core/class/ldap.class.php
    +++ b/htdocs/core/class/ldap.class.php
    @@ -29,12 +29,21 @@
      */
     class Ldap
     {
    -	var $error;
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[]	Array of error strings
    +	 */
    +	public $errors = array();
     
     	/**
     	 * Tableau des serveurs (IP addresses ou nom d'hotes)
     	 */
     	var $server=array();
    +
     	/**
     	 * Base DN (e.g. "dc=foo,dc=com")
     	 */
    @@ -140,6 +149,7 @@ class Ldap
     
     	// Connection handling methods -------------------------------------------
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Connect and bind
     	 * 	Use this->server, this->serverPort, this->ldapProtocolVersion, this->serverType, this->searchUser, this->searchPassword
    @@ -149,6 +159,7 @@ class Ldap
     	 */
     	function connect_bind()
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		$connected=0;
    @@ -370,7 +381,8 @@ class Ldap
     	 *
     	 * @return	boolean					version
     	 */
    -	function setVersion() {
    +    function setVersion()
    +    {
     		// LDAP_OPT_PROTOCOL_VERSION est une constante qui vaut 17
     		$ldapsetversion = ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->ldapProtocolVersion);
     		return $ldapsetversion;
    @@ -381,7 +393,8 @@ class Ldap
     	 *
     	 * @return	boolean					referrals
     	 */
    -	function setReferrals() {
    +    function setReferrals()
    +    {
     		// LDAP_OPT_REFERRALS est une constante qui vaut ?
     		$ldapreferrals = ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0);
     		return $ldapreferrals;
    @@ -643,6 +656,7 @@ class Ldap
     		return -1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Build a LDAP message
     	 *
    @@ -652,6 +666,7 @@ class Ldap
     	 */
     	function dump_content($dn, $info)
     	{
    +        // phpcs:enable
     		$content='';
     
     		// Create file content
    @@ -1423,6 +1438,7 @@ class Ldap
     		return($retval);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Convertit le temps ActiveDirectory en Unix timestamp
     	 *
    @@ -1431,6 +1447,7 @@ class Ldap
     	 */
     	function convert_time($value)
     	{
    +        // phpcs:enable
     		$dateLargeInt=$value; // nano secondes depuis 1601 !!!!
     		$secsAfterADEpoch = $dateLargeInt / (10000000); // secondes depuis le 1 jan 1601
     		$ADToUnixConvertor=((1970-1601) * 365.242190) * 86400; // UNIX start date - AD start date * jours * secondes
    diff --git a/htdocs/core/class/link.class.php b/htdocs/core/class/link.class.php
    index 0441c04a86e..8413725ab11 100644
    --- a/htdocs/core/class/link.class.php
    +++ b/htdocs/core/class/link.class.php
    @@ -28,13 +28,29 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class Link extends CommonObject
     {
    -    public $element = 'link';
    -    public $table_element = 'links';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element = 'link';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element = 'links';
    +
    +    /**
    +	 * @var int Entity
    +	 */
    +	public $entity;
     
    -    public $entity;
         public $datea;
         public $url;
    +
    +    /**
    +     * @var string Links label
    +     */
         public $label;
    +
         public $objecttype;
         public $objectid;
     
    @@ -46,11 +62,7 @@ class Link extends CommonObject
          */
         public function __construct($db)
         {
    -        global $conf;
    -
             $this->db = $db;
    -
    -        return 1;
         }
     
     
    @@ -378,7 +390,5 @@ class Link extends CommonObject
                 $this->db->rollback();
                 return -1;
             }
    -
         }
    -
     }
    diff --git a/htdocs/core/class/menu.class.php b/htdocs/core/class/menu.class.php
    index 17d5e06589f..3d9d92189a3 100644
    --- a/htdocs/core/class/menu.class.php
    +++ b/htdocs/core/class/menu.class.php
    @@ -73,7 +73,7 @@ class Menu
         /**
          * Insert a menu entry into this->liste
          *
    -     * @param	int		$idafter	Array key after which inserting new entry
    +     * @param   int		$idafter	Array key after which inserting new entry
          * @param	string	$url        Url to follow on click
          * @param   string	$titre      Label of menu to add
          * @param   integer	$level      Level of menu to add
    @@ -96,6 +96,7 @@ class Menu
             $this->liste=array_merge($array_start,$array_new,$array_end);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Remove a menu entry from this->liste
          *
    @@ -103,7 +104,10 @@ class Menu
          */
         function remove_last()
         {
    -    	if (count($this->liste) > 1) array_pop($this->liste);
    +        // phpcs:enable
    +        if (count($this->liste) > 1) {
    +            array_pop($this->liste);
    +        }
         }
     
         /**
    diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
    index 48880633563..1ca10d9dd9b 100644
    --- a/htdocs/core/class/menubase.class.php
    +++ b/htdocs/core/class/menubase.class.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2007-2009	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2009-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -28,19 +29,49 @@
      */
     class Menubase
     {
    -    public $db;							// To store db handler
    -    public $error;							// To return error code (or message)
    -    public $errors=array();				// To return several error codes (or messages)
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    public $id;
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error;
    +
    +    /**
    +     * @var string[] Error codes (or messages)
    +     */
    +    public $errors = array();
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
         public $menu_handler;
         public $module;
         public $type;
         public $mainmenu;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_menu;
    +
    +    /**
    +     * @var string fk_mainmenu
    +     */
         public $fk_mainmenu;
    +
    +    /**
    +     * @var string fk_leftmenu
    +     */
         public $fk_leftmenu;
    +
    +    /**
    +     * @var int position
    +     */
         public $position;
         public $url;
         public $target;
    @@ -84,10 +115,10 @@ class Menubase
             $this->type=trim($this->type);
             $this->mainmenu=trim($this->mainmenu);
             $this->leftmenu=trim($this->leftmenu);
    -        $this->fk_menu=trim($this->fk_menu);          // If -1, fk_mainmenu and fk_leftmenu must be defined
    +        $this->fk_menu = (int) $this->fk_menu;          // If -1, fk_mainmenu and fk_leftmenu must be defined
             $this->fk_mainmenu=trim($this->fk_mainmenu);
             $this->fk_leftmenu=trim($this->fk_leftmenu);
    -        $this->position=trim($this->position);
    +        $this->position = (int) $this->position;
             $this->url=trim($this->url);
             $this->target=trim($this->target);
             $this->titre=trim($this->titre);
    @@ -95,7 +126,7 @@ class Menubase
             $this->perms=trim($this->perms);
             $this->enabled=trim($this->enabled);
             $this->user=trim($this->user);
    -        $this->position=trim($this->position);
    +        if (empty($this->position)) $this->position=0;
             if (! $this->level) $this->level=0;
     
             // Check parameters
    @@ -128,7 +159,7 @@ class Menubase
             $sql = "SELECT count(*)";
             $sql.= " FROM ".MAIN_DB_PREFIX."menu";
             $sql.= " WHERE menu_handler = '".$this->db->escape($this->menu_handler)."'";
    -        $sql.= " AND fk_menu = ".((int) $this->db->escape($this->fk_menu));
    +        $sql.= " AND fk_menu = ".((int) $this->fk_menu);
             $sql.= " AND position = ".((int) $this->position);
             $sql.= " AND url = '".$this->db->escape($this->url)."'";
             $sql.= " AND entity = ".$conf->entity;
    @@ -225,10 +256,10 @@ class Menubase
             $this->type=trim($this->type);
             $this->mainmenu=trim($this->mainmenu);
             $this->leftmenu=trim($this->leftmenu);
    -        $this->fk_menu=trim($this->fk_menu);
    +        $this->fk_menu = (int) $this->fk_menu;
             $this->fk_mainmenu=trim($this->fk_mainmenu);
             $this->fk_leftmenu=trim($this->fk_leftmenu);
    -        $this->position=trim($this->position);
    +        $this->position = (int) $this->position;
             $this->url=trim($this->url);
             $this->target=trim($this->target);
             $this->titre=trim($this->titre);
    @@ -247,7 +278,7 @@ class Menubase
             $sql.= " type='".$this->db->escape($this->type)."',";
             $sql.= " mainmenu='".$this->db->escape($this->mainmenu)."',";
             $sql.= " leftmenu='".$this->db->escape($this->leftmenu)."',";
    -        $sql.= " fk_menu='".$this->db->escape($this->fk_menu)."',";
    +        $sql.= " fk_menu=".$this->fk_menu.",";
             $sql.= " fk_mainmenu=".($this->fk_mainmenu?"'".$this->db->escape($this->fk_mainmenu)."'":"null").",";
             $sql.= " fk_leftmenu=".($this->fk_leftmenu?"'".$this->db->escape($this->fk_leftmenu)."'":"null").",";
             $sql.= " position=".($this->position > 0 ? $this->position : 0).",";
    @@ -683,6 +714,4 @@ class Menubase
                 }
             }
        }
    -
     }
    -
    diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
    index c226fb647d0..18635aeee00 100644
    --- a/htdocs/core/class/notify.class.php
    +++ b/htdocs/core/class/notify.class.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2014	   Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2018 	   Philippe Grand		<philippe.grand@atoo-net.com>
      *
      * 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
    @@ -30,21 +31,41 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/CMailFile.class.php';
      */
     class Notify
     {
    -	var $id;
    -	var $db;
    -	var $error;
    -	var $errors=array();
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $author;
    -	var $ref;
    -	var $date;
    -	var $duree;
    -	var $note;
    -	var $fk_project;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +	public $author;
    +	public $ref;
    +	public $date;
    +	public $duree;
    +	public $note;
    +
    +	/**
    +     * @var int Project ID
    +     */
    +    public $fk_project;
     
     	// Les codes actions sont definis dans la table llx_notify_def
     
     	// codes actions supported are
    +	// @TODO defined also into interface_50_modNotificiation_Notificiation.class.php
     	public $arrayofnotifsupported = array(
     		'BILL_VALIDATE',
     		'BILL_PAYED',
    @@ -56,7 +77,11 @@ class Notify
     		'ORDER_SUPPLIER_VALIDATE',
     		'ORDER_SUPPLIER_APPROVE',
     		'ORDER_SUPPLIER_REFUSE',
    -		'SHIPPING_VALIDATE'
    +		'SHIPPING_VALIDATE',
    +		'EXPENSE_REPORT_VALIDATE',
    +		'EXPENSE_REPORT_APPROVE',
    +		'HOLIDAY_VALIDATE',
    +		'HOLIDAY_APPROVE'
     	);
     
     
    @@ -320,22 +345,27 @@ class Notify
     		$oldref=(empty($object->oldref)?$object->ref:$object->oldref);
     		$newref=(empty($object->newref)?$object->ref:$object->newref);
     
    +		$sql = '';
    +
     		// Check notification per third party
    -		$sql = "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
    -		$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
    -		$sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
    -		$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
    -		$sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
    -		$sql.= " ".MAIN_DB_PREFIX."societe as s";
    -		$sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
    -		$sql.= " AND n.fk_soc = s.rowid";
    -		if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
    -		else $sql.= " AND a.code = '".$notifcode."'";	// New usage
    -		$sql .= " AND s.rowid = ".$object->socid;
    +		if ($object->socid > 0)
    +		{
    +			$sql.= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
    +			$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
    +			$sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
    +			$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
    +			$sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
    +			$sql.= " ".MAIN_DB_PREFIX."societe as s";
    +			$sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
    +			$sql.= " AND n.fk_soc = s.rowid";
    +			if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
    +			else $sql.= " AND a.code = '".$notifcode."'";	// New usage
    +			$sql .= " AND s.rowid = ".$object->socid;
    +
    +			$sql.= "\nUNION\n";
    +		}
     
     		// Check notification per user
    -		$sql.= "\nUNION\n";
    -
     		$sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
     		$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
     		$sql.= " FROM ".MAIN_DB_PREFIX."user as c,";
    @@ -343,12 +373,20 @@ class Notify
     		$sql.= " ".MAIN_DB_PREFIX."notify_def as n";
     		$sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
     		if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
    -		else $sql.= " AND a.code = '".$notifcode."'";	// New usage
    +		else $sql.= " AND a.code = '".$this->db->escape($notifcode)."'";	// New usage
     
     		$result = $this->db->query($sql);
     		if ($result)
     		{
     			$num = $this->db->num_rows($result);
    +			$projtitle='';
    +			if (! empty($object->fk_project))
    +			{
    +				require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +				$proj = new Project($this->db);
    +				$proj->fetch($object->fk_project);
    +				$projtitle='('.$proj->title.')';
    +			}
     
     			if ($num > 0)
     			{
    @@ -371,7 +409,7 @@ class Notify
     							$outputlangs->loadLangs(array("main","other"));
     						}
     
    -						$subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification");
    +						$subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
     
     						switch ($notifcode) {
     							case 'BILL_VALIDATE':
    @@ -445,6 +483,26 @@ class Notify
     								$object_type = 'order_supplier';
     								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
     								break;
    +							case 'EXPENSE_REPORT_VALIDATE':
    +								$dir_output = $conf->expensereport->dir_output;
    +								$object_type = 'expensereport';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
    +								break;
    +							case 'EXPENSE_REPORT_APPROVE':
    +								$dir_output = $conf->expensereport->dir_output;
    +								$object_type = 'expensereport';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
    +								break;
    +							case 'HOLIDAY_VALIDATE':
    +								$dir_output = $conf->holiday->dir_output;
    +								$object_type = 'holiday';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
    +								break;
    +							case 'HOLIDAY_APPROVE':
    +								$dir_output = $conf->holiday->dir_output;
    +								$object_type = 'holiday';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
    +								break;
     						}
     						$ref = dol_sanitizeFileName($newref);
     						$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
    @@ -491,12 +549,10 @@ class Notify
     							if ($obj->type_target == 'touserid') {
     	 							$sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_user, type, objet_type, type_target, objet_id, email)";
     								$sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')";
    -
     							}
     							else {
     								$sql = "INSERT INTO ".MAIN_DB_PREFIX."notify (daten, fk_action, fk_soc, fk_contact, type, objet_type, type_target, objet_id, email)";
     								$sql.= " VALUES ('".$this->db->idate(dol_now())."', ".$notifcodedefid.", ".($object->socid?$object->socid:'null').", ".$obj->cid.", '".$obj->type."', '".$object_type."', '".$obj->type_target."', ".$object->id.", '".$this->db->escape($obj->email)."')";
    -
     							}
     							if (! $this->db->query($sql))
     							{
    @@ -553,7 +609,7 @@ class Notify
     				$link = '';
     				$num++;
     
    -				$subject = '['.$mysoc->name.'] '.$langs->transnoentitiesnoconv("DolibarrNotification");
    +				$subject = '['.$mysoc->name.'] '.$langs->transnoentitiesnoconv("DolibarrNotification").($projtitle?' '.$projtitle:'');
     
     				switch ($notifcode) {
     					case 'BILL_VALIDATE':
    @@ -575,13 +631,13 @@ class Notify
     						$mesg = $langs->transnoentitiesnoconv("EMailTextOrderValidated",$link);
     						break;
     					case 'PROPAL_VALIDATE':
    -						$link='/comm/propal/card.php?id='.$object->id;
    +						$link='<a href="' . $urlwithroot . '/comm/propal/card.php?id='.$object->id . '">' . $newref . '</a>';
     						$dir_output = $conf->propal->multidir_output[$object->entity];
     						$object_type = 'propal';
     						$mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$link);
     						break;
     					case 'PROPAL_CLOSE_SIGNED':
    -						$link='/comm/propal/card.php?id='.$object->id;
    +						$link='<a href="' . $urlwithroot . '/comm/propal/card.php?id='.$object->id . '">' . $newref . '</a>';
     						$dir_output = $conf->propal->multidir_output[$object->entity];
     						$object_type = 'propal';
     						$mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$link);
    @@ -635,6 +691,26 @@ class Notify
     						$object_type = 'order_supplier';
     						$mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
     						break;
    +					case 'EXPENSE_REPORT_VALIDATE':
    +						$dir_output = $conf->expensereport->dir_output;
    +						$object_type = 'expensereport';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
    +						break;
    +					case 'EXPENSE_REPORT_APPROVE':
    +						$dir_output = $conf->expensereport->dir_output;
    +						$object_type = 'expensereport';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
    +						break;
    +					case 'HOLIDAY_VALIDATE':
    +						$dir_output = $conf->holiday->dir_output;
    +						$object_type = 'holiday';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
    +						break;
    +					case 'HOLIDAY_APPROVE':
    +						$dir_output = $conf->holiday->dir_output;
    +						$object_type = 'holiday';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
    +						break;
     				}
     				$ref = dol_sanitizeFileName($newref);
     				$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
    @@ -717,6 +793,4 @@ class Notify
     		if (! $error) return $num;
     		else return -1 * $error;
     	}
    -
     }
    -
    diff --git a/htdocs/core/class/openid.class.php b/htdocs/core/class/openid.class.php
    index d46481a0c60..48de42ad847 100644
    --- a/htdocs/core/class/openid.class.php
    +++ b/htdocs/core/class/openid.class.php
    @@ -30,8 +30,8 @@ class SimpleOpenID
         var $URLs = array();
         var $error = array();
         var $fields = array(
    -		'required'	 => array(),
    -		'optional'	 => array(),
    +		'required' => array(),
    +		'optional' => array(),
         );
     
         /**
    @@ -45,6 +45,7 @@ class SimpleOpenID
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetOpenIDServer
          *
    @@ -53,9 +54,11 @@ class SimpleOpenID
          */
         function SetOpenIDServer($a)
         {
    +        // phpcs:enable
             $this->URLs['openid_server'] = $a;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetOpenIDServer
          *
    @@ -64,9 +67,11 @@ class SimpleOpenID
          */
         function SetTrustRoot($a)
         {
    +        // phpcs:enable
             $this->URLs['trust_root'] = $a;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetOpenIDServer
          *
    @@ -75,9 +80,11 @@ class SimpleOpenID
          */
         function SetCancelURL($a)
         {
    +        // phpcs:enable
             $this->URLs['cancel'] = $a;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetApprovedURL
          *
    @@ -86,9 +93,11 @@ class SimpleOpenID
          */
         function SetApprovedURL($a)
         {
    +        // phpcs:enable
             $this->URLs['approved'] = $a;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetRequiredFields
          *
    @@ -97,13 +106,15 @@ class SimpleOpenID
          */
         function SetRequiredFields($a)
         {
    -        if (is_array($a)){
    +        // phpcs:enable
    +        if (is_array($a)) {
                 $this->fields['required'] = $a;
    -        }else{
    +        } else {
                 $this->fields['required'][] = $a;
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetOptionalFields
          *
    @@ -112,23 +123,27 @@ class SimpleOpenID
          */
         function SetOptionalFields($a)
         {
    -        if (is_array($a)){
    +        // phpcs:enable
    +        if (is_array($a)) {
                 $this->fields['optional'] = $a;
    -        }else{
    +        } else {
                 $this->fields['optional'][] = $a;
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetIdentity
          *
    -     * @param	string	$a		Server
    +     * @param	string  $a		Server
          * @return	void
          */
         function SetIdentity($a)
    -    { 	// Set Identity URL
    +    {
    +        // phpcs:enable
    +        // Set Identity URL
             if ((stripos($a, 'http://') === false)
    -        && (stripos($a, 'https://') === false)){
    +        && (stripos($a, 'https://') === false)) {
                 $a = 'http://'.$a;
             }
             /*
    @@ -147,16 +162,20 @@ class SimpleOpenID
             $this->openid_url_identity = $a;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * GetIdentity
          *
          * @return	string
          */
         function GetIdentity()
    -    { 	// Get Identity
    +    {
    +        // phpcs:enable
    +        // Get Identity
             return $this->openid_url_identity;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * SetOpenIDServer
          *
    @@ -164,10 +183,12 @@ class SimpleOpenID
          */
         function GetError()
         {
    +        // phpcs:enable
             $e = $this->error;
             return array('code'=>$e[0],'description'=>$e[1]);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * ErrorStore
          *
    @@ -177,6 +198,7 @@ class SimpleOpenID
          */
         function ErrorStore($code, $desc = null)
         {
    +        // phpcs:enable
             $errs['OPENID_NOSERVERSFOUND'] = 'Cannot find OpenID Server TAG on Identity page.';
             if ($desc == null){
                 $desc = $errs[$code];
    @@ -184,6 +206,7 @@ class SimpleOpenID
             $this->error = array($code,$desc);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * IsError
          *
    @@ -191,6 +214,7 @@ class SimpleOpenID
          */
         function IsError()
         {
    +        // phpcs:enable
             if (count($this->error) > 0)
             {
                 return true;
    @@ -221,6 +245,7 @@ class SimpleOpenID
             return $r;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * OpenID_Standarize
          *
    @@ -229,6 +254,7 @@ class SimpleOpenID
          */
         function OpenID_Standarize($openid_identity = null)
         {
    +        // phpcs:enable
             if ($openid_identity === null)
             $openid_identity = $this->openid_url_identity;
     
    @@ -254,7 +280,8 @@ class SimpleOpenID
          * @return false|string		false if KO, string of url if OK
          */
         function array2url($arr)
    -    { // converts associated array to URL Query String
    +    {
    +        // converts associated array to URL Query String
             if (!is_array($arr)){
                 return false;
             }
    @@ -265,6 +292,7 @@ class SimpleOpenID
             return $query;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * FSOCK_Request
          *
    @@ -275,6 +303,7 @@ class SimpleOpenID
          */
         function FSOCK_Request($url, $method="GET", $params = "")
         {
    +        // phpcs:enable
             $fp = fsockopen("ssl://www.myopenid.com", 443, $errno, $errstr, 3); // Connection timeout is 3 seconds
             if (!$fp) {
                 $this->ErrorStore('OPENID_SOCKETERROR', $errstr);
    @@ -297,6 +326,7 @@ class SimpleOpenID
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * CURL_Request
          *
    @@ -306,7 +336,9 @@ class SimpleOpenID
          * @return string
          */
         function CURL_Request($url, $method="GET", $params = "")
    -    { // Remember, SSL MUST BE SUPPORTED
    +    {
    +        // phpcs:enable
    +        // Remember, SSL MUST BE SUPPORTED
             if (is_array($params)) $params = $this->array2url($params);
     
             $curl = curl_init($url . ($method == "GET" && $params != "" ? "?" . $params : ""));
    @@ -327,6 +359,7 @@ class SimpleOpenID
             return $response;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * HTML2OpenIDServer
          *
    @@ -335,6 +368,7 @@ class SimpleOpenID
          */
         function HTML2OpenIDServer($content)
         {
    +        // phpcs:enable
             $get = array();
     
             // Get details of their OpenID server and (optional) delegate
    @@ -353,6 +387,7 @@ class SimpleOpenID
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Get openid server
          *
    @@ -361,7 +396,8 @@ class SimpleOpenID
          */
         function GetOpenIDServer($url='')
         {
    -    	global $conf;
    +        // phpcs:enable
    +        global $conf;
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
     		if (empty($url)) $url=$conf->global->MAIN_AUTHENTICATION_OPENID_URL;
    @@ -369,18 +405,19 @@ class SimpleOpenID
             $response = getURLContent($url);
     
             list($servers, $delegates) = $this->HTML2OpenIDServer($response);
    -        if (count($servers) == 0){
    +        if (count($servers) == 0) {
                 $this->ErrorStore('OPENID_NOSERVERSFOUND');
                 return false;
             }
             if (isset($delegates[0])
    -        && ($delegates[0] != "")){
    +        && ($delegates[0] != "")) {
                 $this->SetIdentity($delegates[0]);
             }
             $this->SetOpenIDServer($servers[0]);
             return $servers[0];
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * GetRedirectURL
          *
    @@ -388,6 +425,7 @@ class SimpleOpenID
          */
         function GetRedirectURL()
         {
    +        // phpcs:enable
             $params = array();
             $params['openid.return_to'] = urlencode($this->URLs['approved']);
             $params['openid.mode'] = 'checkid_setup';
    @@ -405,6 +443,7 @@ class SimpleOpenID
             return $this->URLs['openid_server'] . "?". $this->array2url($params);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Redirect
          *
    @@ -412,6 +451,7 @@ class SimpleOpenID
          */
         function Redirect()
         {
    +        // phpcs:enable
             $redirect_to = $this->GetRedirectURL();
             if (headers_sent())
             { // Use JavaScript to redirect if content has been previously sent (not recommended, but safe)
    @@ -425,6 +465,7 @@ class SimpleOpenID
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * ValidateWithServer
          *
    @@ -432,6 +473,7 @@ class SimpleOpenID
          */
         function ValidateWithServer()
         {
    +        // phpcs:enable
             $params = array(
     			'openid.assoc_handle' => urlencode($_GET['openid_assoc_handle']),
     			'openid.signed' => urlencode($_GET['openid_signed']),
    @@ -520,6 +562,4 @@ class SimpleOpenID
             	return $server;
     	    }
         }
    -
     }
    -
    diff --git a/htdocs/core/class/rssparser.class.php b/htdocs/core/class/rssparser.class.php
    index 47c36cb0eaf..fd37476a26e 100644
    --- a/htdocs/core/class/rssparser.class.php
    +++ b/htdocs/core/class/rssparser.class.php
    @@ -26,8 +26,15 @@
      */
     class RssParser
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
         private $_format='';
         private $_urlRSS;
    @@ -54,7 +61,7 @@ class RssParser
          */
         public function __construct($db)
         {
    -    	$this->db=$db;
    +    	$this->db = $db;
         }
     
         /**
    @@ -454,6 +461,7 @@ class RssParser
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Triggered when opened tag is found
          *
    @@ -464,6 +472,7 @@ class RssParser
          */
         function feed_start_element($p, $element, &$attrs)
         {
    +        // phpcs:enable
             $el = $element = strtolower($element);
             $attrs = array_change_key_case($attrs, CASE_LOWER);
     
    @@ -536,8 +545,6 @@ class RssParser
                 }
     
                 $this->incontent = $el;
    -
    -
             }
     
             // if inside an Atom content construct (e.g. content or summary) field treat tags as text
    @@ -574,6 +581,7 @@ class RssParser
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Triggered when CDATA is found
          *
    @@ -583,6 +591,7 @@ class RssParser
          */
         function feed_cdata($p, $text)
         {
    +        // phpcs:enable
             if ($this->_format == 'atom' and $this->incontent)
             {
                 $this->append_content($text);
    @@ -594,6 +603,7 @@ class RssParser
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Triggered when closed tag is found
          *
    @@ -603,6 +613,7 @@ class RssParser
          */
         function feed_end_element($p, $el)
         {
    +        // phpcs:enable
             $el = strtolower($el);
     
             if ($el == 'item' or $el == 'entry')
    @@ -663,6 +674,7 @@ class RssParser
             $str1 .= $str2;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Enter description here ...
          *
    @@ -671,6 +683,7 @@ class RssParser
          */
         function append_content($text)
         {
    +        // phpcs:enable
             if ( $this->initem ) {
                 $this->concat($this->current_item[ $this->incontent ], $text);
             }
    @@ -719,10 +732,8 @@ class RssParser
                 elseif ($this->inchannel) {
                     $this->concat($this->channel[ $el ], $text);
                 }
    -
             }
         }
    -
     }
     
     
    @@ -745,11 +756,10 @@ function xml2php($xml)
             foreach($value->attributes() as $ak=>$av)
             {
                 $child[$ak] = (string) $av;
    -
             }
     
             //Let see if the new child is not in the array
    -        if($tab === false && in_array($key,array_keys($array)))
    +        if ($tab === false && in_array($key,array_keys($array)))
             {
                 //If this element is already in the array we will create an indexed array
                 $tmp = $array[$key];
    @@ -773,12 +783,10 @@ function xml2php($xml)
         }
     
     
    -    if($fils==0)
    +    if ($fils==0)
         {
             return (string) $xml;
         }
     
         return $array;
    -
     }
    -
    diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php
    index ffa9dafdfbe..113f5a6f278 100644
    --- a/htdocs/core/class/smtps.class.php
    +++ b/htdocs/core/class/smtps.class.php
    @@ -344,6 +344,7 @@ class SMTPs
     		$_aryToList = $this->getTO();
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Attempt a connection to mail server
     	 *
    @@ -351,6 +352,7 @@ class SMTPs
     	 */
     	function _server_connect()
     	{
    +        // phpcs:enable
     		// Default return value
     		$_retVal = true;
     
    @@ -406,6 +408,7 @@ class SMTPs
     		return $_retVal;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Attempt mail server authentication for a secure connection
     	 *
    @@ -413,6 +416,7 @@ class SMTPs
     	 */
     	function _server_authenticate()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		// Send the RFC2554 specified EHLO.
    @@ -656,7 +660,7 @@ class SMTPs
     		{
     			// If the path is not valid, this will NOT generate an error,
     			// it will simply return false.
    -			if ( ! @include ( $_strConfigPath ) )
    +			if ( ! @include $_strConfigPath)
     			{
     				$this->_setErr(110, '"' . $_strConfigPath . '" is not a valid path.');
     				$_retVal = false;
    @@ -1036,6 +1040,7 @@ class SMTPs
     		$this->_msgRecipients = $aryHost;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns an array of the various parts of an email address
     	 * This assumes a well formed address:
    @@ -1054,6 +1059,7 @@ class SMTPs
     	 */
     	function _strip_email($_strAddr)
     	{
    +        // phpcs:enable
     		// Keep the orginal
     		$_aryEmail['org'] = $_strAddr;
     
    @@ -1087,6 +1093,7 @@ class SMTPs
     		return $_aryEmail;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns an array of bares addresses for use with 'RCPT TO:'
     	 * This is a "build as you go" method. Each time this method is called
    @@ -1096,6 +1103,7 @@ class SMTPs
     	 */
     	function get_RCPT_list()
     	{
    +        // phpcs:enable
     		/**
     		 * An array of bares addresses for use with 'RCPT TO:'
     		 */
    @@ -1117,6 +1125,7 @@ class SMTPs
     		return $_RCPT_list;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Returns an array of addresses for a specific type; TO, CC or BCC
     	 *
    @@ -1125,6 +1134,7 @@ class SMTPs
     	 */
     	function get_email_list($_which = null)
     	{
    +        // phpcs:enable
     		// We need to know which address segment to pull
     		if ( $_which )
     		{
    @@ -1165,7 +1175,6 @@ class SMTPs
     			$this->_setErr(102, 'eMail type not defined.');
     			return false;
     		}
    -
     	}
     
     	/**
    @@ -1650,7 +1659,7 @@ class SMTPs
     	 * @param 	integer 	$_value 	Message Priority
     	 * @return 	void
     	 */
    -	function setPriority ( $_value = 3 )
    +	function setPriority( $_value = 3 )
     	{
     		if ( ( is_numeric($_value) ) &&
     		( ( $_value >= 0 ) && ( $_value <= 5 ) ) )
    @@ -1746,6 +1755,7 @@ class SMTPs
     		else if ($type == 'alternative') return $this->_smtpsAlternativeBoundary;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * This function has been modified as provided by SirSir to allow multiline responses when
     	 * using SMTP Extensions
    @@ -1756,6 +1766,7 @@ class SMTPs
     	 */
     	function server_parse($socket, $response)
     	{
    +        // phpcs:enable
     		/**
     		 * Returns constructed SELECT Object string or boolean upon failure
     		 * Default value is set at true
    @@ -1787,6 +1798,7 @@ class SMTPs
     		return $_retVal;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Send str
     	 *
    @@ -1797,6 +1809,7 @@ class SMTPs
     	 */
     	function socket_send_str( $_strSend, $_returnCode = null, $CRLF = "\r\n" )
     	{
    +        // phpcs:enable
     		if ($this->_debug) $this->log.=$_strSend;	// @CHANGE LDR for log
     		fputs($this->socket, $_strSend . $CRLF);
     		if ($this->_debug) $this->log.=' ('.$_returnCode.')' . $CRLF;
    @@ -1814,12 +1827,14 @@ class SMTPs
     	 * @param  int    $_errNum  Error Code Number
     	 * @param  string $_errMsg  Error Message
     	 * @return void
    -	 */
    -	function _setErr ( $_errNum, $_errMsg )
    -	{
    -		$this->_smtpsErrors[] = array( 'num' => $_errNum,
    -                                       'msg' => $_errMsg );
    -	}
    +     */
    +    function _setErr( $_errNum, $_errMsg )
    +    {
    +        $this->_smtpsErrors[] = array(
    +            'num' => $_errNum,
    +            'msg' => $_errMsg,
    +        );
    +    }
     
     	/**
     	 * Returns errors codes and messages for Class
    @@ -1840,8 +1855,6 @@ class SMTPs
     
     		return implode("\n", $_errMsg);
     	}
    -
    -
     }
     
     
    @@ -2049,4 +2062,3 @@ class SMTPs
      *  - basic shell with some commets
      *
      */
    -
    diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
    index bdcae2e33ea..2e489f6ba65 100644
    --- a/htdocs/core/class/translate.class.php
    +++ b/htdocs/core/class/translate.class.php
    @@ -655,11 +655,12 @@ class Translate
     	 *  @param  string	$param2     chaine de param2
     	 *  @param  string	$param3     chaine de param3
     	 *  @param  string	$param4     chaine de param4
    +	 *  @param  string	$param5     chaine de param5
     	 *  @return string      		Translated string (encoded into UTF8)
     	 */
    -	function transnoentities($key, $param1='', $param2='', $param3='', $param4='')
    +	function transnoentities($key, $param1='', $param2='', $param3='', $param4='', $param5='')
     	{
    -		return $this->convToOutputCharset($this->transnoentitiesnoconv($key, $param1, $param2, $param3, $param4));
    +		return $this->convToOutputCharset($this->transnoentitiesnoconv($key, $param1, $param2, $param3, $param4, $param5));
     	}
     
     
    @@ -675,9 +676,10 @@ class Translate
     	 *  @param  string	$param2     chaine de param2
     	 *  @param  string	$param3     chaine de param3
     	 *  @param  string	$param4     chaine de param4
    +	 *  @param  string	$param5     chaine de param5
     	 *  @return string      		Translated string
     	 */
    -	function transnoentitiesnoconv($key, $param1='', $param2='', $param3='', $param4='')
    +	function transnoentitiesnoconv($key, $param1='', $param2='', $param3='', $param4='', $param5='')
     	{
     		global $conf;
     
    @@ -700,7 +702,7 @@ class Translate
                 if (! preg_match('/^Format/',$key))
                 {
                 	//print $str;
    -           		$str=sprintf($str,$param1,$param2,$param3,$param4);	// Replace %s and %d except for FormatXXX strings.
    +           		$str=sprintf($str, $param1, $param2, $param3, $param4, $param5);	// Replace %s and %d except for FormatXXX strings.
                 }
     
                 return $str;
    @@ -756,6 +758,7 @@ class Translate
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of all available languages
     	 *
    @@ -766,6 +769,7 @@ class Translate
     	 */
     	function get_available_languages($langdir=DOL_DOCUMENT_ROOT,$maxlength=0,$usecode=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		// We scan directory langs to detect available languages
    @@ -795,6 +799,7 @@ class Translate
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return if a filename $filename exists for current language (or alternate language)
     	 *
    @@ -804,6 +809,7 @@ class Translate
     	 */
     	function file_exists($filename,$searchalt=0)
     	{
    +        // phpcs:enable
     		// Test si fichier dans repertoire de la langue
     		foreach($this->dir as $searchdir)
     		{
    @@ -1018,6 +1024,7 @@ class Translate
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return an array with content of all loaded translation keys (found into this->tab_translate) so
     	 * we get a substitution array we can use for substitutions (for mail or ODT generation for example)
    @@ -1026,6 +1033,7 @@ class Translate
     	 */
     	function get_translations_for_substitutions()
     	{
    +        // phpcs:enable
     		$substitutionarray = array();
     
     		foreach($this->tab_translate as $code => $label) {
    diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
    index ec95063906c..e3b151f9874 100644
    --- a/htdocs/core/class/utils.class.php
    +++ b/htdocs/core/class/utils.class.php
    @@ -27,7 +27,10 @@
      */
     class Utils
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $output;   // Used by Cron method to return message
     	var $result;   // Used by Cron method to return data
    @@ -281,8 +284,9 @@ class Utils
     			}
     
     			$errormsg='';
    +			$handle = '';
     
    -			// Debut appel methode execution
    +			// Start call method to execute dump
     			$fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
     			$fullcommandclear=$command." ".$paramclear." 2>&1";
     			if ($compression == 'none') $handle = fopen($outputfile, 'w');
    @@ -339,7 +343,6 @@ class Utils
     						elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1;
     					}
     					pclose($handlein);
    -
     				}
     
     
    @@ -374,7 +377,7 @@ class Utils
     				{
     					// Renommer fichier sortie en fichier erreur
     					//print "$outputfile -> $outputerror";
    -					@dol_delete_file($outputerror,1);
    +					@dol_delete_file($outputerror, 1, 0, 0, null, false, 0);
     					@rename($outputfile,$outputerror);
     					// Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide
     					if (! $errormsg)
    @@ -406,13 +409,13 @@ class Utils
     
     			if ($compression == 'gz' or $compression == 'bz')
     			{
    -				$this->backup_tables($outputfiletemp);
    +				$this->backupTables($outputfiletemp);
     				dol_compress_file($outputfiletemp, $outputfile, $compression);
     				unlink($outputfiletemp);
     			}
     			else
     			{
    -				$this->backup_tables($outputfile);
    +				$this->backupTables($outputfile);
     			}
     
     			$this->output = "";
    @@ -481,7 +484,7 @@ class Utils
     			{
     				$i++;
     				if ($i <= $keeplastnfiles) continue;
    -				dol_delete_file($val['fullname']);
    +				dol_delete_file($val['fullname'], 0, 0, 0, null, false, 0);
     			}
     		}
     
    @@ -708,12 +711,14 @@ class Utils
     	}
     
     	/**
    -	 * This saves syslog files and compresses older ones
    -	 * Used from cronjob
    +	 * This saves syslog files and compresses older ones.
    +	 * Nb of archive to keep is defined into $conf->global->SYSLOG_FILE_SAVES
    +	 * CAN BE A CRON TASK
     	 *
     	 * @return	int						0 if OK, < 0 if KO
     	 */
    -	function compressSyslogs() {
    +    function compressSyslogs()
    +    {
     		global $conf;
     
     		if(empty($conf->loghandlers['mod_syslog_file'])) { // File Syslog disabled
    @@ -746,50 +751,52 @@ class Utils
     			$logname = $file['name'];
     			$logpath = $file['path'];
     
    -			// Handle already compressed files to rename them and add +1
    +			if (dol_is_file($logpath.'/'.$logname) && dol_filesize($logpath.'/'.$logname) > 0)	// If log file exists and is not empty
    +			{
    +				// Handle already compressed files to rename them and add +1
     
    -			$filter = '^'.preg_quote($logname, '/').'\.([0-9]+)\.gz$';
    +				$filter = '^'.preg_quote($logname, '/').'\.([0-9]+)\.gz$';
     
    -			$gzfilestmp = dol_dir_list($logpath, 'files', 0, $filter);
    -			$gzfiles = array();
    +				$gzfilestmp = dol_dir_list($logpath, 'files', 0, $filter);
    +				$gzfiles = array();
     
    -			foreach($gzfilestmp as $gzfile) {
    -				$tabmatches = array();
    -				preg_match('/'.$filter.'/i', $gzfile['name'], $tabmatches);
    +				foreach($gzfilestmp as $gzfile) {
    +					$tabmatches = array();
    +					preg_match('/'.$filter.'/i', $gzfile['name'], $tabmatches);
     
    -				$numsave = intval($tabmatches[1]);
    +					$numsave = intval($tabmatches[1]);
     
    -				$gzfiles[$numsave] = $gzfile;
    -			}
    -
    -			krsort($gzfiles, SORT_NUMERIC);
    -
    -			foreach($gzfiles as $numsave => $dummy) {
    -				if (dol_is_file($logpath.'/'.$logname.'.'.($numsave+1).'.gz')) {
    -					return -2;
    +					$gzfiles[$numsave] = $gzfile;
     				}
     
    -				if($numsave >= $nbSaves) {
    -					dol_delete_file($logpath.'/'.$logname.'.'.$numsave.'.gz');
    -				} else {
    -					dol_move($logpath.'/'.$logname.'.'.$numsave.'.gz', $logpath.'/'.$logname.'.'.($numsave+1).'.gz', 0, 1, 0, 0);
    -				}
    -			}
    +				krsort($gzfiles, SORT_NUMERIC);
     
    -			// Compress last save
    -			if (dol_is_file($logpath.'/'.$logname.'.1')) {
    -				if($nbSaves > 1) {
    -					$gzfilehandle = gzopen($logpath.'/'.$logname.'.2.gz', 'wb9');
    +				foreach($gzfiles as $numsave => $dummy) {
    +					if (dol_is_file($logpath.'/'.$logname.'.'.($numsave+1).'.gz')) {
    +						return -2;
    +					}
    +
    +					if($numsave >= $nbSaves) {
    +						dol_delete_file($logpath.'/'.$logname.'.'.$numsave.'.gz', 0, 0, 0, null, false, 0);
    +					} else {
    +						dol_move($logpath.'/'.$logname.'.'.$numsave.'.gz', $logpath.'/'.$logname.'.'.($numsave+1).'.gz', 0, 1, 0, 0);
    +					}
    +				}
    +
    +				// Compress current file and recreate it
    +
    +				if ($nbSaves > 0) {			// If $nbSaves is 1, we keep 1 archive .gz file, If 2, we keep 2 .gz files
    +					$gzfilehandle = gzopen($logpath.'/'.$logname.'.1.gz', 'wb9');
     
     					if (empty($gzfilehandle)) {
    -						$this->error = 'Failted to open file '.$logpath.'/'.$logname.'.2.gz';
    +						$this->error = 'Failted to open file '.$logpath.'/'.$logname.'.1.gz';
     						return -3;
     					}
     
    -					$sourcehandle = fopen($logpath.'/'.$logname.'.1', 'r');
    +					$sourcehandle = fopen($logpath.'/'.$logname, 'r');
     
     					if (empty($sourcehandle)) {
    -						$this->error = 'Failed to open file '.$logpath.'/'.$logname.'.1';
    +						$this->error = 'Failed to open file '.$logpath.'/'.$logname;
     						return -4;
     					}
     
    @@ -799,19 +806,18 @@ class Utils
     
     					fclose($sourcehandle);
     					gzclose($gzfilehandle);
    -				} else {
    -					dol_delete_file($logpath.'/'.$logname.'.1');
    -				}
    -			}
     
    -			// Compress current file et recreate it
    -
    -			if (dol_is_file($logpath.'/'.$logname)) {
    -				if (dol_move($logpath.'/'.$logname, $logpath.'/'.$logname.'.1', 0, 1, 0, 0))
    -				{
    -					$newlog = fopen($logpath.'/'.$logname, 'a+');
    -					fclose($newlog);
    +					@chmod($logpath.'/'.$logname.'.1.gz', octdec(empty($conf->global->MAIN_UMASK)?'0664':$conf->global->MAIN_UMASK));
     				}
    +
    +				dol_delete_file($logpath.'/'.$logname, 0, 0, 0, null, false, 0);
    +
    +				// Create empty file
    +				$newlog = fopen($logpath.'/'.$logname, 'a+');
    +				fclose($newlog);
    +
    +				//var_dump($logpath.'/'.$logname." - ".octdec(empty($conf->global->MAIN_UMASK)?'0664':$conf->global->MAIN_UMASK));
    +				@chmod($logpath.'/'.$logname, octdec(empty($conf->global->MAIN_UMASK)?'0664':$conf->global->MAIN_UMASK));
     			}
     		}
     
    @@ -829,7 +835,7 @@ class Utils
     	 *	@param	string	$tables			Table name or '*' for all
     	 *	@return	int						<0 if KO, >0 if OK
     	 */
    -	function backup_tables($outputfile, $tables='*')
    +	function backupTables($outputfile, $tables='*')
     	{
     		global $db, $langs;
     		global $errormsg;
    @@ -989,4 +995,4 @@ class Utils
     
     		return 1;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/core/class/vcard.class.php b/htdocs/core/class/vcard.class.php
    index 8bdeb3e43b7..c3dc5547d88 100644
    --- a/htdocs/core/class/vcard.class.php
    +++ b/htdocs/core/class/vcard.class.php
    @@ -111,12 +111,13 @@ class vCard
          *	mise en forme de la photo
          *  warning NON TESTE !
          *
    -     *	@param	string	$type			Type
    -     *	@param	string	$photo			Photo
    -     *	@return	void
    -	 */
    +     *  @param  string  $type			Type
    +     *  @param  string  $photo			Photo
    +     *  @return	void
    +     */
         function setPhoto($type, $photo)
    -    { // $type = "GIF" | "JPEG"
    +    {
    +        // $type = "GIF" | "JPEG"
             $this->properties["PHOTO;TYPE=$type;ENCODING=BASE64"] = base64_encode($photo);
         }
     
    @@ -155,7 +156,7 @@ class vCard
          *	@return	void
          */
         function setBirthday($date)
    -    { 
    +    {
             // $date format is YYYY-MM-DD - RFC 2425 and RFC 2426
             $this->properties["BDAY"] = dol_print_date($date, 'dayrfc');
         }
    @@ -200,7 +201,8 @@ class vCard
          *	@param	string	$type			Type
          *	@return	void
          */
    -    function setLabel($postoffice="", $extended="", $street="", $city="", $region="", $zip="", $country="", $type="HOME;POSTAL") {
    +    function setLabel($postoffice="", $extended="", $street="", $city="", $region="", $zip="", $country="", $type="HOME;POSTAL")
    +    {
             $label = "";
             if ($postoffice!="") $label.= "$postoffice\r\n";
             if ($extended!="") $label.= "$extended\r\n";
    @@ -328,5 +330,4 @@ class vCard
         {
             return $this->filename;
         }
    -
     }
    diff --git a/htdocs/core/class/workboardresponse.class.php b/htdocs/core/class/workboardresponse.class.php
    index 13de74281ff..35449693599 100644
    --- a/htdocs/core/class/workboardresponse.class.php
    +++ b/htdocs/core/class/workboardresponse.class.php
    @@ -1,6 +1,7 @@
     <?php
     
     /* Copyright (C) 2015   Marcos García   <marcosgdf@gmail.com>
    + * Copyright (C) 2018   Charlene Benke  <charlie@patas-monkey.com>
      *
      * 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
    @@ -66,4 +67,9 @@ class WorkboardResponse
     	 */
     	public $nbtodolate = 0;
     
    -}
    \ No newline at end of file
    +	/**
    +	 * total price of items
    +	 * @var int
    +	 */
    +	public $total = 0;
    +}
    diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php
    index 074760e88ca..546ca757234 100644
    --- a/htdocs/core/datepicker.php
    +++ b/htdocs/core/datepicker.php
    @@ -41,8 +41,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09'));	// If language was forced on URL by the main.inc.php
     
    -$langs->load("main");
    -$langs->load("agenda");
    +// Load translation files required by the page
    +$langs->loadLangs(array("main","agenda"));
     
     $right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
     $left=($langs->trans("DIRECTION")=='rtl'?'right':'left');
    @@ -66,18 +66,19 @@ else
     }
     
     // Define tradMonths javascript array (we define this in datapicker AND in parent page to avoid errors with IE8)
    -$tradTemp=array($langs->trans("January"),
    -$langs->trans("February"),
    -$langs->trans("March"),
    -$langs->trans("April"),
    -$langs->trans("May"),
    -$langs->trans("June"),
    -$langs->trans("July"),
    -$langs->trans("August"),
    -$langs->trans("September"),
    -$langs->trans("October"),
    -$langs->trans("November"),
    -$langs->trans("December")
    +$tradTemp=array(
    +    $langs->trans("January"),
    +    $langs->trans("February"),
    +    $langs->trans("March"),
    +    $langs->trans("April"),
    +    $langs->trans("May"),
    +    $langs->trans("June"),
    +    $langs->trans("July"),
    +    $langs->trans("August"),
    +    $langs->trans("September"),
    +    $langs->trans("October"),
    +    $langs->trans("November"),
    +    $langs->trans("December")
     );
     print '<script type="text/javascript">';
     print 'var tradMonths = [';
    @@ -96,25 +97,22 @@ $qualified=true;
     
     if (! isset($_GET["sd"])) $_GET["sd"]="00000000";
     
    -if (! isset($_GET["m"])) $qualified=false;
    -if (! isset($_GET["y"])) $qualified=false;
    +if (! isset($_GET["m"]) || ! isset($_GET["y"])) $qualified=false;
     if (isset($_GET["m"]) && isset($_GET["y"]))
     {
    -	if ($_GET["m"] < 1)    $qualified=false;
    -	if ($_GET["m"] > 12)   $qualified=false;
    -	if ($_GET["y"] < 0)    $qualified=false;
    -	if ($_GET["y"] > 9999) $qualified=false;
    +	if ($_GET["m"] < 1 || $_GET["m"] > 12) $qualified=false;
    +	if ($_GET["y"] < 0 || $_GET["y"] > 9999) $qualified=false;
     }
     
     // If parameters provided, we show calendar
     if ($qualified)
     {
     	//print $_GET["cm"].",".$_GET["sd"].",".$_GET["m"].",".$_GET["y"];exit;
    -	displayBox(GETPOST("sd",'alpha'),GETPOST("m",'int'),GETPOST("y",'int'));
    +	displayBox(GETPOST("sd",'alpha'), GETPOST("m",'int'), GETPOST("y",'int'));
     }
     else
     {
    -	dol_print_error('','ErrorBadParameters');
    +	dol_print_error('', 'ErrorBadParameters');
     }
     
     
    @@ -195,9 +193,7 @@ function displayBox($selectedDate,$month,$year)
     	{
     		echo '<td width="', (int) (($i+1)*100/7) - (int) ($i*100/7), '%">', $langs->trans($day_names[($i + $startday) % 7]), '</td>', "\n";
     	}
    -	?>
    -	</tr>
    -	<?php
    +	print '</tr>';
     	//print "x ".$thedate." y";			// $thedate = first day of month
     	$firstdate=dol_getdate($thedate);
     	//var_dump($firstdateofweek);
    @@ -210,7 +206,7 @@ function displayBox($selectedDate,$month,$year)
     		//print_r($mydate);
     		if ($mydate < $firstdate)	// At first run
     		{
    -			echo "<TR class=\"dpWeek\">";
    +			echo "<tr class=\"dpWeek\">";
     			//echo $conf->global->MAIN_START_WEEK.' '.$firstdate["wday"].' '.$startday;
     			$cols=0;
     			for ($i = 0; $i < 7; $i++)
    @@ -221,7 +217,7 @@ function displayBox($selectedDate,$month,$year)
     					$mydate = $firstdate;
     					break;
     				}
    -				echo "<TD>&nbsp;</TD>";
    +				echo "<td>&nbsp;</td>";
     				$cols++;
     			}
     		}
    @@ -229,7 +225,7 @@ function displayBox($selectedDate,$month,$year)
     		{
     			if ($mydate["wday"] == $startday)
     			{
    -				echo "<TR class=\"dpWeek\">";
    +				echo "<tr class=\"dpWeek\">";
     				$cols=0;
     			}
     		}
    @@ -245,17 +241,17 @@ function displayBox($selectedDate,$month,$year)
     		}
     
     		// Sur click dans calendrier, appelle fonction dpClickDay
    -		echo "<TD class=\"".$dayclass."\"";
    +		echo "<td class=\"".$dayclass."\"";
     		echo " onMouseOver=\"dpHighlightDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",tradMonths)\"";
     		echo " onClick=\"dpClickDay(".$mydate["year"].",parseInt('".dol_print_date($thedate,"%m")."',10),".$mydate["mday"].",'".$langs->trans("FormatDateShortJavaInput")."')\"";
    -		echo ">".sprintf("%02s",$mydate["mday"])."</TD>";
    +		echo ">".sprintf("%02s",$mydate["mday"])."</td>";
     		$cols++;
     
     		if (($mydate["wday"] + 1) % 7 == $startday) echo "</TR>\n";
     
     		//$thedate=strtotime("tomorrow",$thedate);
     		$day++;
    -		$thedate=dol_mktime(12,0,0,$month,$day,$year);
    +		$thedate=dol_mktime(12, 0, 0, $month, $day, $year);
     		if ($thedate == '')
     		{
     			$stoploop=1;
    @@ -269,8 +265,8 @@ function displayBox($selectedDate,$month,$year)
     
     	if ($cols < 7)
     	{
    -		for($i=6; $i>=$cols; $i--) echo "<TD>&nbsp;</TD>";
    -		echo "</TR>\n";
    +		for($i=6; $i>=$cols; $i--) echo "<td>&nbsp;</td>";
    +		echo "</tr>\n";
     	}
     	?>
     	<tr>
    diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php
    index 65699585f4a..db233dda1b4 100644
    --- a/htdocs/core/db/Database.interface.php
    +++ b/htdocs/core/db/Database.interface.php
    @@ -35,13 +35,15 @@ interface Database
     	 */
     	function ifsql($test, $resok, $resko);
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return datas as an array
     	 *
     	 * @param   resource $resultset Resultset of request
     	 * @return  array                    Array
     	 */
    -	function fetch_row($resultset);
    +    function fetch_row($resultset);
    +    // phpcs:enable
     
     	/**
     	 * Convert (by PHP) a GM Timestamp date into a string date with PHP server TZ to insert into a date field.
    @@ -66,6 +68,7 @@ interface Database
     	 */
     	function begin();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create a new database
     	 * Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
    @@ -77,7 +80,8 @@ interface Database
     	 * @param   string 		$owner 			Username of database owner
     	 * @return  resource                	resource defined if OK, null if KO
     	 */
    -	function DDLCreateDb($database, $charset = '', $collation = '', $owner = '');
    +    function DDLCreateDb($database, $charset = '', $collation = '', $owner = '');
    +    // phpcs:enable
     
     	/**
     	 * Return version of database server into an array
    @@ -95,6 +99,7 @@ interface Database
     	 */
     	static function convertSQLFromMysql($line, $type = 'ddl');
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE
     	 *
    @@ -102,7 +107,8 @@ interface Database
     	 * @return 	int            Nombre de lignes
     	 * @see    	num_rows
     	 */
    -	function affected_rows($resultset);
    +    function affected_rows($resultset);
    +    // phpcs:enable
     
     	/**
     	 * Return description of last error
    @@ -111,6 +117,7 @@ interface Database
     	 */
     	function error();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  List tables into a database
     	 *
    @@ -118,7 +125,8 @@ interface Database
     	 *  @param	string		$table		Nmae of table filter ('xxx%')
     	 *  @return	array					List of tables in an array
     	 */
    -	function DDLListTables($database, $table = '');
    +    function DDLListTables($database, $table = '');
    +    // phpcs:enable
     
     	/**
     	 * Return last request executed with query()
    @@ -144,13 +152,15 @@ interface Database
     	 */
     	function decrypt($value);
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return datas as an array
     	 *
     	 * @param   resource $resultset Resultset of request
     	 * @return  array                    Array
     	 */
    -	function fetch_array($resultset);
    +    function fetch_array($resultset);
    +    // phpcs:enable
     
     	/**
     	 * Return last error label
    @@ -167,6 +177,7 @@ interface Database
     	 */
     	function escape($stringtoencode);
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get last ID after an insert INSERT
     	 *
    @@ -174,7 +185,8 @@ interface Database
     	 * @param   string 	$fieldid 	Field name
     	 * @return  int                	Id of row
     	 */
    -	function last_insert_id($tab, $fieldid = 'rowid');
    +    function last_insert_id($tab, $fieldid = 'rowid');
    +    // phpcs:enable
     
     	/**
     	 *    Return full path of restore program
    @@ -196,7 +208,7 @@ interface Database
     	 *
     	 * @param   string $query SQL query string
     	 * @param   int $usesavepoint 0=Default mode, 1=Run a savepoint before and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
    -	 *                                    Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints.
    +	 *                            Note that with Mysql, this parameter is not used as Myssql can already commit a transaction even if one request is in error, without using savepoints.
     	 * @param   string $type Type of SQL order ('ddl' for insert, update, select, delete or 'dml' for create, alter...)
     	 * @return  resource                Resultset of answer
     	 */
    @@ -247,6 +259,7 @@ interface Database
     	 */
     	function getDefaultCollationDatabase();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return number of lines for result of a SELECT
     	 *
    @@ -254,7 +267,8 @@ interface Database
     	 * @return 	int                        Nb of lines
     	 * @see    	affected_rows
     	 */
    -	function num_rows($resultset);
    +    function num_rows($resultset);
    +    // phpcs:enable
     
     	/**
     	 * Return full path of dump program
    @@ -277,6 +291,7 @@ interface Database
     	 */
     	function errno();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create a table into database
     	 *
    @@ -289,15 +304,18 @@ interface Database
     	 * @param        array $keys 			Tableau des champs cles noms => valeur
     	 * @return       int                    <0 if KO, >=0 if OK
     	 */
    -	function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null);
    +    function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null);
    +    // phpcs:enable
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Drop a table into database
     	 *
     	 * @param        string $table 			Name of table
     	 * @return       int                    <0 if KO, >=0 if OK
     	 */
    -	function DDLDropTable($table);
    +    function DDLDropTable($table);
    +    // phpcs:enable
     
     	/**
     	 * Return list of available charset that can be used to store data in database
    @@ -306,6 +324,7 @@ interface Database
     	 */
     	function getListOfCharacterSet();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create a new field into table
     	 *
    @@ -315,8 +334,10 @@ interface Database
     	 * @param    string $field_position 	Optionnel ex.: "after champtruc"
     	 * @return   int                        <0 if KO, >0 if OK
     	 */
    -	function DDLAddField($table, $field_name, $field_desc, $field_position = "");
    +    function DDLAddField($table, $field_name, $field_desc, $field_position = "");
    +    // phpcs:enable
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Drop a field from table
     	 *
    @@ -324,8 +345,10 @@ interface Database
     	 * @param    string $field_name 		Name of field to drop
     	 * @return   int                        <0 if KO, >0 if OK
     	 */
    -	function DDLDropField($table, $field_name);
    +    function DDLDropField($table, $field_name);
    +    // phpcs:enable
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Update format of a field into a table
     	 *
    @@ -334,7 +357,8 @@ interface Database
     	 * @param    string 	$field_desc 	Array with description of field format
     	 * @return   int                        <0 if KO, >0 if OK
     	 */
    -	function DDLUpdateField($table, $field_name, $field_desc);
    +    function DDLUpdateField($table, $field_name, $field_desc);
    +    // phpcs:enable
     
     	/**
     	 * Return list of available collation that can be used for database
    @@ -343,6 +367,7 @@ interface Database
     	 */
     	function getListOfCollation();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return a pointer of line with description of a table or field
     	 *
    @@ -350,7 +375,8 @@ interface Database
     	 * @param    string 	$field 			Optionnel : Name of field if we want description of field
     	 * @return   resource            		Resource
     	 */
    -	function DDLDescTable($table, $field = "");
    +    function DDLDescTable($table, $field = "");
    +    // phpcs:enable
     
     	/**
     	 * Return version of database server
    @@ -366,6 +392,7 @@ interface Database
     	 */
     	function getDefaultCharacterSetDatabase();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create a user and privileges to connect to database (even if database does not exists yet)
     	 *
    @@ -380,7 +407,8 @@ interface Database
     		$dolibarr_main_db_user,
     		$dolibarr_main_db_pass,
     		$dolibarr_main_db_name
    -	);
    +    );
    +    // phpcs:enable
     
     	/**
     	 * Convert (by PHP) a PHP server TZ string date into a Timestamps date (GMT if gm=true)
    @@ -411,13 +439,15 @@ interface Database
     	 */
     	function commit($log = '');
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * List information of columns into a table.
     	 *
     	 * @param   string 			$table 			Name of table
     	 * @return  array                			Array with inforation on table
     	 */
    -	function DDLInfoTable($table);
    +    function DDLInfoTable($table);
    +    // phpcs:enable
     
     	/**
     	 * Free last resultset used.
    @@ -442,27 +472,32 @@ interface Database
     	 */
     	function lastqueryerror();
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return connexion ID
     	 *
     	 * @return  string      Id connexion
     	 */
    -	function DDLGetConnectId();
    +    function DDLGetConnectId();
    +    // phpcs:enable
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoie la ligne courante (comme un objet) pour le curseur resultset
     	 *
     	 * @param   resource $resultset Curseur de la requete voulue
     	 * @return  Object                    Object result line or false if KO or end of cursor
     	 */
    -	function fetch_object($resultset);
    +    function fetch_object($resultset);
    +    // phpcs:enable
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Select a database
     	 *
     	 * @param	string $database Name of database
     	 * @return  boolean            true if OK, false if KO
     	 */
    -	function select_db($database);
    -
    +    function select_db($database);
    +    // phpcs:enable
     }
    diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php
    index 4734c3364b5..a8483ec1401 100644
    --- a/htdocs/core/db/mssql.class.php
    +++ b/htdocs/core/db/mssql.class.php
    @@ -139,6 +139,7 @@ class DoliDBMssql extends DoliDB
     		return $line;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Select a database
     	 *
    @@ -147,6 +148,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function select_db($database)
     	{
    +        // phpcs:enable
     		return @mssql_select_db($database, $this->db);
     	}
     
    @@ -372,7 +374,6 @@ class DoliDBMssql extends DoliDB
                         $query="ALTER TABLE [".$matches[1]."] ADD CONSTRAINT [".$matches[2]."] PRIMARY KEY CLUSTERED (".$matches[3].")";
         		    }
         		}
    -
     		}
     
     		if ($type=="auto" || $type='ddl')
    @@ -414,7 +415,6 @@ class DoliDBMssql extends DoliDB
         	       $sql='SET IDENTITY_INSERT ['.trim($matches[1]).'] ON;';
         	       @mssql_query($sql, $this->db);
         	       $post_query='SET IDENTITY_INSERT ['.trim($matches[1]).'] OFF;';
    -
         	   }
     		}
     		//print "<!--".$query."-->";
    @@ -459,6 +459,7 @@ class DoliDBMssql extends DoliDB
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoie la ligne courante (comme un objet) pour le curseur resultset
     	 *
    @@ -467,11 +468,13 @@ class DoliDBMssql extends DoliDB
     	 */
     	function fetch_object($resultset)
     	{
    +        // phpcs:enable
     		// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return mssql_fetch_object($resultset);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Return datas as an array
          *
    @@ -480,12 +483,14 @@ class DoliDBMssql extends DoliDB
     	 */
     	function fetch_array($resultset)
     	{
    +        // phpcs:enable
     		// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return mssql_fetch_array($resultset);
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Return datas as an array
          *
    @@ -494,11 +499,13 @@ class DoliDBMssql extends DoliDB
     	 */
     	function fetch_row($resultset)
     	{
    +        // phpcs:enable
     		// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return @mssql_fetch_row($resultset);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Return number of lines for result of a SELECT
          *
    @@ -508,11 +515,13 @@ class DoliDBMssql extends DoliDB
     	 */
     	function num_rows($resultset)
     	{
    +        // phpcs:enable
     		// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return mssql_num_rows($resultset);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE
     	 *
    @@ -522,6 +531,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function affected_rows($resultset)
     	{
    +        // phpcs:enable
     		// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		// mssql necessite un link de base pour cette fonction contrairement
    @@ -639,6 +649,7 @@ class DoliDBMssql extends DoliDB
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get last ID after an insert INSERT
     	 *
    @@ -648,6 +659,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function last_insert_id($tab,$fieldid='rowid')
     	{
    +        // phpcs:enable
     		$res = $this->query("SELECT @@IDENTITY as id");
     		if ($res && $data = $this->fetch_array($res))
     		{
    @@ -702,6 +714,7 @@ class DoliDBMssql extends DoliDB
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return connexion ID
     	 *
    @@ -709,6 +722,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLGetConnectId()
     	{
    +        // phpcs:enable
     		$resql=$this->query('SELECT CONNECTION_ID()');
     		if ($resql)
     		{
    @@ -718,6 +732,7 @@ class DoliDBMssql extends DoliDB
     		else return '?';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a new database
     	 *	Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
    @@ -731,6 +746,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLCreateDb($database,$charset='',$collation='',$owner='')
     	{
    +        // phpcs:enable
             /*if (empty($charset))   $charset=$this->forcecharset;
             if (empty($collation)) $collation=$this->forcecollate;
             */
    @@ -754,6 +770,7 @@ class DoliDBMssql extends DoliDB
     	    return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  List tables into a database
     	 *
    @@ -763,10 +780,12 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLListTables($database,$table='')
     	{
    +        // phpcs:enable
     		$this->_results = mssql_list_tables($database, $this->db);
     		return $this->_results;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	List information of columns into a table.
     	 *
    @@ -775,6 +794,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLInfoTable($table)
     	{
    +        // phpcs:enable
     
     		// FIXME: Dummy method
     		// TODO: Implement
    @@ -784,6 +804,7 @@ class DoliDBMssql extends DoliDB
     		return $infotables;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a table into database
     	 *
    @@ -798,6 +819,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys=null,$fulltext_keys=null,$keys=null)
     	{
    +        // phpcs:enable
     		// FIXME: $fulltext_keys parameter is unused
     
     		// cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
    @@ -863,6 +885,7 @@ class DoliDBMssql extends DoliDB
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Drop a table into database
     	 *
    @@ -871,6 +894,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLDropTable($table)
     	{
    +        // phpcs:enable
     		$sql = "DROP TABLE ".$table;
     
     		if (! $this->query($sql))
    @@ -879,6 +903,7 @@ class DoliDBMssql extends DoliDB
     			return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return a pointer of line with description of a table or field
     	 *
    @@ -888,6 +913,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLDescTable($table,$field="")
     	{
    +        // phpcs:enable
     		$sql="DESC ".$table." ".$field;
     
     		dol_syslog($sql);
    @@ -895,6 +921,7 @@ class DoliDBMssql extends DoliDB
     		return $this->_results;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a new field into table
     	 *
    @@ -906,6 +933,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLAddField($table,$field_name,$field_desc,$field_position="")
     	{
    +        // phpcs:enable
     		// cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
     		// ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
     		$sql= "ALTER TABLE ".$table." ADD ".$field_name." ";
    @@ -931,6 +959,7 @@ class DoliDBMssql extends DoliDB
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Update format of a field into a table
     	 *
    @@ -941,6 +970,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLUpdateField($table,$field_name,$field_desc)
     	{
    +        // phpcs:enable
     		$sql = "ALTER TABLE ".$table;
     		$sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
     		if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') {
    @@ -954,6 +984,7 @@ class DoliDBMssql extends DoliDB
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Drop a field from table
     	 *
    @@ -963,6 +994,7 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLDropField($table,$field_name)
     	{
    +        // phpcs:enable
     		$sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`";
     		dol_syslog($sql,LOG_DEBUG);
     		if (! $this->query($sql))
    @@ -973,6 +1005,7 @@ class DoliDBMssql extends DoliDB
     		else return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Create a user and privileges to connect to database (even if database does not exists yet)
     	 *
    @@ -984,7 +1017,8 @@ class DoliDBMssql extends DoliDB
     	 */
     	function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name)
     	{
    -	    $sql = "CREATE LOGIN ".$this->EscapeFieldName($dolibarr_main_db_user)." WITH PASSWORD='$dolibarr_main_db_pass'";
    +        // phpcs:enable
    +        $sql = "CREATE LOGIN ".$this->EscapeFieldName($dolibarr_main_db_user)." WITH PASSWORD='$dolibarr_main_db_pass'";
             dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);	// No sql to avoid password in log
             $resql=$this->query($sql);
             if (! $resql)
    @@ -1132,17 +1166,21 @@ class DoliDBMssql extends DoliDB
     		return array();
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Escape a field name according to escape's syntax
     	 *
     	 * @param      string $fieldname   Field's name to escape
     	 * @return     string              field's name escaped
     	 */
    -	function EscapeFieldName($fieldname) {
    +    function EscapeFieldName($fieldname)
    +    {
    +        // phpcs:enable
     	    return "[".$fieldname."]";
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get information on field
     	 *
    @@ -1150,7 +1188,9 @@ class DoliDBMssql extends DoliDB
     	 * @param      mixed   $fields     String for one field or array of string for multiple field
     	 * @return false|object
     	 */
    -	function GetFieldInformation($table,$fields) {
    +    function GetFieldInformation($table,$fields)
    +    {
    +        // phpcs:enable
     	    $sql="SELECT * from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='".$this->escape($table)."' AND COLUMN_NAME";
     	    if (is_array($fields))
     	    {
    @@ -1174,6 +1214,4 @@ class DoliDBMssql extends DoliDB
     
     	    return $result;
     	}
    -
     }
    -
    diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php
    index 23c19542ae6..868712a31d0 100644
    --- a/htdocs/core/db/mysqli.class.php
    +++ b/htdocs/core/db/mysqli.class.php
    @@ -167,16 +167,18 @@ class DoliDBMysqli extends DoliDB
             return $line;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *	Select a database
    +	 *  Select a database
     	 *
    -	 *	@param	    string	$database	Name of database
    -	 *	@return	    boolean  		    true if OK, false if KO
    +	 *  @param	    string	$database	Name of database
    +	 *  @return	    boolean  		    true if OK, false if KO
     	 */
         function select_db($database)
         {
    +        // phpcs:enable
             dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG);
    -	    return $this->db->select_db($database);
    +        return $this->db->select_db($database);
         }
     
     
    @@ -285,6 +287,7 @@ class DoliDBMysqli extends DoliDB
             return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Renvoie la ligne courante (comme un objet) pour le curseur resultset
          *
    @@ -293,12 +296,14 @@ class DoliDBMysqli extends DoliDB
          */
         function fetch_object($resultset)
         {
    +        // phpcs:enable
             // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
     		return $resultset->fetch_object();
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return datas as an array
          *
    @@ -307,11 +312,13 @@ class DoliDBMysqli extends DoliDB
          */
         function fetch_array($resultset)
         {
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
             return $resultset->fetch_array();
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return datas as an array
          *
    @@ -320,6 +327,7 @@ class DoliDBMysqli extends DoliDB
          */
         function fetch_row($resultset)
         {
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
             if (! is_bool($resultset))
             {
    @@ -333,6 +341,7 @@ class DoliDBMysqli extends DoliDB
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return number of lines for result of a SELECT
          *
    @@ -342,11 +351,13 @@ class DoliDBMysqli extends DoliDB
          */
         function num_rows($resultset)
         {
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
             return $resultset->num_rows;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE
          *
    @@ -356,6 +367,7 @@ class DoliDBMysqli extends DoliDB
          */
         function affected_rows($resultset)
         {
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
             // mysql necessite un link de base pour cette fonction contrairement
    @@ -456,6 +468,7 @@ class DoliDBMysqli extends DoliDB
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 * Get last ID after an insert INSERT
     	 *
    @@ -465,6 +478,7 @@ class DoliDBMysqli extends DoliDB
          */
         function last_insert_id($tab,$fieldid='rowid')
         {
    +        // phpcs:enable
             return $this->db->insert_id;
         }
     
    @@ -538,6 +552,7 @@ class DoliDBMysqli extends DoliDB
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 * Return connexion ID
     	 *
    @@ -545,6 +560,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLGetConnectId()
         {
    +        // phpcs:enable
             $resql=$this->query('SELECT CONNECTION_ID()');
             if ($resql)
             {
    @@ -554,8 +570,9 @@ class DoliDBMysqli extends DoliDB
             else return '?';
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -	 *	Create a new database
    +     *  Create a new database
     	 *	Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
     	 *	We force to create database with charset this->forcecharset and collate this->forcecollate
     	 *
    @@ -567,6 +584,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLCreateDb($database,$charset='',$collation='',$owner='')
         {
    +        // phpcs:enable
             if (empty($charset))   $charset=$this->forcecharset;
             if (empty($collation)) $collation=$this->forcecollate;
     
    @@ -586,6 +604,7 @@ class DoliDBMysqli extends DoliDB
             return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *  List tables into a database
     	 *
    @@ -595,6 +614,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLListTables($database, $table='')
         {
    +        // phpcs:enable
             $listtables=array();
     
             $like = '';
    @@ -612,6 +632,7 @@ class DoliDBMysqli extends DoliDB
             return $listtables;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	List information of columns into a table.
     	 *
    @@ -620,6 +641,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLInfoTable($table)
         {
    +        // phpcs:enable
             $infotables=array();
     
             $sql="SHOW FULL COLUMNS FROM ".$table.";";
    @@ -636,6 +658,7 @@ class DoliDBMysqli extends DoliDB
             return $infotables;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Create a table into database
     	 *
    @@ -650,6 +673,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys=null,$fulltext_keys=null,$keys=null)
         {
    +        // phpcs:enable
     	    // FIXME: $fulltext_keys parameter is unused
     
             // cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
    @@ -718,15 +742,17 @@ class DoliDBMysqli extends DoliDB
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *	Drop a table into database
    +     *  Drop a table into database
          *
          *	@param	    string	$table 			Name of table
          *	@return	    int						<0 if KO, >=0 if OK
          */
         function DDLDropTable($table)
         {
    -    	$sql = "DROP TABLE ".$table;
    +        // phpcs:enable
    +        $sql = "DROP TABLE ".$table;
     
     		if (! $this->query($sql))
      			return -1;
    @@ -734,6 +760,7 @@ class DoliDBMysqli extends DoliDB
         		return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Return a pointer of line with description of a table or field
     	 *
    @@ -743,6 +770,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLDescTable($table,$field="")
         {
    +        // phpcs:enable
             $sql="DESC ".$table." ".$field;
     
             dol_syslog(get_class($this)."::DDLDescTable ".$sql,LOG_DEBUG);
    @@ -750,6 +778,7 @@ class DoliDBMysqli extends DoliDB
             return $this->_results;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Create a new field into table
     	 *
    @@ -761,6 +790,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLAddField($table,$field_name,$field_desc,$field_position="")
         {
    +        // phpcs:enable
             // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
             // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
             $sql= "ALTER TABLE ".$table." ADD ".$field_name." ";
    @@ -800,6 +830,7 @@ class DoliDBMysqli extends DoliDB
             return -1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Update format of a field into a table
     	 *
    @@ -810,6 +841,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLUpdateField($table,$field_name,$field_desc)
         {
    +        // phpcs:enable
             $sql = "ALTER TABLE ".$table;
             $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
             if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') {
    @@ -845,6 +877,7 @@ class DoliDBMysqli extends DoliDB
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Drop a field from table
     	 *
    @@ -854,16 +887,18 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLDropField($table,$field_name)
         {
    +        // phpcs:enable
             $sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`";
             dol_syslog(get_class($this)."::DDLDropField ".$sql,LOG_DEBUG);
             if ($this->query($sql)) {
                 return 1;
             }
    -	    $this->error=$this->lasterror();
    -	    return -1;
    +        $this->error=$this->lasterror();
    +        return -1;
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 * 	Create a user and privileges to connect to database (even if database does not exists yet)
     	 *
    @@ -875,6 +910,7 @@ class DoliDBMysqli extends DoliDB
          */
         function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name)
         {
    +        // phpcs:enable
             $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."'";
             dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);	// No sql to avoid password in log
             $resql=$this->query($sql);
    @@ -1082,4 +1118,3 @@ class DoliDBMysqli extends DoliDB
             return $result;
         }
     }
    -
    diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php
    index 8e57b29109e..78a3b91279e 100644
    --- a/htdocs/core/db/pgsql.class.php
    +++ b/htdocs/core/db/pgsql.class.php
    @@ -359,8 +359,9 @@ class DoliDBPgsql extends DoliDB
     		return $line;
     	}
     
    -	/**
    -	 *	Select a database
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Select a database
          *  Ici postgresql n'a aucune fonction equivalente de mysql_select_db
          *  On compare juste manuellement si la database choisie est bien celle activee par la connexion
     	 *
    @@ -369,9 +370,13 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function select_db($database)
     	{
    -		if ($database == $this->database_name) return true;
    -		else return false;
    -	}
    +        // phpcs:enable
    +        if ($database == $this->database_name) {
    +            return true;
    +        } else {
    +            return false;
    +        }
    +    }
     
     	/**
     	 *	Connexion to server
    @@ -540,6 +545,7 @@ class DoliDBPgsql extends DoliDB
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoie la ligne courante (comme un objet) pour le curseur resultset
     	 *
    @@ -548,12 +554,14 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function fetch_object($resultset)
     	{
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return pg_fetch_object($resultset);
     	}
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *	Return datas as an array
          *
          *	@param	resource	$resultset  Resultset of request
    @@ -561,11 +569,13 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function fetch_array($resultset)
     	{
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return pg_fetch_array($resultset);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Return datas as an array
          *
    @@ -574,25 +584,29 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function fetch_row($resultset)
     	{
    +        // phpcs:enable
     		// Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return pg_fetch_row($resultset);
     	}
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *	Return number of lines for result of a SELECT
          *
          *	@param	resourse	$resultset  Resulset of requests
          *	@return int		    			Nb of lines, -1 on error
          *	@see    affected_rows
    -	 */
    +     */
     	function num_rows($resultset)
     	{
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		return pg_num_rows($resultset);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Renvoie le nombre de lignes dans le resultat d'une requete INSERT, DELETE ou UPDATE
     	 *
    @@ -602,6 +616,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function affected_rows($resultset)
     	{
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
     		if (! is_resource($resultset)) { $resultset=$this->_results; }
     		// pgsql necessite un resultset pour cette fonction contrairement
    @@ -754,6 +769,7 @@ class DoliDBPgsql extends DoliDB
     		return pg_last_error($this->db);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Get last ID after an insert INSERT
     	 *
    @@ -763,6 +779,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function last_insert_id($tab,$fieldid='rowid')
     	{
    +        // phpcs:enable
     		//$result = pg_query($this->db,"SELECT MAX(".$fieldid.") FROM ".$tab);
     		$result = pg_query($this->db,"SELECT currval('".$tab."_".$fieldid."_seq')");
     		if (! $result)
    @@ -819,6 +836,7 @@ class DoliDBPgsql extends DoliDB
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return connexion ID
     	 *
    @@ -826,11 +844,13 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLGetConnectId()
     	{
    +        // phpcs:enable
     		return '?';
     	}
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a new database
     	 *	Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
    @@ -844,6 +864,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLCreateDb($database,$charset='',$collation='',$owner='')
     	{
    +        // phpcs:enable
     	    if (empty($charset))   $charset=$this->forcecharset;
     		if (empty($collation)) $collation=$this->forcecollate;
     
    @@ -856,6 +877,7 @@ class DoliDBPgsql extends DoliDB
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  List tables into a database
     	 *
    @@ -864,7 +886,8 @@ class DoliDBPgsql extends DoliDB
     	 *  @return	array					List of tables in an array
     	 */
     	function DDLListTables($database, $table='')
    -	{
    +    {
    +        // phpcs:enable
     		$listtables=array();
     
     		$like = '';
    @@ -880,6 +903,7 @@ class DoliDBPgsql extends DoliDB
     		return $listtables;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	List information of columns into a table.
     	 *
    @@ -889,6 +913,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLInfoTable($table)
     	{
    +        // phpcs:enable
     		$infotables=array();
     
     		$sql="SELECT ";
    @@ -920,6 +945,7 @@ class DoliDBPgsql extends DoliDB
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a table into database
     	 *
    @@ -934,6 +960,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys=null,$fulltext_keys=null,$keys=null)
     	{
    +        // phpcs:enable
     		// FIXME: $fulltext_keys parameter is unused
     
     		// cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
    @@ -999,6 +1026,7 @@ class DoliDBPgsql extends DoliDB
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Drop a table into database
     	 *
    @@ -1007,6 +1035,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLDropTable($table)
     	{
    +        // phpcs:enable
     		$sql = "DROP TABLE ".$table;
     
     		if (! $this->query($sql))
    @@ -1015,6 +1044,7 @@ class DoliDBPgsql extends DoliDB
     			return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Create a user to connect to database
     	 *
    @@ -1026,6 +1056,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name)
     	{
    +        // phpcs:enable
     		// Note: using ' on user does not works with pgsql
     		$sql = "CREATE USER ".$this->escape($dolibarr_main_db_user)." with password '".$this->escape($dolibarr_main_db_pass)."'";
     
    @@ -1039,6 +1070,7 @@ class DoliDBPgsql extends DoliDB
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return a pointer of line with description of a table or field
     	 *
    @@ -1048,6 +1080,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLDescTable($table,$field="")
     	{
    +        // phpcs:enable
     		$sql ="SELECT attname FROM pg_attribute, pg_type WHERE typname = '".$table."' AND attrelid = typrelid";
     		$sql.=" AND attname NOT IN ('cmin', 'cmax', 'ctid', 'oid', 'tableoid', 'xmin', 'xmax')";
     		if ($field) $sql.= " AND attname = '".$field."'";
    @@ -1057,6 +1090,7 @@ class DoliDBPgsql extends DoliDB
     		return $this->_results;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a new field into table
     	 *
    @@ -1068,34 +1102,36 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLAddField($table,$field_name,$field_desc,$field_position="")
     	{
    +        // phpcs:enable
     		// cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
     		// ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
     		$sql= "ALTER TABLE ".$table." ADD ".$field_name." ";
     		$sql .= $field_desc['type'];
    -		if(preg_match("/^[^\s]/i",$field_desc['value']))
    +		if (preg_match("/^[^\s]/i",$field_desc['value']))
     		    if (! in_array($field_desc['type'],array('int','date','datetime')))
     		    {
     		        $sql.= "(".$field_desc['value'].")";
     		    }
     		if (preg_match("/^[^\s]/i",$field_desc['attribute']))
    -		$sql .= " ".$field_desc['attribute'];
    +            $sql .= " ".$field_desc['attribute'];
     		if (preg_match("/^[^\s]/i",$field_desc['null']))
    -		$sql .= " ".$field_desc['null'];
    +            $sql .= " ".$field_desc['null'];
     		if (preg_match("/^[^\s]/i",$field_desc['default']))
    -		if (preg_match("/null/i",$field_desc['default']))
    -		$sql .= " default ".$field_desc['default'];
    -		else
    -		$sql .= " default '".$field_desc['default']."'";
    +            if (preg_match("/null/i",$field_desc['default']))
    +                $sql .= " default ".$field_desc['default'];
    +		    else
    +                $sql .= " default '".$field_desc['default']."'";
     		if (preg_match("/^[^\s]/i",$field_desc['extra']))
    -		$sql .= " ".$field_desc['extra'];
    +            $sql .= " ".$field_desc['extra'];
     		$sql .= " ".$field_position;
     
     		dol_syslog($sql,LOG_DEBUG);
    -		if(! $this -> query($sql))
    +		if (! $this -> query($sql))
     			return -1;
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Update format of a field into a table
     	 *
    @@ -1106,6 +1142,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLUpdateField($table,$field_name,$field_desc)
     	{
    +        // phpcs:enable
     		$sql = "ALTER TABLE ".$table;
     		$sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
     		if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') {
    @@ -1139,6 +1176,7 @@ class DoliDBPgsql extends DoliDB
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Drop a field from table
     	 *
    @@ -1148,6 +1186,7 @@ class DoliDBPgsql extends DoliDB
     	 */
     	function DDLDropField($table,$field_name)
     	{
    +        // phpcs:enable
     		$sql= "ALTER TABLE ".$table." DROP COLUMN ".$field_name;
     		dol_syslog($sql,LOG_DEBUG);
     		if (! $this->query($sql))
    diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php
    index 78762f282b4..97e799a2b69 100644
    --- a/htdocs/core/db/sqlite3.class.php
    +++ b/htdocs/core/db/sqlite3.class.php
    @@ -260,7 +260,6 @@ class DoliDBSqlite3 extends DoliDB
                         // Pour l'instant les contraintes ne sont pas créées
                         dol_syslog(get_class().'::query line emptied');
                         $line = 'SELECT 0;';
    -
                     }
     
                     //if (preg_match('/rowid\s+.*\s+PRIMARY\s+KEY,/i', $line)) {
    @@ -296,6 +295,7 @@ class DoliDBSqlite3 extends DoliDB
             return $line;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Select a database
          *
    @@ -304,8 +304,9 @@ class DoliDBSqlite3 extends DoliDB
          */
         function select_db($database)
         {
    +        // phpcs:enable
             dol_syslog(get_class($this)."::select_db database=".$database, LOG_DEBUG);
    -	    // sqlite_select_db() does not exist
    +        // sqlite_select_db() does not exist
             //return sqlite_select_db($this->db,$database);
             return true;
         }
    @@ -443,7 +444,6 @@ class DoliDBSqlite3 extends DoliDB
     
                 // dummy statement
                 $query="SELECT 0";
    -
             } else {
                 $query=$this->convertSQLFromMysql($query,$type);
             }
    @@ -490,6 +490,7 @@ class DoliDBSqlite3 extends DoliDB
             return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Renvoie la ligne courante (comme un objet) pour le curseur resultset
          *
    @@ -498,6 +499,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function fetch_object($resultset)
         {
    +        // phpcs:enable
             // Si le resultset n'est pas fourni, on prend le dernier utilise sur cette connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
             //return $resultset->fetch(PDO::FETCH_OBJ);
    @@ -509,6 +511,7 @@ class DoliDBSqlite3 extends DoliDB
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return datas as an array
          *
    @@ -517,6 +520,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function fetch_array($resultset)
         {
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
             //return $resultset->fetch(PDO::FETCH_ASSOC);
    @@ -524,6 +528,7 @@ class DoliDBSqlite3 extends DoliDB
     	    return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return datas as an array
          *
    @@ -532,6 +537,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function fetch_row($resultset)
         {
    +        // phpcs:enable
             // If resultset not provided, we take the last used by connexion
             if (! is_bool($resultset))
             {
    @@ -545,6 +551,7 @@ class DoliDBSqlite3 extends DoliDB
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return number of lines for result of a SELECT
          *
    @@ -554,7 +561,8 @@ class DoliDBSqlite3 extends DoliDB
          */
         function num_rows($resultset)
         {
    -	    // FIXME: SQLite3Result does not have a queryString member
    +        // phpcs:enable
    +        // FIXME: SQLite3Result does not have a queryString member
     
             // If resultset not provided, we take the last used by connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
    @@ -564,6 +572,7 @@ class DoliDBSqlite3 extends DoliDB
             return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Return number of lines for result of a SELECT
          *
    @@ -573,7 +582,8 @@ class DoliDBSqlite3 extends DoliDB
          */
         function affected_rows($resultset)
         {
    -	    // FIXME: SQLite3Result does not have a queryString member
    +        // phpcs:enable
    +        // FIXME: SQLite3Result does not have a queryString member
     
             // If resultset not provided, we take the last used by connexion
             if (! is_object($resultset)) { $resultset=$this->_results; }
    @@ -692,6 +702,7 @@ class DoliDBSqlite3 extends DoliDB
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Get last ID after an insert INSERT
          *
    @@ -701,6 +712,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function last_insert_id($tab,$fieldid='rowid')
         {
    +        // phpcs:enable
             return $this->db->lastInsertRowId();
         }
     
    @@ -773,6 +785,7 @@ class DoliDBSqlite3 extends DoliDB
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return connexion ID
          *
    @@ -780,10 +793,12 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLGetConnectId()
         {
    +        // phpcs:enable
             return '?';
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Create a new database
     	 *	Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated
    @@ -797,6 +812,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLCreateDb($database,$charset='',$collation='',$owner='')
         {
    +        // phpcs:enable
             if (empty($charset))   $charset=$this->forcecharset;
             if (empty($collation)) $collation=$this->forcecollate;
     
    @@ -816,6 +832,7 @@ class DoliDBSqlite3 extends DoliDB
             return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  List tables into a database
          *
    @@ -825,6 +842,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLListTables($database, $table='')
         {
    +        // phpcs:enable
             $listtables=array();
     
             $like = '';
    @@ -842,8 +860,9 @@ class DoliDBSqlite3 extends DoliDB
             return $listtables;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -	 *	List information of columns into a table.
    +     *  List information of columns into a table.
          *
     	 *	@param	string	$table		Name of table
     	 *	@return	array				Tableau des informations des champs de la table
    @@ -851,6 +870,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLInfoTable($table)
         {
    +        // phpcs:enable
             $infotables=array();
     
             $sql="SHOW FULL COLUMNS FROM ".$table.";";
    @@ -867,6 +887,7 @@ class DoliDBSqlite3 extends DoliDB
             return $infotables;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Create a table into database
          *
    @@ -881,7 +902,8 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLCreateTable($table,$fields,$primary_key,$type,$unique_keys=null,$fulltext_keys=null,$keys=null)
         {
    -	    // FIXME: $fulltext_keys parameter is unused
    +        // phpcs:enable
    +        // FIXME: $fulltext_keys parameter is unused
     
             // cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
             // ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
    @@ -945,6 +967,7 @@ class DoliDBSqlite3 extends DoliDB
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Drop a table into database
          *
    @@ -953,6 +976,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLDropTable($table)
         {
    +        // phpcs:enable
         	$sql = "DROP TABLE ".$table;
     
         	if (! $this->query($sql))
    @@ -961,6 +985,7 @@ class DoliDBSqlite3 extends DoliDB
         		return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Return a pointer of line with description of a table or field
          *
    @@ -970,6 +995,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLDescTable($table,$field="")
         {
    +        // phpcs:enable
             $sql="DESC ".$table." ".$field;
     
             dol_syslog(get_class($this)."::DDLDescTable ".$sql,LOG_DEBUG);
    @@ -977,6 +1003,7 @@ class DoliDBSqlite3 extends DoliDB
             return $this->_results;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Create a new field into table
          *
    @@ -988,6 +1015,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLAddField($table,$field_name,$field_desc,$field_position="")
         {
    +        // phpcs:enable
             // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
             // ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
             $sql= "ALTER TABLE ".$table." ADD ".$field_name." ";
    @@ -1020,6 +1048,7 @@ class DoliDBSqlite3 extends DoliDB
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Update format of a field into a table
          *
    @@ -1030,6 +1059,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLUpdateField($table,$field_name,$field_desc)
         {
    +        // phpcs:enable
             $sql = "ALTER TABLE ".$table;
             $sql .= " MODIFY COLUMN ".$field_name." ".$field_desc['type'];
             if ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int' || $field_desc['type'] == 'varchar') {
    @@ -1042,6 +1072,7 @@ class DoliDBSqlite3 extends DoliDB
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *	Drop a field from table
          *
    @@ -1051,6 +1082,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLDropField($table,$field_name)
         {
    +        // phpcs:enable
             $sql= "ALTER TABLE ".$table." DROP COLUMN `".$field_name."`";
             dol_syslog(get_class($this)."::DDLDropField ".$sql,LOG_DEBUG);
             if (! $this->query($sql))
    @@ -1062,8 +1094,9 @@ class DoliDBSqlite3 extends DoliDB
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -	 * 	Create a user and privileges to connect to database (even if database does not exists yet)
    +     * 	Create a user and privileges to connect to database (even if database does not exists yet)
          *
     	 *	@param	string	$dolibarr_main_db_host 		Ip serveur
     	 *	@param	string	$dolibarr_main_db_user 		Nom user a creer
    @@ -1073,6 +1106,7 @@ class DoliDBSqlite3 extends DoliDB
          */
         function DDLCreateUser($dolibarr_main_db_host,$dolibarr_main_db_user,$dolibarr_main_db_pass,$dolibarr_main_db_name)
         {
    +        // phpcs:enable
             $sql = "INSERT INTO user ";
             $sql.= "(Host,User,password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Index_Priv,Alter_priv,Lock_tables_priv)";
             $sql.= " VALUES ('".$this->escape($dolibarr_main_db_host)."','".$this->escape($dolibarr_main_db_user)."',password('".addslashes($dolibarr_main_db_pass)."')";
    @@ -1294,6 +1328,7 @@ class DoliDBSqlite3 extends DoliDB
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          * calc_daynr
          *
    @@ -1302,7 +1337,9 @@ class DoliDBSqlite3 extends DoliDB
          * @param	int     $day 		Day
          * @return int Formatted date
          */
    -    private static function calc_daynr($year, $month, $day) {
    +    private static function calc_daynr($year, $month, $day)
    +    {
    +        // phpcs:enable
             $y = $year;
             if ($y == 0 && $month == 0) return 0;
             $num = (365* $y + 31 * ($month - 1) + $day);
    @@ -1315,6 +1352,7 @@ class DoliDBSqlite3 extends DoliDB
             return $num + floor($y / 4) - $temp;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          * calc_weekday
          *
    @@ -1322,11 +1360,14 @@ class DoliDBSqlite3 extends DoliDB
          * @param bool	$sunday_first_day_of_week		???
          * @return int
          */
    -    private static function calc_weekday($daynr, $sunday_first_day_of_week) {
    -      $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7);
    -      return $ret;
    +    private static function calc_weekday($daynr, $sunday_first_day_of_week)
    +    {
    +        // phpcs:enable
    +        $ret = floor(($daynr + 5 + ($sunday_first_day_of_week ? 1 : 0)) % 7);
    +        return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          * calc_days_in_year
          *
    @@ -1335,9 +1376,11 @@ class DoliDBSqlite3 extends DoliDB
          */
         private static function calc_days_in_year($year)
         {
    -      return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365);
    +        // phpcs:enable
    +        return (($year & 3) == 0 && ($year%100 || ($year%400 == 0 && $year)) ? 366 : 365);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 * calc_week
     	 *
    @@ -1348,7 +1391,9 @@ class DoliDBSqlite3 extends DoliDB
     	 * @param 	string	$calc_year			???
     	 * @return	string						???
     	 */
    -    private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year) {
    +    private static function calc_week($year, $month, $day, $week_behaviour, &$calc_year)
    +    {
    +        // phpcs:enable
             $daynr=self::calc_daynr($year,$month,$day);
             $first_daynr=self::calc_daynr($year,1,1);
             $monday_first= ($week_behaviour & self::WEEK_MONDAY_FIRST) ? 1 : 0;
    @@ -1386,6 +1431,4 @@ class DoliDBSqlite3 extends DoliDB
           }
           return floor($days/7+1);
         }
    -
     }
    -
    diff --git a/htdocs/core/filemanagerdol/connectors/php/io.php b/htdocs/core/filemanagerdol/connectors/php/io.php
    index 66d024edce8..3ac325ed5d4 100644
    --- a/htdocs/core/filemanagerdol/connectors/php/io.php
    +++ b/htdocs/core/filemanagerdol/connectors/php/io.php
    @@ -24,7 +24,7 @@
     
     /**
      * CombinePaths
    - * 
    + *
      * @param   string $sBasePath     sBasePath
      * @param   string $sFolder       sFolder
      * @return  string                Combined path
    @@ -393,13 +393,13 @@ EOF;
     // This is the function that sends the results of the uploading process to CKE.
     /**
      * SendCKEditorResults
    - * 
    + *
      * @param   string  $callback       callback
      * @param   string  $sFileUrl       sFileUrl
      * @param   string  $customMsg      customMsg
      * @return  void
      */
    -function SendCKEditorResults ($callback, $sFileUrl, $customMsg = '')
    +function SendCKEditorResults($callback, $sFileUrl, $customMsg = '')
     {
       echo '<script type="text/javascript">';
     
    @@ -409,5 +409,3 @@ function SendCKEditorResults ($callback, $sFileUrl, $customMsg = '')
     
       echo '</script>';
     }
    -
    -
    diff --git a/htdocs/core/get_info.php b/htdocs/core/get_info.php
    index 2f08a1d7d24..4e52c584083 100644
    --- a/htdocs/core/get_info.php
    +++ b/htdocs/core/get_info.php
    @@ -134,7 +134,7 @@ if (! empty($conf->modulebuilder->enabled))
     
     // Link to print main content area
     /*
    -if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && empty($conf->browser->phone))
    +if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $conf->browser->layout != 'phone')
     {
     	$qs=dol_escape_htmltag($_SERVER["QUERY_STRING"]);
     
    diff --git a/htdocs/core/js/blockUI.js b/htdocs/core/js/blockUI.js
    index 6abcc706e25..20c2bd348d4 100644
    --- a/htdocs/core/js/blockUI.js
    +++ b/htdocs/core/js/blockUI.js
    @@ -41,7 +41,7 @@ $(document).ready(function() {
     				'-moz-border-radius':	 '10px',
     				'border-radius': 		 '10px'
     			},
    -			
    +
     			// styles applied when using $.growlUI
     			dolEventErrorCSS: {
     				width:  	'350px',
    @@ -60,7 +60,7 @@ $(document).ready(function() {
     			}
     
     	};*/
    -	
    +
     	$.dolEventValid = function(title, message, timeout, onClose) {
     		var $m = $('<div class="dolEventValid"></div>');
     		if (title) $m.append('<h1>'+title+'</h1>');
    @@ -73,7 +73,7 @@ $(document).ready(function() {
     			css: $.blockUI.events.dolEventValidCSS
     		});
     	};
    -	
    +
     	$.dolEventError = function(title, message, timeout, onClose) {
     		var $m = $('<div class="dolEventError"></div>');
     		if (title) $m.append('<h1>'+title+'</h1>');
    @@ -87,7 +87,7 @@ $(document).ready(function() {
     		});
     		$('.dolEventError').click($.unblockUI);
     	};
    -	
    +
     	$.pleaseBePatient = function(message) {
     		$.blockUI({
     			message: message,
    diff --git a/htdocs/core/js/lib_photosresize.js b/htdocs/core/js/lib_photosresize.js
    index 9c4c6671b1e..37fb21a4a01 100644
    --- a/htdocs/core/js/lib_photosresize.js
    +++ b/htdocs/core/js/lib_photosresize.js
    @@ -21,10 +21,10 @@
     
     /* Enable jcrop plugin onto id cropbox */
     jQuery(function() {
    -   jQuery('#cropbox').Jcrop({
    -      onSelect: updateCoords, 
    -      onChange: updateCoords
    -   });
    +    jQuery('#cropbox').Jcrop({
    +        onSelect: updateCoords,
    +        onChange: updateCoords
    +    });
     });
     
     /* Update fields that store new size */
    diff --git a/htdocs/core/js/listview.js b/htdocs/core/js/listview.js
    index de3113d0fae..f5ee0af6568 100644
    --- a/htdocs/core/js/listview.js
    +++ b/htdocs/core/js/listview.js
    @@ -22,28 +22,28 @@ var Listview_include = true;
     
     function Listview_OrderDown(idListe, column) {
     	var base_url = document.location.href;
    -	
    +
     	base_url = Listview_recup_form_param(idListe,base_url);
     	base_url = Listview_removeParam(base_url,'Listview['+encodeURIComponent(idListe)+'][orderBy]');
    -	
    +
     	base_url = Listview_removeParam(base_url,'get-all-for-export');
    -	
    +
     	document.location.href=Listview_modifyUrl(base_url,"Listview["+encodeURIComponent(idListe)+"][orderBy]["+encodeURIComponent(column)+"]","DESC");
     }
     function Listview_OrderUp(idListe, column) {
    -	
    +
     	var base_url = document.location.href;
    -	
    +
     	base_url = Listview_recup_form_param(idListe,base_url);
     	base_url = Listview_removeParam(base_url,'Listview['+encodeURIComponent(idListe)+'][orderBy]');
    -	
    +
     	base_url = Listview_removeParam(base_url,'get-all-for-export');
    -	
    +
     	document.location.href=Listview_modifyUrl(base_url,"Listview["+encodeURIComponent(idListe)+"][orderBy]["+encodeURIComponent(column)+"]","ASC");
     }
     function Listview_modifyUrl(strURL,paramName,paramNewValue){
     	    if (strURL.indexOf(paramName+'=')!=-1){
    -        	
    +
                     var strFirstPart=strURL.substring(0,strURL.indexOf(paramName+'=',0))+paramName+'=';
                     var strLastPart="";
                     if (strURL.indexOf('&',strFirstPart.length-1)>0)
    @@ -56,55 +56,55 @@ function Listview_modifyUrl(strURL,paramName,paramNewValue){
                     else
                             strURL+='?'+paramName+'='+paramNewValue;
             }
    -        
    +
             return strURL;
     }
     function Listview_removeParam(strURL, paramMask) {
     	var cpt=0;
     	var url = '';
    -	
    +
     	 while(strURL.indexOf(paramMask)!=-1 && cpt++ <50){
     	 	var strFirstPart= strURL.substring(0,strURL.indexOf(paramMask)-1);
    -	 	
    +
     	 	var strLastPart='';
     	 	if (strURL.indexOf('&',strFirstPart.length+1)>0) {
    -	 		strLastPart = strURL.substring(strURL.indexOf('&',strFirstPart.length+1),strURL.length);	
    +	 		strLastPart = strURL.substring(strURL.indexOf('&',strFirstPart.length+1),strURL.length);
     	 	}
    -	 		
    +
     		url = strFirstPart+strLastPart;
    -	 	
    +
     	 }
    -	 
    +
     	 if(url=='')url = strURL;
    -	 
    +
     	 return url;
     }
     
     function Listview_recup_form_param(idListe,base_url) {
    -	
    +
     	$('#'+idListe+' tr.barre-recherche [listviewtbs],#'+idListe+' tr.barre-recherche-head input,#'+idListe+' tr.barre-recherche-head select,#'+idListe+' div.tabsAction input[listviewtbs]').each(function(i,item) {
     		if($(item).attr("name")) {
     			base_url = Listview_modifyUrl(base_url, $(item).attr("name") , $(item).val());
     		}
    -		
    +
     	});
    -	
    +
     	return base_url;
     }
     
     function Listview_GoToPage(idListe,pageNumber){
    -	
    +
     	var base_url = document.location.href;
    -	
    +
     	base_url = Listview_recup_form_param(idListe,base_url);
     	base_url =Listview_modifyUrl(base_url,"Listview["+encodeURIComponent(idListe)+"][page]",pageNumber);
    -	
    +
     	base_url = Listview_removeParam(base_url,'get-all-for-export');
    -	
    +
     	document.location.href=base_url;
     }
     function Listview_submitSearch(obj) {
    -	
    +
     	$form = $(obj).closest('form');
     	console.log($form);
     	if($form.length>0){
    @@ -113,20 +113,20 @@ function Listview_submitSearch(obj) {
     }
     function Listview_launch_downloadAs(mode,url,token,session_name) {
     	 $('#listviewdAS_export_form').remove();
    -	
    +
     	$form = $('<form action="'+url+'" method="post" name="listviewdAS_export_form" id="listTBSdAS_export_form"></form>');
     	$form.append('<input type="hidden" name="mode" value="'+mode+'" />');
     	$form.append('<input type="hidden" name="token" value="'+token+'" />');
     	$form.append('<input type="hidden" name="session_name" value="'+session_name+'" />');
    -	
    +
     	$('body').append($form);
    -	
    +
         $('#listviewdAS_export_form').submit();
    -	
    +
     }
     
     function Listview_downloadAs(obj, mode,url,token,session_name) {
    -	
    +
     	$form = $(obj).closest('form');
     	$div = $form.find('div.tabsAction');
     	$div.append('<input type="hidden" listviewtbs="hidden" name="token" value="'+token+'" />');
    @@ -134,33 +134,33 @@ function Listview_downloadAs(obj, mode,url,token,session_name) {
     	$div.append('<input type="hidden" listviewtbs="hidden" name="url" value="'+url+'" />');
     	$div.append('<input type="hidden" listviewtbs="hidden" name="session_name" value="'+session_name+'" />');
     	$div.append('<input type="hidden" listviewtbs="hidden" name="get-all-for-export" value="1" />');
    -	
    +
     	Listview_submitSearch(obj);
     }
     
     $(document).ready(function() {
     	$('tr.barre-recherche input').keypress(function(e) {
     	    if(e.which == 13) {
    -	       
    +
     	       var id_list = $(this).closest('table').attr('id');
    -	       
    +
     	       $('#'+id_list+' .list-search-link').click();
    -	       
    +
     	    }
     	});
    -	
    +
     	var $_GET = {};
    -	
    +
     	document.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function () {
     	    function decode(s) {
     	        return decodeURIComponent(s.split("+").join(" "));
     	    }
    -	
    +
     	    $_GET[decode(arguments[1])] = decode(arguments[2]);
     	});
    -	
    +
     	if(typeof $_GET["get-all-for-export"] != "undefined") {
     		Listview_launch_downloadAs($_GET['mode'],$_GET['url'],$_GET['token'],$_GET['session_name']);
     	}
    -	
    +
     });
    diff --git a/htdocs/core/js/timesheet.js b/htdocs/core/js/timesheet.js
    index aaec6971e2f..3bd93555d76 100644
    --- a/htdocs/core/js/timesheet.js
    +++ b/htdocs/core/js/timesheet.js
    @@ -24,9 +24,9 @@ function regexEvent(objet,evt,type)
         {
               case 'days':
                   var regex= /^[0-9]{1}([.,]{1}[0-9]{1})?$/;
    -   
    +
                   if(regex.test(objet.value) )
    -              { 
    +              {
                     var tmp=objet.value.replace(',','.');
                     if(tmp<=1.5){
                         var tmpint=parseInt(tmp);
    @@ -41,15 +41,20 @@ function regexEvent(objet,evt,type)
                   }else{
                      objet.value= '0';
                 }
    -          break; 
    +          break;
               case 'hours':
                   var regex= /^[0-9]{1,2}:[0-9]{2}$/;
                   var regex2=/^[0-9]{1,2}$/;
    +              var regex3= /^[0-9]{1}([.,]{1}[0-9]{1,2})?$/;
                   if(!regex.test(objet.value))
    -              { 
    +              {
                       if(regex2.test(objet.value))
                         objet.value=objet.value+':00';
    -                  else
    +                  else if(regex3.test(objet.value)) {
    +                    var tmp=parseFloat(objet.value.replace(',','.'));
    +                    var rnd=Math.trunc(tmp);
    +                    objet.value=rnd+':'+ Math.round(60*(tmp-rnd));
    +                  } else
                         objet.value='';
                   }
                   /* alert(jQuery("#"+id).val()); */
    @@ -58,25 +63,25 @@ function regexEvent(objet,evt,type)
                   //var regex= /^[0-9:]{1}$/;
                   //alert(event.charCode);
                   var charCode = (evt.which) ? evt.which : event.keyCode;
    -              
    +
                   if(((charCode >= 48) && (charCode <= 57)) || //num
                         (charCode===46) || (charCode===8)||// comma & periode
                         (charCode === 58) || (charCode==44) )// : & all charcode
                   {
                       // ((charCode>=96) && (charCode<=105)) || //numpad
                 	  return true;
    -         
    +
                   }else
                   {
                       return false;
                   }
    -                
    -              break;    
    +
    +              break;
               default:
                   break;
           }
    -}    
    -  
    +}
    +
     
     function pad(n) {
         return (n < 10) ? ("0" + n) : n;
    @@ -90,7 +95,7 @@ function parseTime(timeStr, dt)
         if (!dt) {
             dt = new Date();
         }
    - 
    +
         var time = timeStr.match(/(\d+)(?::(\d\d))?\s*(p?)/i);
         if (!time) {
             return -1;
    @@ -102,7 +107,7 @@ function parseTime(timeStr, dt)
         else {
             hours += (hours < 12 && time[3]) ? 12 : 0;
         }
    - 
    +
         dt.setHours(hours);
         dt.setMinutes(parseInt(time[2], 10) || 0);
         dt.setSeconds(0, 0);
    @@ -117,10 +122,10 @@ function updateTotal(days,mode)
         {
             var total = new Date(0);
             total.setHours(0);
    -        total.setMinutes(0);   
    +        total.setMinutes(0);
             var nbline = document.getElementById('numberOfLines').value;
             for (var i=-1; i<nbline; i++)
    -        { 
    +        {
                 var id='timespent['+i+']['+days+']';
                 var taskTime= new Date(0);
                 var element=document.getElementById(id);
    @@ -128,7 +133,7 @@ function updateTotal(days,mode)
                 {
                 	/* alert(element.value);*/
                     if (element.value)
    -                {   
    +                {
                     	result=parseTime(element.value,taskTime);
                     }
                     else
    @@ -142,14 +147,14 @@ function updateTotal(days,mode)
                     }
                 }
     
    -            var id='timeadded['+i+']['+days+']';   
    +            var id='timeadded['+i+']['+days+']';
                 var taskTime= new Date(0);
                 var element=document.getElementById(id);
                 if(element)
                 {
                 	/* alert(element.value);*/
                     if (element.value)
    -                {   
    +                {
                     	result=parseTime(element.value,taskTime);
                     }
                     else
    @@ -173,7 +178,7 @@ function updateTotal(days,mode)
             		console.log(this.value)
                 	alert(element.value);*/
                     if (this.value)
    -                {   
    +                {
                     	console.log(this.value+':00')
                     	result=parseTime(this.value+':00',taskTime);
                     }
    @@ -197,7 +202,7 @@ function updateTotal(days,mode)
             		console.log(this.value)
                 	alert(element.value);*/
                     if (this.value)
    -                {   
    +                {
                     	console.log('00:'+this.value)
                     	result=parseTime('00:'+"00".substring(0, 2 - this.value.length) + this.value,taskTime);
                     }
    @@ -212,11 +217,11 @@ function updateTotal(days,mode)
             		console.log(total.getMinutes())
                 }
             });
    -        
    +
             if (total.getHours() || total.getMinutes()) jQuery('.totalDay'+days).addClass("bold");
             else jQuery('.totalDay'+days).removeClass("bold");
         	jQuery('.totalDay'+days).text(pad(total.getHours())+':'+pad(total.getMinutes()));
    -    	
    +
         	var totalhour = 0;
         	var totalmin = 0;
             for (var i=0; i<7; i++)
    @@ -238,14 +243,14 @@ function updateTotal(days,mode)
             var total =0;
             var nbline = document.getElementById('numberOfLines').value;
             for (var i=-1; i<nbline; i++)
    -        { 
    -            var id='timespent['+i+']['+days+']';   
    +        {
    +            var id='timespent['+i+']['+days+']';
                 var taskTime= new Date(0);
                 var element=document.getElementById(id);
                 if(element)
                 {
                     if (element.value)
    -                {   
    +                {
                         total+=parseInt(element.value);
     
                        }
    @@ -255,13 +260,13 @@ function updateTotal(days,mode)
                     }
                 }
     
    -            var id='timeadded['+i+']['+days+']';   
    +            var id='timeadded['+i+']['+days+']';
                 var taskTime= new Date(0);
                 var element=document.getElementById(id);
                 if(element)
                 {
                     if (element.value)
    -                {   
    +                {
                         total+=parseInt(element.value);
     
                        }
    @@ -271,11 +276,9 @@ function updateTotal(days,mode)
                     }
                 }
             }
    -        
    +
             if (total) jQuery('.totalDay'+days).addClass("bold");
             else jQuery('.totalDay'+days).removeClass("bold");
         	jQuery('.totalDay'+days).text(total);
         }
     }
    -
    -   
    \ No newline at end of file
    diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php
    index f4b027840c1..f92fd56a87b 100644
    --- a/htdocs/core/lib/admin.lib.php
    +++ b/htdocs/core/lib/admin.lib.php
    @@ -108,28 +108,37 @@ function versiondolibarrarray()
     
     
     /**
    - *	Launch a sql file. Function used by:
    + *	Launch a sql file. Function is used by:
      *  - Migrate process (dolibarr-xyz-abc.sql)
      *  - Loading sql menus (auguria)
      *  - Running specific Sql by a module init
    + *  - Loading sql file of website import package
      *  Install process however does not use it.
    - *  Note that Sql files must have all comments at start of line.
    + *  Note that Sql files must have all comments at start of line. Also this function take ';' as the char to detect end of sql request
      *
    - *	@param		string	$sqlfile					Full path to sql file
    - * 	@param		int		$silent						1=Do not output anything, 0=Output line for update page
    - * 	@param		int		$entity						Entity targeted for multicompany module
    - *	@param		int		$usesavepoint				1=Run a savepoint before each request and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
    - *	@param		string	$handler					Handler targeted for menu
    - *	@param 		string	$okerror					Family of errors we accept ('default', 'none')
    + *	@param		string	$sqlfile			Full path to sql file
    + * 	@param		int		$silent				1=Do not output anything, 0=Output line for update page
    + * 	@param		int		$entity				Entity targeted for multicompany module
    + *	@param		int		$usesavepoint		1=Run a savepoint before each request and a rollback to savepoint if error (this allow to have some request with errors inside global transactions).
    + *	@param		string	$handler			Handler targeted for menu (replace __HANDLER__ with this value)
    + *	@param 		string	$okerror			Family of errors we accept ('default', 'none')
    + *  @param		int		$linelengthlimit	Limit for length of each line (Use 0 if unknown, may be faster if defined)
    + *  @param		int		$nocommentremoval	Do no try to remove comments (in such a case, we consider that each line is a request, so use also $linelengthlimit=0)
      *  @param		int		$offsetforchartofaccount	Offset to use to load chart of account table to update sql on the fly to add offset to rowid and account_parent value
    - * 	@return		int									<=0 if KO, >0 if OK
    + * 	@return		int							<=0 if KO, >0 if OK
      */
    -function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='', $okerror='default', $offsetforchartofaccount=0)
    +function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0)
     {
         global $db, $conf, $langs, $user;
     
         dol_syslog("Admin.lib::run_sql run sql file ".$sqlfile." silent=".$silent." entity=".$entity." usesavepoint=".$usesavepoint." handler=".$handler." okerror=".$okerror, LOG_DEBUG);
     
    +    if (! is_numeric($linelengthlimit))
    +    {
    +    	dol_syslog("Admin.lib::run_sql param linelengthlimit is not a numeric", LOG_ERR);
    +    	return -1;
    +    }
    +
         $ok=0;
         $error=0;
         $i=0;
    @@ -144,7 +153,9 @@ function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='',
         {
             while (! feof($fp))
             {
    -            $buf = fgets($fp, 32768);
    +        	// Warning fgets with second parameter that is null or 0 hang.
    +        	if ($linelengthlimit > 0) $buf = fgets($fp, $linelengthlimit);
    +        	else $buf = fgets($fp);
     
                 // Test if request must be ran only for particular database or version (if yes, we must remove the -- comment)
                 if (preg_match('/^--\sV(MYSQL|PGSQL)([^\s]*)/i',$buf,$reg))
    @@ -192,13 +203,13 @@ function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='',
                 }
     
                 // Add line buf to buffer if not a comment
    -            if (! preg_match('/^\s*--/',$buf))
    +            if ($nocommentremoval || ! preg_match('/^\s*--/',$buf))
                 {
    -                $buf=preg_replace('/([,;ERLT\)])\s*--.*$/i','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer
    +            	if (empty($nocommentremoval)) $buf=preg_replace('/([,;ERLT\)])\s*--.*$/i','\1',$buf); //remove comment from a line that not start with -- before add it to the buffer
                     $buffer .= trim($buf);
                 }
     
    -            //          print $buf.'<br>';
    +            //print $buf.'<br>';exit;
     
                 if (preg_match('/;/',$buffer))	// If string contains ';', it's end of a request string, we save it in arraysql.
                 {
    @@ -230,7 +241,7 @@ function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='',
                 if (! isset($listofmaxrowid[$table]))
                 {
                     //var_dump($db);
    -                $sqlgetrowid='SELECT MAX(rowid) as max from '.$table;
    +                $sqlgetrowid='SELECT MAX(rowid) as max from '.preg_replace('/^llx_/', MAIN_DB_PREFIX, $table);
                     $resql=$db->query($sqlgetrowid);
                     if ($resql)
                     {
    @@ -247,9 +258,10 @@ function run_sql($sqlfile, $silent=1, $entity='', $usesavepoint=1, $handler='',
                         break;
                     }
                 }
    +            // Replace __+MAX_llx_table__ with +999
                 $from='__+MAX_'.$table.'__';
                 $to='+'.$listofmaxrowid[$table];
    -            $newsql=str_replace($from,$to,$newsql);
    +            $newsql=str_replace($from, $to, $newsql);
                 dol_syslog('Admin.lib::run_sql New Request '.($i+1).' (replacing '.$from.' to '.$to.')', LOG_DEBUG);
     
                 $arraysql[$i]=$newsql;
    @@ -717,6 +729,11 @@ function defaultvalues_prepare_head()
         $head[$h][2] = 'focus';
         $h++;
     
    +    $head[$h][0] = DOL_URL_ROOT."/admin/defaultvalues.php?mode=mandatory";
    +    $head[$h][1] = $langs->trans("DefaultMandatory");
    +    $head[$h][2] = 'mandatory';
    +    $h++;
    +
         /*$head[$h][0] = DOL_URL_ROOT."/admin/translation.php?mode=searchkey";
         $head[$h][1] = $langs->trans("TranslationKeySearch");
         $head[$h][2] = 'searchkey';
    @@ -1214,9 +1231,8 @@ function activateModulesRequiredByCountry($country_code)
     							{
     								activateModule($modName);
     
    -								setEventMessage($objMod->automatic_activation[$country_code],'warnings');
    +								setEventMessages($objMod->automatic_activation[$country_code], null, 'warnings');
     							}
    -
     						}
     						else dol_syslog("Module ".get_class($objMod)." not qualified");
     					}
    diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php
    index a6562af2729..86d3a68fed4 100644
    --- a/htdocs/core/lib/agenda.lib.php
    +++ b/htdocs/core/lib/agenda.lib.php
    @@ -68,7 +68,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh
     
     	print '<div class="fichecenter">';
     
    -	if (! empty($conf->browser->phone)) print '<div class="fichehalfleft">';
    +	if ($conf->browser->layout == 'phone') print '<div class="fichehalfleft">';
     	else print '<table class="nobordernopadding" width="100%"><tr><td class="borderright">';
     
     	print '<table class="nobordernopadding centpercent">';
    @@ -180,10 +180,10 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh
     
     	print '</table>';
     
    -	if (! empty($conf->browser->phone)) print '</div>';
    +	if ($conf->browser->layout == 'phone') print '</div>';
     	else print '</td>';
     
    -	if (! empty($conf->browser->phone)) print '<div class="fichehalfright">';
    +	if ($conf->browser->layout == 'phone') print '<div class="fichehalfright">';
     	else print '<td align="center" valign="middle" class="nowrap">';
     
     	print '<table class="centpercent"><tr><td align="center">';
    @@ -193,7 +193,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh
     	print '</td></tr>';
     	print '</table>';
     
    -	if (! empty($conf->browser->phone)) print '</div>';
    +	if ($conf->browser->layout == 'phone') print '</div>';
     	else print '</td></tr></table>';
     
     	print '</div>';	// Close fichecenter
    diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
    index 1d16ba84858..bb08018b7f6 100644
    --- a/htdocs/core/lib/ajax.lib.php
    +++ b/htdocs/core/lib/ajax.lib.php
    @@ -35,12 +35,12 @@
      *  @param	string	$urloption			More parameters on URL request
      *  @param	int		$minLength			Minimum number of chars to trigger that Ajax search
      *  @param	int		$autoselect			Automatic selection if just one value
    - *  @param	array	$ajaxoptions		Multiple options array
    - *                                          Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done
    - *                                          Ex: array('disabled'=> )
    - *                                          Ex: array('show'=> )
    - *                                          Ex: array('update_textarea'=> )
    - *                                          Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax)
    + *  @param	array   $ajaxoptions		Multiple options array
    + *                                      - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done
    + *                                      - Ex: array('disabled'=> )
    + *                                      - Ex: array('show'=> )
    + *                                      - Ex: array('update_textarea'=> )
    + *                                      - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax)
      *	@return string              		Script
      */
     function ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLength=2, $autoselect=0, $ajaxoptions=array())
    @@ -377,7 +377,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $
     
     	// select2 disabled for smartphones with standard browser.
     	// TODO With select2 v4, it seems ok, except that responsive style on table become crazy when scrolling at end of array)
    -	if (! empty($conf->browser->phone)) return '';
    +	if ($conf->browser->layout == 'phone') return '';
     
     	if (! empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) return '';
     	if (empty($conf->use_javascript_ajax)) return '';
    @@ -622,4 +622,3 @@ function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input=a
     
         return $out;
     }
    -
    diff --git a/htdocs/core/lib/asset.lib.php b/htdocs/core/lib/asset.lib.php
    index 5953c8b9420..b0a4a6b81a9 100644
    --- a/htdocs/core/lib/asset.lib.php
    +++ b/htdocs/core/lib/asset.lib.php
    @@ -16,7 +16,7 @@
      */
     
     /**
    - * \file    core/lib/assets.lib.php
    + * \file    htdocs/core/lib/asset.lib.php
      * \ingroup asset
      * \brief   Library files with common functions for Assets
      */
    @@ -24,9 +24,9 @@
     /**
      * Prepare admin pages header
      *
    - * @return array
    + * @return array head array with tabs
      */
    -function AssetsAdminPrepareHead()
    +function asset_admin_prepare_head()
     {
     	global $langs, $conf;
     
    @@ -65,7 +65,12 @@ function AssetsAdminPrepareHead()
     	return $head;
     }
     
    -function AssetsPrepareHead()
    +/**
    + * Prepare admin pages header
    + *
    + * @return array head array with tabs
    + */
    +function asset_prepare_head()
     {
     	global $langs, $conf;
     
    diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php
    index 5e1e300520c..ded980e3246 100644
    --- a/htdocs/core/lib/bank.lib.php
    +++ b/htdocs/core/lib/bank.lib.php
    @@ -161,7 +161,8 @@ function bank_admin_prepare_head($object)
      * @param   Object	$object		Object related to tabs
      * @return  array				Array of tabs to shoc
      */
    -function various_payment_prepare_head($object) {
    +function various_payment_prepare_head($object)
    +{
     
     	global $db, $langs, $conf;
     
    @@ -214,7 +215,6 @@ function checkSwiftForAccount($account)
         } else {
             return false;
         }
    -
     }
     
     /**
    @@ -356,7 +356,7 @@ function checkES($IentOfi, $InumCta)
         $sum = 0;
     
         for ($i = 0; $i < 11; $i++) {
    -        $sum += $values[$i] * substr($InumCta, $i, 1);
    +        $sum += $values[$i] * (int) substr($InumCta, $i, 1);//int to cast result of substr to a number
         }
     
         $key = 11 - $sum % 11;
    @@ -369,4 +369,3 @@ function checkES($IentOfi, $InumCta)
         $keycontrol .= $key;
         return $keycontrol;
     }
    -
    diff --git a/htdocs/core/lib/barcode.lib.php b/htdocs/core/lib/barcode.lib.php
    index 13956f688aa..efd245209d2 100644
    --- a/htdocs/core/lib/barcode.lib.php
    +++ b/htdocs/core/lib/barcode.lib.php
    @@ -251,7 +251,7 @@ function barcode_encode_genbarcode($code,$encoding)
         $command=escapeshellarg($genbarcode_loc);
         //$paramclear=" \"".str_replace("\"", "\\\"",$code)."\" \"".str_replace("\"", "\\\"",strtoupper($encoding))."\"";
         $paramclear=" ".escapeshellarg($code)." ".escapeshellarg(strtoupper($encoding));
    -    
    +
         $fullcommandclear=$command." ".$paramclear." 2>&1";
         //print $fullcommandclear."<br>\n";exit;
     
    @@ -277,8 +277,8 @@ function barcode_encode_genbarcode($code,$encoding)
         	"error" => ""
         );
         //var_dump($ret);
    -    if (preg_match('/permission denied/i',$ret['bars'])) 
    -    { 
    +    if (preg_match('/permission denied/i',$ret['bars']))
    +    {
         	$ret['error']=$ret['bars']; $ret['bars']='';
         	return $ret;
         }
    diff --git a/htdocs/core/lib/categories.lib.php b/htdocs/core/lib/categories.lib.php
    index 4be484e1aa4..e8a7dfcb0ff 100644
    --- a/htdocs/core/lib/categories.lib.php
    +++ b/htdocs/core/lib/categories.lib.php
    @@ -33,8 +33,8 @@ function categories_prepare_head($object,$type)
     {
     	global $langs, $conf, $user;
     
    -	$langs->load("categories");
    -	$langs->load("products");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array('categories', 'products'));
     
     	$h = 0;
     	$head = array();
    @@ -48,7 +48,7 @@ function categories_prepare_head($object,$type)
     	$head[$h][1] = $langs->trans("Photos");
     	$head[$h][2] = 'photos';
     	$h++;
    -	
    +
     	if (! empty($conf->global->MAIN_MULTILANGS))
     	{
         	$head[$h][0] = DOL_URL_ROOT.'/categories/traduction.php?id='.$object->id.'&amp;type='.$type;
    @@ -56,7 +56,7 @@ function categories_prepare_head($object,$type)
         	$head[$h][2] = 'translation';
         	$h++;
     	}
    -	
    +
         // Show more tabs from modules
         // Entries must be declared in modules descriptor with line
         // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
    @@ -87,7 +87,7 @@ function categoriesadmin_prepare_head()
     	$head[$h][1] = $langs->trans("Setup");
     	$head[$h][2] = 'setup';
     	$h++;
    -	
    +
     	$head[$h][0] = DOL_URL_ROOT.'/categories/admin/categorie_extrafields.php';
     	$head[$h][1] = $langs->trans("ExtraFieldsCategories");
     	$head[$h][2] = 'attributes_categories';
    diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
    index 758c0803a10..fe9d15c8322 100644
    --- a/htdocs/core/lib/company.lib.php
    +++ b/htdocs/core/lib/company.lib.php
    @@ -6,11 +6,11 @@
      * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2013-2014  Juanjo Menent           <jmenent@2byte.es>
      * Copyright (C) 2013       Christophe Battarel     <contact@altairis.fr>
    - * Copyright (C) 2013       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2015       Frederic France         <frederic.france@free.fr>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2015-2018  Frédéric France         <frederic.france@netlogic.fr>
      * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) 2017       Rui Strecht			    <rui.strecht@aliartalentos.com>
    - * Copyright (C) 2018       Ferran Marcet		    <fmarcet@2byte.es>
    + * Copyright (C) 2017       Rui Strecht             <rui.strecht@aliartalentos.com>
    + * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
      *
      * 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
    @@ -154,18 +154,18 @@ function societe_prepare_head(Societe $object)
     		// Tab to accountancy
     		if (! empty($conf->accounting->enabled) && $object->client>0)
     		{
    -			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettrage.php?socid='.$object->id;
    -			$head[$h][1] = $langs->trans("TabAccountingCustomer");
    -			$head[$h][2] = 'accounting';
    +			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_customer.php?socid='.$object->id;
    +			$head[$h][1] = $langs->trans("TabLetteringCustomer");
    +			$head[$h][2] = 'lettering_customer';
     			$h++;
     		}
     
     		// Tab to accountancy
     		if (! empty($conf->accounting->enabled) && $object->fournisseur>0)
     		{
    -			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettrage_supplier.php?socid='.$object->id;
    -			$head[$h][1] = $langs->trans("TabAccountingSupplier");
    -			$head[$h][2] = 'accounting_supplier';
    +			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_supplier.php?socid='.$object->id;
    +			$head[$h][1] = $langs->trans("TabLetteringSupplier");
    +			$head[$h][2] = 'lettering_supplier';
     			$h++;
     		}
     	}
    @@ -634,7 +634,6 @@ function getFormeJuridiqueLabel($code)
             {
                 return $langs->trans("NotDefined");
             }
    -
         }
     }
     
    @@ -1244,12 +1243,12 @@ function show_addresses($conf,$langs,$db,$object,$backtopage='')
     			print "</tr>\n";
     		}
     	}
    -	else
    -	{
    +	//else
    +	//{
     		//print '<tr class="oddeven">';
     		//print '<td>'.$langs->trans("NoAddressYetDefined").'</td>';
     		//print "</tr>\n";
    -	}
    +	//}
     	print "\n</table>\n";
     
     	print "<br>\n";
    @@ -1285,7 +1284,7 @@ function show_actions_todo($conf,$langs,$db,$filterobj,$objcon='',$noprint=0,$ac
      * 		@param	Conf		       $conf		   Object conf
      * 		@param	Translate	       $langs		   Object langs
      * 		@param	DoliDB		       $db			   Object db
    - * 		@param	mixed			   $filterobj	   Object Adherent|Societe|Project|Product|CommandeFournisseur
    + * 		@param	mixed			   $filterobj	   Object Adherent|Societe|Project|Product|CommandeFournisseur|Dolresource
      * 		@param	Contact		       $objcon		   Object contact
      *      @param  int			       $noprint        Return string but does not output it
      *      @param  string		       $actioncode     Filter on actioncode
    @@ -1325,30 +1324,37 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
             $sql.= " c.code as acode, c.libelle as alabel, c.picto as apicto,";
             $sql.= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname";
             if (is_object($filterobj) && get_class($filterobj) == 'Societe')  $sql.= ", sp.lastname, sp.firstname";
    -        if (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname";
    -        if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref";
    -        if (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", o.ref";
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname";
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref";
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", o.ref";
             $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
             $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_action";
             $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id";
             if (is_object($filterobj) && get_class($filterobj) == 'Societe')  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid";
    -        if (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m";
    -        if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o";
    -        if (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", ".MAIN_DB_PREFIX."product as o";
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Dolresource') {
    +        	$sql.= " INNER JOIN ".MAIN_DB_PREFIX."element_resources as er";
    +        	$sql.= " ON er.resource_type = 'dolresource'";
    +        	$sql.= " AND er.element_id = a.id";
    +        	$sql.= " AND er.resource_id = ".$filterobj->id;
    +        }
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m";
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o";
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", ".MAIN_DB_PREFIX."product as o";
    +
             $sql.= " WHERE a.entity IN (".getEntity('agenda').")";
             if (is_object($filterobj) && get_class($filterobj) == 'Societe'  && $filterobj->id) $sql.= " AND a.fk_soc = ".$filterobj->id;
    -        if (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) $sql.= " AND a.fk_project = ".$filterobj->id;
    -        if (is_object($filterobj) && get_class($filterobj) == 'Adherent')
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) $sql.= " AND a.fk_project = ".$filterobj->id;
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent')
             {
                 $sql.= " AND a.fk_element = m.rowid AND a.elementtype = 'member'";
                 if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
             }
    -        if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur')
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur')
             {
             	$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'";
             	if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
             }
    -        if (is_object($filterobj) && get_class($filterobj) == 'Product')
    +        elseif (is_object($filterobj) && get_class($filterobj) == 'Product')
             {
             	$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'product'";
             	if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
    @@ -1365,7 +1371,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
                     else
                     {
                         if ($actioncode == 'AC_OTH') $sql.= " AND c.type != 'systemauto'";
    -                    if ($actioncode == 'AC_OTH_AUTO') $sql.= " AND c.type = 'systemauto'";
    +                    elseif ($actioncode == 'AC_OTH_AUTO') $sql.= " AND c.type = 'systemauto'";
                     }
                 }
                 else
    @@ -1376,7 +1382,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
                 }
             }
             if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
    -        if ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
    +        elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
             if (is_array($filters) && $filters['search_agenda_label']) $sql.= natural_search('a.label', $filters['search_agenda_label']);
             $sql.= $db->order($sortfield, $sortorder);
             dol_syslog("company.lib::show_actions_done", LOG_DEBUG);
    @@ -1399,7 +1405,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
                     }
     
                     //if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
    -                //if ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
    +                //elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
                     $tododone='';
                     if (($obj->percent >= 0 and $obj->percent < 100) || ($obj->percent == -1 && $obj->datep > $now)) $tododone='todo';
     
    @@ -1497,13 +1503,10 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
         {
             $delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60;
     
    -        require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
             require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
    -        require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
    -        require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
    -        require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
    -        require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    -        require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
    +        include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +	    require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
    +	    require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     
             $formactions=new FormActions($db);
     
    @@ -1511,12 +1514,6 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
             $userstatic=new User($db);
             $contactstatic = new Contact($db);
     
    -        // TODO mutualize/uniformize
    -        $propalstatic=new Propal($db);
    -        $orderstatic=new Commande($db);
    -        $supplierorderstatic=new CommandeFournisseur($db);
    -        $facturestatic=new Facture($db);
    -
             $out.='<form name="listactionsfilter" class="listactionsfilter" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
             if ($objcon && get_class($objcon) == 'Contact' && $filterobj && get_class($filterobj) == 'Societe')
             {
    @@ -1604,7 +1601,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
                 $out.='</td>';
     
                 // Author of event
    -            $out.='<td>';
    +            $out.='<td class="tdoverflowmax100">';
                 //$userstatic->id=$histo[$key]['userid'];
                 //$userstatic->login=$histo[$key]['login'];
                 //$out.=$userstatic->getLoginUrl(1);
    @@ -1677,45 +1674,10 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint=
                 //$out.='<td>'.dol_trunc($histo[$key]['note'], 40).'</td>';
     
                 // Objet lie
    -            // TODO mutualize/uniformize
                 $out.='<td>';
    -            //var_dump($histo[$key]['elementtype']);
    -            if (isset($histo[$key]['elementtype']))
    +            if (isset($histo[$key]['elementtype']) && !empty($histo[$key]['fk_element']))
                 {
    -            	if ($histo[$key]['elementtype'] == 'propal' && ! empty($conf->propal->enabled))
    -            	{
    -            		//$propalstatic->ref=$langs->trans("ProposalShort");
    -            		//$propalstatic->id=$histo[$key]['fk_element'];
    -                    if ($propalstatic->fetch($histo[$key]['fk_element'])>0) {
    -                        $propalstatic->type=$histo[$key]['ftype'];
    -                        $out.=$propalstatic->getNomUrl(1);
    -                    } else {
    -                        //$out.= '<span class="opacitymedium">'.$langs->trans("ProposalDeleted").'</span>';
    -                    }
    -             	}
    -            	elseif (($histo[$key]['elementtype'] == 'order' || $histo[$key]['elementtype'] == 'commande') && ! empty($conf->commande->enabled))
    -            	{
    -            		//$orderstatic->ref=$langs->trans("Order");
    -            		//$orderstatic->id=$histo[$key]['fk_element'];
    -                    if ($orderstatic->fetch($histo[$key]['fk_element'])>0) {
    -                        $orderstatic->type=$histo[$key]['ftype'];
    -                        $out.=$orderstatic->getNomUrl(1);
    -                    } else {
    -                    	//$out.= '<span class="opacitymedium">'.$langs->trans("OrderDeleted").'<span>';
    -                    }
    -             	}
    -            	elseif (($histo[$key]['elementtype'] == 'invoice' || $histo[$key]['elementtype'] == 'facture') && ! empty($conf->facture->enabled))
    -            	{
    -            		//$facturestatic->ref=$langs->trans("Invoice");
    -            		//$facturestatic->id=$histo[$key]['fk_element'];
    -                    if ($facturestatic->fetch($histo[$key]['fk_element'])>0) {
    -                        $facturestatic->type=$histo[$key]['ftype'];
    -                        $out.=$facturestatic->getNomUrl(1,'compta');
    -                    } else {
    -                    	//$out.= '<span class="opacitymedium">'.$langs->trans("InvoiceDeleted").'</span>';
    -                    }
    -            	}
    -            	else $out.='&nbsp;';
    +            	$out.=dolGetElementUrl($histo[$key]['fk_element'],$histo[$key]['elementtype'],1);
                 }
                 else $out.='&nbsp;';
                 $out.='</td>';
    diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
    index 8985a4e7621..84048ac9c66 100644
    --- a/htdocs/core/lib/date.lib.php
    +++ b/htdocs/core/lib/date.lib.php
    @@ -162,15 +162,15 @@ function convertTime2Seconds($iHours=0,$iMinutes=0,$iSeconds=0)
      *
      *    	@param      int		$iSecond		Number of seconds
      *    	@param      string	$format		    Output format ('all': total delay days hour:min like "2 days 12:30",
    - *                                                         'allwithouthour': total delay days without hour part like "2 days",
    - *                                                         'allhourmin': total delay with format hours:min like "60:30",
    - *                                                         'allhour': total delay hours without min/sec like "60:30",
    - *                                                         'fullhour': total delay hour decimal like "60.5" for 60:30,
    - *                                                         'hour': only hours part "12",
    - *                                                         'min': only minutes part "30",
    - *                                                         'sec': only seconds part,
    - *                                                         'month': only month part,
    - *                                                         'year': only year part);
    + *                                          - 'allwithouthour': total delay days without hour part like "2 days",
    + *                                          - 'allhourmin': total delay with format hours:min like "60:30",
    + *                                          - 'allhour': total delay hours without min/sec like "60:30",
    + *                                          - 'fullhour': total delay hour decimal like "60.5" for 60:30,
    + *                                          - 'hour': only hours part "12",
    + *                                          - 'min': only minutes part "30",
    + *                                          - 'sec': only seconds part,
    + *                                          - 'month': only month part,
    + *                                          - 'year': only year part);
      *      @param      int		$lengthOfDay    Length of day (default 86400 seconds for 1 day, 28800 for 8 hour)
      *      @param      int		$lengthOfWeek   Length of week (default 7)
      *    	@return     string		 		 	Formated text of duration
    @@ -439,7 +439,6 @@ function dol_get_next_week($day, $week, $month, $year)
     	$tmparray=dol_getdate($time,true);
     
     	return array('year' => $tmparray['year'], 'month' => $tmparray['mon'], 'day' => $tmparray['mday']);
    -
     }
     
     /**	Return GMT time for first day of a month or year
    @@ -586,6 +585,7 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     	{
     		$ferie=false;
     		$countryfound=0;
    +		$includesaturdayandsunday=1;
     
     		$jour  = date("d", $timestampStart);
     		$mois  = date("m", $timestampStart);
    @@ -672,12 +672,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			$mois_pentecote = date("m", $date_pentecote);
     			if($jour_pentecote == $jour && $mois_pentecote == $mois) $ferie=true;
     			// "Pentecote"
    -
    -			// Calul des samedis et dimanches
    -			$jour_julien = unixtojd($timestampStart);
    -			$jour_semaine = jddayofweek($jour_julien, 0);
    -			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			// Samedi (6) et dimanche (0)
     		}
     
     		// Pentecoste and Ascensione in Italy go to the sunday after: isn't holiday.
    @@ -704,12 +698,18 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			$mois_paques = date("m", $date_paques);
     			if($jour_paques == $jour && $mois_paques == $mois) $ferie=true;
     			// Paques
    +		}
     
    -			// Calul des samedis et dimanches
    -			$jour_julien = unixtojd($timestampStart);
    -			$jour_semaine = jddayofweek($jour_julien, 0);
    -			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			//Samedi (6) et dimanche (0)
    +		if ($countrycode == 'IN')
    +		{
    +			$countryfound=1;
    +
    +			if($jour == 1 && $mois == 1) $ferie=true; // New Year's Day
    +			if($jour == 26 && $mois == 1) $ferie=true; // Republic Day
    +			if($jour == 1 && $mois == 5) $ferie=true; // May Day
    +			if($jour == 15 && $mois == 8) $ferie=true; // Independence Day
    +			if($jour == 2 && $mois == 10) $ferie=true; // Gandhi Jayanti
    +			if($jour == 25 && $mois == 12) $ferie=true; // Christmas
     		}
     
     		if ($countrycode == 'ES')
    @@ -747,12 +747,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			$mois_viernes = date("m", $date_viernes);
     			if($jour_viernes == $jour && $mois_viernes == $mois) $ferie=true;
     			//Viernes Santo
    -
    -			// Calul des samedis et dimanches
    -			$jour_julien = unixtojd($timestampStart);
    -			$jour_semaine = jddayofweek($jour_julien, 0);
    -			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			//Samedi (6) et dimanche (0)
     		}
     
     		if ($countrycode == 'AT')
    @@ -834,22 +828,15 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     		    $mois_fronleichnam = date("m", $date_fronleichnam);
     		    if($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) $ferie=true;
     		    // Fronleichnam
    -
    -		    // Calul des samedis et dimanches
    -		    $jour_julien = unixtojd($timestampStart);
    -		    $jour_semaine = jddayofweek($jour_julien, 0);
    -		    if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -		    //Samedi (6) et dimanche (0)
     		}
     
    -		// Cas pays non defini
    -		if (! $countryfound)
    +		// If we have to include saturday and sunday
    +		if ($includesaturdayandsunday)
     		{
    -			// Calul des samedis et dimanches
     			$jour_julien = unixtojd($timestampStart);
     			$jour_semaine = jddayofweek($jour_julien, 0);
     			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			//Samedi (6) et dimanche (0)
    +			//Saturday (6) and Sunday (0)
     		}
     
     		// On incremente compteur
    @@ -946,44 +933,43 @@ function num_open_day($timestampStart, $timestampEnd, $inhour=0, $lastday=0, $ha
      *  This replace old function monthArrayOrSelected.
      *
      *	@param	Translate	$outputlangs	Object langs
    - *  @param	int			$short			1=Return short label
    + *  @param	int			$short			0=Return long label, 1=Return short label
      *	@return array						Month string or array if selected < 0
      */
     function monthArray($outputlangs,$short=0)
     {
     	$montharray = array (
    -	    1  => $outputlangs->trans("January"),
    -	    2  => $outputlangs->trans("February"),
    -	    3  => $outputlangs->trans("March"),
    -	    4  => $outputlangs->trans("April"),
    -	    5  => $outputlangs->trans("May"),
    -	    6  => $outputlangs->trans("June"),
    -	    7  => $outputlangs->trans("July"),
    -	    8  => $outputlangs->trans("August"),
    -	    9  => $outputlangs->trans("September"),
    -	    10 => $outputlangs->trans("October"),
    -	    11 => $outputlangs->trans("November"),
    -	    12 => $outputlangs->trans("December")
    +	    1  => $outputlangs->trans("Month01"),
    +	    2  => $outputlangs->trans("Month02"),
    +	    3  => $outputlangs->trans("Month03"),
    +	    4  => $outputlangs->trans("Month04"),
    +	    5  => $outputlangs->trans("Month05"),
    +	    6  => $outputlangs->trans("Month06"),
    +	    7  => $outputlangs->trans("Month07"),
    +	    8  => $outputlangs->trans("Month08"),
    +	    9  => $outputlangs->trans("Month09"),
    +	    10 => $outputlangs->trans("Month10"),
    +	    11 => $outputlangs->trans("Month11"),
    +	    12 => $outputlangs->trans("Month12")
         );
     
     	if (! empty($short))
     	{
     		$montharray = array (
    -		    1  => $outputlangs->trans("JanuaryMin"),
    -		    2  => $outputlangs->trans("FebruaryMin"),
    -		    3  => $outputlangs->trans("MarchMin"),
    -		    4  => $outputlangs->trans("AprilMin"),
    -		    5  => $outputlangs->trans("MayMin"),
    -		    6  => $outputlangs->trans("JuneMin"),
    -		    7  => $outputlangs->trans("JulyMin"),
    -		    8  => $outputlangs->trans("AugustMin"),
    -		    9  => $outputlangs->trans("SeptemberMin"),
    -		    10 => $outputlangs->trans("OctoberMin"),
    -		    11 => $outputlangs->trans("NovemberMin"),
    -		    12 => $outputlangs->trans("DecemberMin")
    +		    1  => $outputlangs->trans("MonthShort01"),
    +		    2  => $outputlangs->trans("MonthShort02"),
    +		    3  => $outputlangs->trans("MonthShort03"),
    +		    4  => $outputlangs->trans("MonthShort04"),
    +		    5  => $outputlangs->trans("MonthShort05"),
    +		    6  => $outputlangs->trans("MonthShort06"),
    +		    7  => $outputlangs->trans("MonthShort07"),
    +		    8  => $outputlangs->trans("MonthShort08"),
    +		    9  => $outputlangs->trans("MonthShort09"),
    +		    10 => $outputlangs->trans("MonthShort10"),
    +		    11 => $outputlangs->trans("MonthShort11"),
    +		    12 => $outputlangs->trans("MonthShort12")
     			);
     	}
     
     	return $montharray;
     }
    -
    diff --git a/htdocs/core/lib/emailing.lib.php b/htdocs/core/lib/emailing.lib.php
    index 00a06ca3f09..06ceb2c96b0 100644
    --- a/htdocs/core/lib/emailing.lib.php
    +++ b/htdocs/core/lib/emailing.lib.php
    @@ -46,10 +46,9 @@ function emailing_prepare_head(Mailing $object)
     		if ($object->nbemail > 0) $head[$h][1].= ' <span class="badge">'.$object->nbemail.'</span>';
         	$head[$h][2] = 'targets';
         	$h++;
    -
     	}
    -	
    -	if (! empty($conf->global->EMAILING_USE_ADVANCED_SELECTOR)) 
    +
    +	if (! empty($conf->global->EMAILING_USE_ADVANCED_SELECTOR))
     	{
     		$head[$h][0] = DOL_URL_ROOT."/comm/mailing/advtargetemailing.php?id=".$object->id;
     		$head[$h][1] = $langs->trans("MailAdvTargetRecipients");
    diff --git a/htdocs/core/lib/expensereport.lib.php b/htdocs/core/lib/expensereport.lib.php
    index 1efdc73f247..779e6c9e174 100644
    --- a/htdocs/core/lib/expensereport.lib.php
    +++ b/htdocs/core/lib/expensereport.lib.php
    @@ -67,7 +67,7 @@ function expensereport_prepare_head($object)
     	    $head[$h][2] = 'note';
     	    $h++;
     	}
    -	
    +
     	$head[$h][0] = DOL_URL_ROOT . '/expensereport/info.php?id=' . $object->id;
     	$head[$h][1] = $langs->trans("Info");
     	$head[$h][2] = 'info';
    @@ -81,11 +81,12 @@ function expensereport_prepare_head($object)
     /**
      * Returns an array with the tabs for the "Expense report payment" section
      * It loads tabs from modules looking for the entity payment
    - * 
    + *
      * @param	Paiement	$object		Current payment object
      * @return	array					Tabs for the payment section
      */
    -function payment_expensereport_prepare_head(PaymentExpenseReport $object) {
    +function payment_expensereport_prepare_head(PaymentExpenseReport $object)
    +{
     
     	global $langs, $conf;
     
    @@ -139,7 +140,7 @@ function expensereport_admin_prepare_head()
     		$head[$h][2] = 'expenseik';
     		$h++;
     	}
    -	
    +
     	if (!empty($conf->global->MAIN_USE_EXPENSE_RULE))
     	{
     		$head[$h][0] = DOL_URL_ROOT."/admin/expensereport_rules.php";
    @@ -147,7 +148,7 @@ function expensereport_admin_prepare_head()
     		$head[$h][2] = 'expenserules';
     		$h++;
     	}
    -	
    +
     	// Show more tabs from modules
     	// Entries must be declared in modules descriptor with line
     	// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
    @@ -168,5 +169,5 @@ function expensereport_admin_prepare_head()
     
     	complete_head_from_modules($conf,$langs,null,$head,$h,'expensereport_admin','remove');
     
    -	return $head;
    +    return $head;
     }
    diff --git a/htdocs/core/lib/fichinter.lib.php b/htdocs/core/lib/fichinter.lib.php
    index 8507a85292a..20e257eee2f 100644
    --- a/htdocs/core/lib/fichinter.lib.php
    +++ b/htdocs/core/lib/fichinter.lib.php
    @@ -2,8 +2,9 @@
     /* Copyright (C) 2006-2007	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2007		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
      * Copyright (C) 2012		Regis Houssin			<regis.houssin@capnetworks.com>
    - * Copyright (C) 2016		   Gilles Poirier 		   <glgpoirier@gmail.com>
    - 
    + * Copyright (C) 2016		Gilles Poirier 		   <glgpoirier@gmail.com>
    + * Copyright (C) 2018		charlene Benke 		   <charlie@patas-monkey.com>
    +
      *
      * 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
    @@ -75,11 +76,10 @@ function fichinter_prepare_head($object)
     				foreach($resources as $resource_obj)
     				{
     					$linked_resources = $object->getElementResources('fichinter',$object->id,$resource_obj);
    -					
     				}
     			}
     		}
    -				
    +
        		$head[$h][0] = DOL_URL_ROOT.'/resource/element_resource.php?element=fichinter&element_id='.$object->id;
     		$head[$h][1] = $langs->trans("Resources");
     		if ($nbResource > 0) $head[$h][1].= ' <span class="badge">'.$nbResource.'</span>';
    @@ -162,4 +162,28 @@ function fichinter_admin_prepare_head()
     		return $head;
     }
     
    +/**
    + * Prepare array with list of tabs
    + *
    + * @param   Object  $object     Object related to tabs
    + * @return  array               Array of tabs to show
    + */
    +function fichinter_rec_prepare_head($object)
    +{
    +	global $langs, $conf; //, $user;
     
    +	$h = 0;
    +	$head = array();
    +
    +	$head[$h][0] = DOL_URL_ROOT.'/fichinter/card-rec.php?id='.$object->id;
    +	$head[$h][1] = $langs->trans("CardFichinter");
    +	$head[$h][2] = 'card';
    +	$h++;
    +
    +	complete_head_from_modules($conf, $langs, $object, $head, $h, 'intervention-rec');
    +
    +	complete_head_from_modules($conf, $langs, $object, $head, $h,'intervention-rec','remove');
    +
    +
    +	return $head;
    +}
    diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
    index 210626f461c..1a114c62a01 100644
    --- a/htdocs/core/lib/files.lib.php
    +++ b/htdocs/core/lib/files.lib.php
    @@ -574,7 +574,7 @@ function dol_filemtime($pathoffile)
      * @param	array	$arrayreplacement	Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...)
      * @param	string	$destfile			Destination file (can't be a directory). If empty, will be same than source file.
      * @param	int		$newmask			Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666'
    - * @param	int		$indexdatabase		Index new file into database.
    + * @param	int		$indexdatabase		1=index new file into database.
      * @return	int							<0 if error, 0 if nothing done (dest file already exists), >0 if OK
      * @see		dol_copy dolReplaceRegExInFile
      */
    @@ -611,7 +611,7 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0,
     	dol_delete_file($tmpdestfile);
     
     	// Create $newpathoftmpdestfile from $newpathofsrcfile
    -	$content=file_get_contents($newpathofsrcfile, 'r');
    +	$content = file_get_contents($newpathofsrcfile, 'r');
     
     	$content = make_substitutions($content, $arrayreplacement, null);
     
    @@ -651,7 +651,6 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0,
     function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0)
     {
     	// TODO
    -
     }
     
     /**
    @@ -782,7 +781,6 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep
     					$result=$tmpresult;
     				}
     				if ($result < 0) break;
    -
     			}
     		}
     		closedir($dir_handle);
    @@ -1134,16 +1132,17 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable
      *  @param	int		$nohook			Disable all hooks
      *  @param	object	$object			Current object in use
      *  @param	boolean	$allowdotdot	Allow to delete file path with .. inside. Never use this, it is reserved for migration purpose.
    + *  @param	int		$indexdatabase	Try to remove also index entries.
      *  @return boolean         		True if no error (file is deleted or if glob is used and there's nothing to delete), False if error
      *  @see dol_delete_dir
      */
    -function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=null,$allowdotdot=false)
    +function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1)
     {
     	global $db, $conf, $user, $langs;
     	global $hookmanager;
     
    -	$langs->load("other");
    -	$langs->load("errors");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array('other', 'errors'));
     
     	dol_syslog("dol_delete_file file=".$file." disableglob=".$disableglob." nophperrors=".$nophperrors." nohook=".$nohook);
     
    @@ -1201,7 +1200,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n
     						{
     							$rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete);
     
    -							if (is_object($db))		// $db may not be defined when lib is in a context with define('NOREQUIREDB',1)
    +							if (is_object($db) && $indexdatabase)		// $db may not be defined when lib is in a context with define('NOREQUIREDB',1)
     							{
     								dol_syslog("Try to remove also entries in database for full relative path = ".$rel_filetodelete, LOG_DEBUG);
     								include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
    @@ -1269,7 +1268,7 @@ function dol_delete_dir($dir,$nophperrors=0)
      *  @param  int		$nophperrors    Disable all PHP output errors
      *  @param	int		$onlysub		Delete only files and subdir, not main directory
      *  @param  int		$countdeleted   Counter to count nb of elements found really deleted
    - *  @return int             		Number of files and directory we try to remove. NB really removed is returned into $countdeleted.
    + *  @return int             		Number of files and directory we try to remove. NB really removed is returned into var by reference $countdeleted.
      */
     function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
     {
    @@ -1509,7 +1508,7 @@ function dol_init_file_process($pathtoscan='', $trackid='')
      *
      * @param	string	$upload_dir				Directory where to store uploaded file (note: used to forge $destpath = $upload_dir + filename)
      * @param	int		$allowoverwrite			1=Allow overwrite existing file
    - * @param	int		$donotupdatesession		1=Do no edit _SESSION variable but update database index. 0=Update _SESSION and not database index.
    + * @param	int		$donotupdatesession		1=Do no edit _SESSION variable but update database index. 0=Update _SESSION and not database index. -1=Do not update SESSION neither db.
      * @param	string	$varfiles				_FILES var name
      * @param	string	$savingdocmask			Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__'
      * @param	string	$link					Link to add (to add a link instead of a file)
    @@ -1591,7 +1590,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio
     					}
     
     					// Update table of files
    -					if ($donotupdatesession)
    +					if ($donotupdatesession == 1)
     					{
     						$result = addFileIntoDatabaseIndex($upload_dir, basename($destfile), $TFile['name'][$i], 'uploaded', 0);
     						if ($result < 0)
    @@ -1656,7 +1655,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio
      * All information used are in db, conf, langs, user and _FILES.
      *
      * @param	int		$filenb					File nb to delete
    - * @param	int		$donotupdatesession		1=Do not edit _SESSION variable
    + * @param	int		$donotupdatesession		-1 or 1 = Do not update _SESSION variable
      * @param   int		$donotdeletefile        1=Do not delete physically file
      * @param   string  $trackid                Track id (used to prefix name of session vars to avoid conflict)
      * @return	void
    @@ -2162,10 +2161,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
     		$original_file=$dirins.'/'.$original_file;
     	}
     	// Wrapping for some images
    -	elseif (($modulepart == 'mycompany' || $modulepart == 'companylogo') && !empty($conf->mycompany->dir_output))
    +	elseif ($modulepart == 'mycompany' && !empty($conf->mycompany->dir_output))
     	{
     		$accessallowed=1;
    -		$original_file=$conf->mycompany->dir_output.'/logos/'.$original_file;
    +		$original_file=$conf->mycompany->dir_output.'/'.$original_file;
     	}
     	// Wrapping for users photos
     	elseif ($modulepart == 'userphoto' && !empty($conf->user->dir_output))
    diff --git a/htdocs/core/lib/format_cards.lib.php b/htdocs/core/lib/format_cards.lib.php
    index 7e89946d471..ecfce2108dd 100644
    --- a/htdocs/core/lib/format_cards.lib.php
    +++ b/htdocs/core/lib/format_cards.lib.php
    @@ -36,7 +36,7 @@ $sql = "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, t
     $resql = $db->query($sql);
     if ($resql)
     {
    -    while ($row = $db->fetch_array($resql)) 
    +    while ($row = $db->fetch_array($resql))
         {
             $_Avery_Labels[$row['code']]['name']=$row['name'];
             $_Avery_Labels[$row['code']]['paper-size']=$row['paper_size'];
    diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
    index a7296ddd5df..d15d07e4c6e 100644
    --- a/htdocs/core/lib/functions.lib.php
    +++ b/htdocs/core/lib/functions.lib.php
    @@ -254,19 +254,19 @@ function GETPOSTISSET($paramname)
      *  Use the property $user->default_values[path]['creatform'] and/or $user->default_values[path]['filters'] and/or $user->default_values[path]['sortorder']
      *  Note: The property $user->default_values is loaded by main.php when loading the user.
      *
    - *  @param	string	$paramname   Name of parameter to found
    - *  @param	string	$check	     Type of check
    - *                                  ''=no check (deprecated)
    - *                                  'none'=no check (only for param that should have very rich content)
    - *                                  'int'=check it's numeric (integer or float)
    - *                                  'intcomma'=check it's integer+comma ('1,2,3,4...')
    - *                                  'alpha'=check it's text and sign
    - *                                  'aZ'=check it's a-z only
    - *                                  'aZ09'=check it's simple alpha string (recommended for keys)
    - *                                  'array'=check it's array
    - *                                  'san_alpha'=Use filter_var with FILTER_SANITIZE_STRING (do not use this for free text string)
    - *                                  'nohtml', 'alphanohtml'=check there is no html content
    - *                                  'custom'= custom filter specify $filter and $options)
    + *  @param  string  $paramname   Name of parameter to found
    + *  @param  string  $check	     Type of check
    + *                               ''=no check (deprecated)
    + *                               'none'=no check (only for param that should have very rich content)
    + *                               'int'=check it's numeric (integer or float)
    + *                               'intcomma'=check it's integer+comma ('1,2,3,4...')
    + *                               'alpha'=check it's text and sign
    + *                               'aZ'=check it's a-z only
    + *                               'aZ09'=check it's simple alpha string (recommended for keys)
    + *                               'array'=check it's array
    + *                               'san_alpha'=Use filter_var with FILTER_SANITIZE_STRING (do not use this for free text string)
    + *                               'nohtml', 'alphanohtml'=check there is no html content
    + *                               'custom'= custom filter specify $filter and $options)
      *  @param	int		$method	     Type of method (0 = get then post, 1 = only get, 2 = only post, 3 = post then get, 4 = post then get then cookie)
      *  @param  int     $filter      Filter to apply when $check is set to 'custom'. (See http://php.net/manual/en/filter.filters.php for détails)
      *  @param  mixed   $options     Options to pass to filter_var when $check is set to 'custom'
    @@ -431,7 +431,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=null, $options=nu
     						}
     						elseif (isset($user->default_values[$relativepathstring]['filters']))
     						{
    -							foreach($user->default_values[$relativepathstring]['filters'] as $defkey => $defval)
    +							foreach($user->default_values[$relativepathstring]['filters'] as $defkey => $defval)	// $defkey is a querystring like 'a=b&c=d', $defval is key of user
     							{
     								$qualified = 0;
     								if ($defkey != '_noquery_')
    @@ -587,7 +587,6 @@ function GETPOST($paramname, $check='none', $method=0, $filter=null, $options=nu
     	// Save data into session if key start with 'search_' or is 'smonth', 'syear', 'month', 'year'
     	if (empty($method) || $method == 3 || $method == 4)
     	{
    -		//if (preg_match('/^search_/', $paramname) || in_array($paramname, array('sortorder', 'sortfield", 'smonth', 'syear', 'month', 'year')))
     		if (preg_match('/^search_/', $paramname) || in_array($paramname, array('sortorder','sortfield')))
     		{
     			//var_dump($paramname.' - '.$out.' '.$user->default_values[$relativepathstring]['filters'][$paramname]);
    @@ -596,8 +595,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=null, $options=nu
     			// - posted value not empty, or
     			// - if posted value is empty and a default value exists that is not empty (it means we did a filter to an empty value when default was not).
     
    -			//if (! empty($out) || ! empty($user->default_values[$relativepathstring]['filters'][$paramname]))
    -			if ($out != '')		// $out = '0' like 'abc' is a search criteria to keep
    +			if ($out != '')		// $out = '0' or 'abc', it is a search criteria to keep
     			{
     				$user->lastsearch_values_tmp[$relativepathstring][$paramname]=$out;
     			}
    @@ -608,19 +606,19 @@ function GETPOST($paramname, $check='none', $method=0, $filter=null, $options=nu
     }
     
     
    -/**
    - *  Return a prefix to use for this Dolibarr instance, for session/cookie names or email id.
    - *  This prefix is valid in a web context only and is unique for instance and avoid conflict
    - *  between multi-instances, even when having two instances with one root dir or two instances
    - *  in virtual servers.
    - *
    - *  @param  string  $mode       			'' (prefix for session name) or 'email' (prefix for email id)
    - *  @return	string      					A calculated prefix
    - */
     if (! function_exists('dol_getprefix'))
     {
    -	function dol_getprefix($mode='')
    -	{
    +    /**
    +     *  Return a prefix to use for this Dolibarr instance, for session/cookie names or email id.
    +     *  This prefix is valid in a web context only and is unique for instance and avoid conflict
    +     *  between multi-instances, even when having two instances with one root dir or two instances
    +     *  in virtual servers.
    +     *
    +     *  @param  string  $mode                   '' (prefix for session name) or 'email' (prefix for email id)
    +     *  @return	string                          A calculated prefix
    +     */
    +    function dol_getprefix($mode='')
    +    {
     		global $conf;
     
     		// If MAIL_PREFIX_FOR_EMAIL_ID is set and prefix is for email
    @@ -1225,7 +1223,6 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi
     					$outmore.='<a class="tabimage'.($morecss?' '.$morecss:'').'" href="'.$links[$i][0].'">'.$links[$i][1].'</a>'."\n";
     				else
     					$outmore.='<span class="tabspan">'.$links[$i][1].'</span>'."\n";
    -
     			}
     			else if (! empty($links[$i][1]))
     			{
    @@ -1354,7 +1351,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r
     		$width=80; $cssclass='photoref';
     		$showimage=$object->is_photo_available($conf->product->multidir_output[$entity]);
     		$maxvisiblephotos=(isset($conf->global->PRODUCT_MAX_VISIBLE_PHOTO)?$conf->global->PRODUCT_MAX_VISIBLE_PHOTO:5);
    -		if ($conf->browser->phone) $maxvisiblephotos=1;
    +		if ($conf->browser->layout == 'phone') $maxvisiblephotos=1;
     		if ($showimage) $morehtmlleft.='<div class="floatleft inline-block valignmiddle divphotoref">'.$object->show_photos('product', $conf->product->multidir_output[$entity],'small',$maxvisiblephotos,0,0,0,$width,0).'</div>';
     		else
     		{
    @@ -1373,7 +1370,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r
     		$width=80; $cssclass='photoref';
     		$showimage=$object->is_photo_available($conf->ticket->multidir_output[$entity].'/'.$object->track_id);
     		$maxvisiblephotos=(isset($conf->global->TICKETSUP_MAX_VISIBLE_PHOTO)?$conf->global->TICKETSUP_MAX_VISIBLE_PHOTO:2);
    -		if ($conf->browser->phone) $maxvisiblephotos=1;
    +		if ($conf->browser->layout == 'phone') $maxvisiblephotos=1;
     		if ($showimage) $morehtmlleft.='<div class="floatleft inline-block valignmiddle divphotoref">'.$object->show_photos('ticket', $conf->ticket->multidir_output[$entity],'small',$maxvisiblephotos,0,0,0,$width,0).'</div>';
     		else
     		{
    @@ -1595,6 +1592,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r
      * @param	string	$langkey		Translation key
      * @param 	string	$fieldkey		Key of the html select field the text refers to
      * @param	int		$fieldrequired	1=Field is mandatory
    + * @return string
      * @deprecated Form::editfieldkey
      */
     function fieldLabel($langkey, $fieldkey, $fieldrequired=0)
    @@ -2191,50 +2189,52 @@ function dol_print_email($email,$cid=0,$socid=0,$addlink=0,$max=64,$showinvalid=
     }
     
     /**
    - * Show Skype link
    + * Show social network link
      *
    - * @param	string		$skype			Skype to show (only skype, without 'Name of recipient' before)
    + * @param	string		$value			Skype to show (only skype, without 'Name of recipient' before)
      * @param	int 		$cid 			Id of contact if known
      * @param	int 		$socid 			Id of third party if known
    - * @param	int 		$addlink		0=no link to create action
    - * @param	int			$max			Max number of characters to show
    + * @param	string 		$type			'skype','facebook',...
      * @return	string						HTML Link
      */
    -function dol_print_skype($skype,$cid=0,$socid=0,$addlink=0,$max=64)
    +function dol_print_socialnetworks($value,$cid,$socid,$type)
     {
     	global $conf,$user,$langs;
     
    -	$newskype=$skype;
    +	$newskype=$value;
     
    -	if (empty($skype)) return '&nbsp;';
    +	if (empty($value)) return '&nbsp;';
     
    -	if (! empty($addlink))
    +	if (! empty($type))
     	{
    -		$newskype =img_picto($langs->trans("Skype"), 'object_skype.png');
    -		$newskype.= '&nbsp;';
    -		$newskype.=dol_trunc($skype,$max);
    -		$newskype.= '&nbsp;';
    -		$newskype.='<a href="skype:';
    -		$newskype.=dol_trunc($skype,$max);
    -		$newskype.='?call" alt="'.$langs->trans("Call").'&nbsp;'.$skype.'" title="'.$langs->trans("Call").'&nbsp;'.$skype.'">';
    -		$newskype.='<img src="'.DOL_URL_ROOT.'/theme/common/skype_callbutton.png" border="0">';
    -		$newskype.='</a>&nbsp;&nbsp;&nbsp;<a href="skype:';
    -		$newskype.=dol_trunc($skype,$max);
    -		$newskype.='?chat" alt="'.$langs->trans("Chat").'&nbsp;'.$skype.'" title="'.$langs->trans("Chat").'&nbsp;'.$skype.'">';
    -		$newskype.='<img src="'.DOL_URL_ROOT.'/theme/common/skype_chatbutton.png" border="0">';
    -		$newskype.='</a>';
    -
    -		if (($cid || $socid) && ! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create)
    +		$newskype ='<div class="divsocialnetwork inline-block valignmiddle">';
    +		$newskype.=img_picto($langs->trans(strtoupper($type)), $type.'.png', '', false, 0, 0, '', 'paddingright');
    +		$newskype.=$value;
    +		if ($type == 'skype')
     		{
    -			$type='AC_SKYPE'; $link='';
    -			if (! empty($conf->global->AGENDA_ADDACTIONFORSKYPE)) $link='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;backtopage=1&amp;actioncode='.$type.'&amp;contactid='.$cid.'&amp;socid='.$socid.'">'.img_object($langs->trans("AddAction"),"calendar").'</a>';
    -			$newskype='<div class="divskype nowrap">'.$newskype.($link?' '.$link:'').'</div>';
    +			$newskype.= '&nbsp;';
    +			$newskype.='<a href="skype:';
    +			$newskype.=$value;
    +			$newskype.='?call" alt="'.$langs->trans("Call").'&nbsp;'.$value.'" title="'.$langs->trans("Call").'&nbsp;'.$value.'">';
    +			$newskype.='<img src="'.DOL_URL_ROOT.'/theme/common/skype_callbutton.png" border="0">';
    +			$newskype.='</a><a href="skype:';
    +			$newskype.=$value;
    +			$newskype.='?chat" alt="'.$langs->trans("Chat").'&nbsp;'.$value.'" title="'.$langs->trans("Chat").'&nbsp;'.$value.'">';
    +			$newskype.='<img class="paddingleft" src="'.DOL_URL_ROOT.'/theme/common/skype_chatbutton.png" border="0">';
    +			$newskype.='</a>';
     		}
    +		if (($cid || $socid) && ! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create && $type=='skype')
    +		{
    +			$addlink='AC_SKYPE'; $link='';
    +			if (! empty($conf->global->AGENDA_ADDACTIONFORSKYPE)) $link='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;backtopage=1&amp;actioncode='.$addlink.'&amp;contactid='.$cid.'&amp;socid='.$socid.'">'.img_object($langs->trans("AddAction"),"calendar").'</a>';
    +			$newskype.=($link?' '.$link:'');
    +		}
    +		$newskype.='</div>';
     	}
     	else
     	{
     		$langs->load("errors");
    -		$newskype.=img_warning($langs->trans("ErrorBadSkype",$skype));
    +		$newskype.=img_warning($langs->trans("ErrorBadSocialNetworkValue",$value));
     	}
     	return $newskype;
     }
    @@ -2549,7 +2549,7 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep
     	}
     	if (! empty($addlink))	// Link on phone number (+ link to add action if conf->global->AGENDA_ADDACTIONFORPHONE set)
     	{
    -		if (! empty($conf->browser->phone) || (! empty($conf->clicktodial->enabled) && ! empty($conf->global->CLICKTODIAL_USE_TEL_LINK_ON_PHONE_NUMBERS)))	// If phone or option for, we use link of phone
    +		if ($conf->browser->layout == 'phone' || (! empty($conf->clicktodial->enabled) && ! empty($conf->global->CLICKTODIAL_USE_TEL_LINK_ON_PHONE_NUMBERS)))	// If phone or option for, we use link of phone
     		{
     			$newphone ='<a href="tel:'.$phone.'"';
     			$newphone.='>'.$phone.'</a>';
    @@ -2783,6 +2783,35 @@ function isValidEmail($address, $acceptsupervisorkey=0)
     	return false;
     }
     
    +/**
    + *	Return if the domain name has a valid MX record.
    + *  WARNING: This need function idn_to_ascii, checkdnsrr and getmxrr
    + *
    + *	@param	    string		$domain	    			Domain name (Ex: "yahoo.com", "yhaoo.com", "dolibarr.fr")
    + *	@return     int     							-1 if error (function not available), 0=Not valid, 1=Valid
    + */
    +function isValidMXRecord($domain)
    +{
    +	if (function_exists('idn_to_ascii') && function_exists('checkdnsrr'))
    +	{
    +		if (! checkdnsrr(idn_to_ascii($domain), 'MX'))
    +		{
    +			return 0;
    +		}
    +		if (function_exists('getmxrr'))
    +		{
    +			$mxhosts=array();
    +			$weight=array();
    +			getmxrr(idn_to_ascii($domain), $mxhosts, $weight);
    +			if (count($mxhosts) > 1) return 1;
    +			if (count($mxhosts) == 1 && ! empty($mxhosts[0])) return 1;
    +
    +			return 0;
    +		}
    +	}
    +	return -1;
    +}
    +
     /**
      *  Return true if phone number syntax is ok
      *  TODO Decide what to do with this
    @@ -3096,8 +3125,8 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo
      *	@param		boolean|int	$pictoisfullpath	If true or 1, image path is a full path
      *	@param		int			$srconly			Return only content of the src attribute of img.
      *  @param		int			$notitle			1=Disable tag title. Use it if you add js tooltip, to avoid duplicate tooltip.
    - *  @param		string		$alt				Force alt for bind peoplae
    - *  @param		string		$morecss			Add more class css on img tag (For example 'myclascss')
    + *  @param		string		$alt				Force alt for bind people
    + *  @param		string		$morecss			Add more class css on img tag (For example 'myclascss'). Work only if $moreatt is empty.
      *  @return     string       				    Return img tag
      *  @see        #img_object, #img_picto_common
      */
    @@ -3123,12 +3152,14 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     
     		//if (in_array($picto, array('switch_off', 'switch_on', 'off', 'on')))
     		if (empty($srconly) && in_array($pictowithoutext, array(
    -				'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'off', 'on', 'play', 'playdisabled', 'printer', 'resize',
    -				'switch_off', 'switch_on', 'unlink', 'uparrow')
    -			)) {
    +				'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'list', 'listlight', 'off', 'on', 'play', 'playdisabled', 'printer', 'resize',
    +				'note','switch_off', 'switch_on', 'unlink', 'uparrow', '1downarrow', '1uparrow',
    +				'skype','twitter','facebook'
    +			)
    +		)) {
     			$fakey = $pictowithoutext;
    -			$facolor = '';
    -			$fasize = '';
    +			$facolor = ''; $fasize = '';
    +			$marginleftonlyshort = 2;
     			if ($pictowithoutext == 'switch_off') {
     				$fakey = 'fa-toggle-off';
     				$facolor = '#999';
    @@ -3168,6 +3199,11 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     			elseif ($pictowithoutext == 'grip_title' || $pictowithoutext == 'grip') {
     				$fakey = 'fa-arrows';
     			}
    +			elseif ($pictowithoutext == 'listlight') {
    +				$fakey = 'fa-download';
    +				$facolor = '#999';
    +				$marginleftonlyshort=1;
    +			}
     			elseif ($pictowithoutext == 'printer') {
     				$fakey = 'fa-print';
     				$fasize = '1.2em';
    @@ -3177,10 +3213,23 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     				$fakey = 'fa-crop';
     				$facolor = '#444';
     			}
    +			elseif ($pictowithoutext == 'note') {
    +				$fakey = 'fa-sticky-note-o';
    +				$facolor = '#999';
    +				$marginleftonlyshort=1;
    +			}
     			elseif ($pictowithoutext == 'uparrow') {
     				$fakey = 'fa-mail-forward';
     				$facolor = '#555';
     			}
    +			elseif ($pictowithoutext == '1uparrow') {
    +				$fakey = 'fa-caret-up';
    +				$marginleftonlyshort = 1;
    +			}
    +			elseif ($pictowithoutext == '1downarrow') {
    +				$fakey = 'fa-caret-down';
    +				$marginleftonlyshort = 1;
    +			}
     			elseif ($pictowithoutext == 'unlink')     {
     				$fakey = 'fa-chain-broken';
     				$facolor = '#555';
    @@ -3192,12 +3241,13 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     			else {
     				$fakey = 'fa-'.$pictowithoutext;
     				$facolor = '#444';
    +				$marginleftonlyshort=0;
     			}
     
     			if (preg_match('/class="([^"]+)"/', $moreatt, $reg)) {
     				$morecss.= ($morecss?' ':'').$reg[1];
     			}
    -			$enabledisablehtml = '<span class="fa '.$fakey.' marginleftonly valignmiddle'.($morecss?' '.$morecss:'').'" style="'.($fasize?('font-size: '.$fasize.';'):'').($facolor?(' color: '.$facolor.';'):'').'" alt="'.dol_escape_htmltag($titlealt).'" title="'.dol_escape_htmltag($titlealt).'"'.($moreatt?' '.$moreatt:'').'>';
    +			$enabledisablehtml = '<span class="fa '.$fakey.' '.($marginleftonlyshort?($marginleftonlyshort==1?'marginleftonlyshort':'marginleftonly'):'').' valignmiddle'.($morecss?' '.$morecss:'').'" style="'.($fasize?('font-size: '.$fasize.';'):'').($facolor?(' color: '.$facolor.';'):'').'" alt="'.dol_escape_htmltag($titlealt).'"'.(($notitle || empty($title))?'':' title="'.dol_escape_htmltag($title).'"').($moreatt?' '.$moreatt:'').'>';
     			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
     				$enabledisablehtml.= $titlealt;
     			}
    @@ -3246,15 +3296,8 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     	if ($srconly) {
     		return $fullpathpicto;
     	}
    -	else {
     		// tag title is used for tooltip on <a>, tag alt can be used with very simple text on image for bind people
    -		//$tmparray=array(0=>$titlealt);
    -		//if (empty($notitle) && preg_match('/:[^\s0-9]/',$titlealt)) $tmparray=explode(':',$titlealt);		// We explode if we have TextA:TextB. Not if we have TextA: TextB
    -		//$title=$tmparray[0];
    -		//$alt=empty($tmparray[1])?'':$tmparray[1];
    -		$title = $titlealt;
    -		return '<img src="'.$fullpathpicto.'" alt="'.dol_escape_htmltag($alt).'"'.(($notitle || empty($title))?'':' title="'.dol_escape_htmltag($title).'"').($moreatt?' '.$moreatt:' class="inline-block"').'>';	// Alt is used for accessibility, title for popup
    -	}
    +    return '<img src="'.$fullpathpicto.'" alt="'.dol_escape_htmltag($alt).'"'.(($notitle || empty($titlealt))?'':' title="'.dol_escape_htmltag($titlealt).'"').($moreatt?' '.$moreatt:' class="inline-block'.($morecss?' '.$morecss:'').'"').'>';	// Alt is used for accessibility, title for popup
     }
     
     /**
    @@ -3828,8 +3871,8 @@ function dol_print_error($db='',$error='',$errors=null)
     		$langs = new Translate('', $conf);
     		$langs->load("main");
     	}
    -	$langs->load("main");
    -	$langs->load("errors");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array('main', 'errors'));
     
     	if ($_SERVER['DOCUMENT_ROOT'])    // Mode web
     	{
    @@ -3881,7 +3924,6 @@ function dol_print_error($db='',$error='',$errors=null)
     			$out.='> '.$langs->transnoentities("RequestLastAccessInError").":\n".($db->lastqueryerror()?$db->lastqueryerror():$langs->transnoentities("ErrorNoRequestInError"))."\n";
     			$out.='> '.$langs->transnoentities("ReturnCodeLastAccessInError").":\n".($db->lasterrno()?$db->lasterrno():$langs->transnoentities("ErrorNoRequestInError"))."\n";
     			$out.='> '.$langs->transnoentities("InformationLastAccessInError").":\n".($db->lasterror()?$db->lasterror():$langs->transnoentities("ErrorNoRequestInError"))."\n";
    -
     		}
     		$syslog.=", sql=".$db->lastquery();
     		$syslog.=", db_error=".$db->lasterror();
    @@ -4220,7 +4262,7 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so
     	// Left
     	//if ($picto && $titre) print '<td class="nobordernopadding hideonsmartphone" width="40" align="left" valign="middle">'.img_picto('', $picto, 'id="pictotitle"', $pictoisfullpath).'</td>';
     	print '<td class="nobordernopadding valignmiddle">';
    -	if ($picto && $titre) print img_picto('', $picto, 'class="hideonsmartphone valignmiddle opacityhigh widthpictotitle" id="pictotitle"', $pictoisfullpath);
    +	if ($picto && $titre) print img_picto('', $picto, 'class="hideonsmartphone valignmiddle opacityhigh pictotitle widthpictotitle"', $pictoisfullpath);
     	print '<div class="titre inline-block">'.$titre;
     	if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print ' ('.$totalnboflines.')';
     	print '</div></td>';
    @@ -4831,7 +4873,6 @@ function get_localtax_by_third($local)
     	}
     
     	return 0;
    -
     }
     
     
    @@ -4944,7 +4985,6 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi
     		else
     		{
     			return array($obj->localtax1_type, get_localtax($vatrate, 1, $buyer, $seller), $obj->localtax2_type, get_localtax($vatrate, 2, $buyer, $seller), $obj->accountancy_code_sell,$obj->accountancy_code_buy);
    -
     		}
     	}
     
    @@ -5066,8 +5106,6 @@ function get_product_localtax_for_country($idprod, $local, $thirdparty_seller)
     		else
     		{
     			// TODO Read default product vat according to countrycode and product
    -
    -
     		}
     	}
     
    @@ -5128,7 +5166,7 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer,
     	$buyer_country_code = $thirdparty_buyer->country_code;
     	$buyer_in_cee = isInEEC($thirdparty_buyer);
     
    -	dol_syslog("get_default_tva: seller use vat=".$seller_use_vat.", seller country=".$seller_country_code.", seller in cee=".$seller_in_cee.", buyer country=".$buyer_country_code.", buyer in cee=".$buyer_in_cee.", idprod=".$idprod.", idprodfournprice=".$idprodfournprice.", SERVICE_ARE_ECOMMERCE_200238EC=".(! empty($conf->global->SERVICES_ARE_ECOMMERCE_200238EC)?$conf->global->SERVICES_ARE_ECOMMERCE_200238EC:''));
    +	dol_syslog("get_default_tva: seller use vat=".$seller_use_vat.", seller country=".$seller_country_code.", seller in cee=".$seller_in_cee.", buyer vat number=".$thirdparty_buyer->tva_intra." buyer country=".$buyer_country_code.", buyer in cee=".$buyer_in_cee.", idprod=".$idprod.", idprodfournprice=".$idprodfournprice.", SERVICE_ARE_ECOMMERCE_200238EC=".(! empty($conf->global->SERVICES_ARE_ECOMMERCE_200238EC)?$conf->global->SERVICES_ARE_ECOMMERCE_200238EC:''));
     
     	// If services are eServices according to EU Council Directive 2002/38/EC (http://ec.europa.eu/taxation_customs/taxation/vat/traders/e-commerce/article_1610_en.htm)
     	// we use the buyer VAT.
    @@ -5179,8 +5217,7 @@ function get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer,
     	}
     
     	// Si (vendeur en France et acheteur hors Communaute europeenne et acheteur particulier) alors TVA par defaut=TVA du produit vendu. Fin de regle
    -	if (! empty($conf->global->MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC) && empty($buyer_in_cee) && !$thirdparty_buyer->isACompany())
    -	{
    +	if (! empty($conf->global->MAIN_USE_VAT_OF_PRODUCT_FOR_INDIVIDUAL_CUSTOMER_OUT_OF_EEC) && empty($buyer_in_cee) && !$thirdparty_buyer->isACompany()) {
     		return get_product_vat_for_country($idprod,$thirdparty_seller,$idprodfournprice);
     	}
     
    @@ -5551,7 +5588,6 @@ function dolGetFirstLineOfText($text, $nboflines=1)
     		{
     			$firstline=preg_replace('/<br[^>]*>.*$/s','',$text);		// The s pattern modifier means the . can match newline characters
     			$firstline=preg_replace('/<div[^>]*>.*$/s','',$firstline);	// The s pattern modifier means the . can match newline characters
    -
     		}
     		else
     		{
    @@ -6134,7 +6170,13 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob
     
     		$substitutionarray=array_merge($substitutionarray, array(
     			'__DAY__' => (string) $tmp['mday'],
    +			'__DAY_TEXT__' => $outputlangs->trans('Day'.$tmp['wday']),					// Monday
    +			'__DAY_TEXT_SHORT__' => $outputlangs->trans($tmp['weekday'].'Min'),			// Mon
    +			'__DAY_TEXT_MIN__' => $outputlangs->trans('Short'.$tmp['weekday']),			// M
     			'__MONTH__' => (string) $tmp['mon'],
    +			'__MONTH_TEXT__' => $outputlangs->trans('Month'.sprintf("%02d", $tmp['mon'])),
    +			'__MONTH_TEXT_SHORT__' => $outputlangs->trans('MonthShort'.sprintf("%02d", $tmp['mon'])),
    +			'__MONTH_TEXT_MIN__' => $outputlangs->trans('MonthVeryShort'.sprintf("%02d", $tmp['mon'])),
     			'__YEAR__' => (string) $tmp['year'],
     			'__PREVIOUS_DAY__' => (string) $tmp2['day'],
     			'__PREVIOUS_MONTH__' => (string) $tmp3['month'],
    @@ -6958,7 +7000,7 @@ function complete_head_from_modules($conf,$langs,$object,&$head,&$h,$type,$mode=
     				foreach($head as $key => $val)
     				{
     					$condition = (! empty($values[3]) ? verifCond($values[3]) : 1);
    -					//var_dump($key.' - '.$tabname.' - '.$head[$key][2].' - '.$condition);
    +					//var_dump($key.' - '.$tabname.' - '.$head[$key][2].' - '.$values[3].' - '.$condition);
     					if ($head[$key][2]==$tabname && $condition)
     					{
     						unset($head[$key]);
    @@ -6995,7 +7037,8 @@ function complete_head_from_modules($conf,$langs,$object,&$head,&$h,$type,$mode=
      */
     function printCommonFooter($zone='private')
     {
    -	global $conf, $hookmanager;
    +	global $conf, $hookmanager, $user;
    +	global $action;
     	global $micro_start_time;
     
     	if ($zone == 'private') print "\n".'<!-- Common footer for private page -->'."\n";
    @@ -7028,7 +7071,77 @@ function printCommonFooter($zone='private')
     				print '});'."\n";
     			}
     
    -			// Google Analytics (need Google module)
    +			// Management of focus and mandatory for fields
    +			if ($action == 'create' || $action == 'edit')
    +			{
    +				print '/* Code js to manage focus and mandatory form fields */'."\n";
    +				$relativepathstring = $_SERVER["PHP_SELF"];
    +				// Clean $relativepathstring
    +				if (constant('DOL_URL_ROOT')) $relativepathstring = preg_replace('/^'.preg_quote(constant('DOL_URL_ROOT'),'/').'/', '', $relativepathstring);
    +				$relativepathstring = preg_replace('/^\//', '', $relativepathstring);
    +				$relativepathstring = preg_replace('/^custom\//', '', $relativepathstring);
    +				$tmpqueryarraywehave=explode('&', dol_string_nohtmltag($_SERVER['QUERY_STRING']));
    +				if (!empty($user->default_values[$relativepathstring]['focus']))
    +				{
    +					foreach($user->default_values[$relativepathstring]['focus'] as $defkey => $defval)
    +					{
    +						$qualified = 0;
    +						if ($defkey != '_noquery_')
    +						{
    +							$tmpqueryarraytohave=explode('&', $defkey);
    +							$foundintru=0;
    +							foreach($tmpqueryarraytohave as $tmpquerytohave)
    +							{
    +								if (! in_array($tmpquerytohave, $tmpqueryarraywehave)) $foundintru=1;
    +							}
    +							if (! $foundintru) $qualified=1;
    +							//var_dump($defkey.'-'.$qualified);
    +						}
    +						else $qualified = 1;
    +
    +						if ($qualified)
    +						{
    +							foreach($defval as $paramkey => $paramval)
    +							{
    +								// Add property 'required' on input
    +								print 'jQuery("input[name=\''.$paramkey.'\']").focus();'."\n";
    +							}
    +						}
    +					}
    +				}
    +				if (!empty($user->default_values[$relativepathstring]['mandatory']))
    +				{
    +					foreach($user->default_values[$relativepathstring]['mandatory'] as $defkey => $defval)
    +					{
    +						$qualified = 0;
    +						if ($defkey != '_noquery_')
    +						{
    +							$tmpqueryarraytohave=explode('&', $defkey);
    +							$foundintru=0;
    +							foreach($tmpqueryarraytohave as $tmpquerytohave)
    +							{
    +								if (! in_array($tmpquerytohave, $tmpqueryarraywehave)) $foundintru=1;
    +							}
    +							if (! $foundintru) $qualified=1;
    +							//var_dump($defkey.'-'.$qualified);
    +						}
    +						else $qualified = 1;
    +
    +						if ($qualified)
    +						{
    +							foreach($defval as $paramkey => $paramval)
    +							{
    +								// Add property 'required' on input
    +								print 'jQuery("input[name=\''.$paramkey.'\']").prop(\'required\',true);'."\n";
    +								print 'jQuery("select[name=\''.$paramkey.'\']").prop(\'required\',true);'."\n";		// required on a select works only if key is "", this does not happen in Dolibarr
    +							}
    +						}
    +					}
    +				}
    +			}
    +
    +			// Google Analytics
    +			// TODO Add a hook here
     			if (! empty($conf->google->enabled) && ! empty($conf->global->MAIN_GOOGLE_AN_ID))
     			{
     				if (($conf->dol_use_jmobile != 4))
    @@ -7164,11 +7277,11 @@ function dol_getmypid()
     /**
      * Generate natural SQL search string for a criteria (this criteria can be tested on one or several fields)
      *
    - * @param 	string|string[]	$fields 	String or array of strings, filled with the name of all fields in the SQL query we must check (combined with a OR). Example: array("p.field1","p.field2")
    - * @param 	string 			$value 		The value to look for.
    + * @param   string|string[]	$fields 	String or array of strings, filled with the name of all fields in the SQL query we must check (combined with a OR). Example: array("p.field1","p.field2")
    + * @param   string 			$value 		The value to look for.
      *                          		    If param $mode is 0, can contains several keywords separated with a space or |
    - *                                         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
    + *                                      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"
    @@ -7421,6 +7534,7 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param=''
      *
      * @param string	$htmlname	Id of html object
      * @param string	$addlink	Add a 'link to' after
    + * @return string
      */
     function ajax_autoselect($htmlname, $addlink='')
     {
    @@ -7558,6 +7672,7 @@ function dol_mimetype($file, $default='application/octet-stream', $mode=0)
      * @param int		$id				id of line
      * @param bool		$checkentity	add filter on entity
      * @param string	$rowidfield		name of the column rowid
    + * @return string
      */
     function getDictvalue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
     {
    @@ -7567,7 +7682,7 @@ function getDictvalue($tablename, $field, $id, $checkentity=false, $rowidfield='
     	{
     		$dictvalues[$tablename] = array();
     		$sql = 'SELECT * FROM '.$tablename.' WHERE 1';
    -		if ($checkentity) $sql.= ' entity IN (0,'.getEntity('').')';
    +		if ($checkentity) $sql.= ' AND entity IN (0,'.getEntity('').')';
     
     		$resql = $db->query($sql);
     		if ($resql)
    diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php
    index 41ff14b011a..8a22337cea8 100644
    --- a/htdocs/core/lib/functions2.lib.php
    +++ b/htdocs/core/lib/functions2.lib.php
    @@ -194,9 +194,10 @@ function dol_print_file($langs,$filename,$searchalt=0)
      */
     function dol_print_object_info($object, $usetable=0)
     {
    -    global $langs,$db;
    -    $langs->load("other");
    -    $langs->load("admin");
    +    global $langs, $db;
    +
    +    // Load translation files required by the page
    +    $langs->loadLangs(array('other', 'admin'));
     
         include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
    @@ -1167,7 +1168,16 @@ function get_next_value($db,$mask,$table,$field,$where='',$objsoc='',$date='',$m
         return $numFinal;
     }
     
    -function get_string_between($string, $start, $end){
    +/**
    + * Get string between
    + *
    + * @param   string  $string     String to test
    + * @param   int     $start      Value for start
    + * @param   int     $end        Value for end
    + * @return  string              Return part of string
    + */
    +function get_string_between($string, $start, $end)
    +{
         $string = " ".$string;
          $ini = strpos($string,$start);
          if ($ini == 0) return "";
    @@ -1760,7 +1770,7 @@ function getSoapParams()
     
     
     /**
    - * List urls of element
    + * Return link url to an object
      *
      * @param 	int		$objectid		Id of record
      * @param 	string	$objecttype		Type of object ('invoice', 'order', 'expedition_bon', ...)
    @@ -1871,7 +1881,11 @@ function dolGetElementUrl($objectid,$objecttype,$withpicto=0,$option='')
     			{
     				$object = new $classname($db);
     				$res=$object->fetch($objectid);
    -				if ($res > 0) $ret=$object->getNomUrl($withpicto,$option);
    +				if ($res > 0) {
    +					$ret=$object->getNomUrl($withpicto,$option);
    +				} elseif($res==0) {
    +					$ret=$langs->trans('Deleted');
    +				}
     				unset($object);
     			}
     			else dol_syslog("Class with classname ".$classname." is unknown even after the include", LOG_ERR);
    @@ -2193,7 +2207,8 @@ function colorStringToArray($stringcolor,$colorifnotfound=array(88,88,88))
      * @param   array $input    Array of products
      * @return  array           Array of combinations
      */
    -function cartesianArray(array $input) {
    +function cartesianArray(array $input)
    +{
         // filter out empty values
         $input = array_filter($input);
     
    @@ -2301,8 +2316,9 @@ function getModuleDirForApiClass($module)
      * @param	$max	int	Between 0 and 255
      * @return String
      */
    -function random_color_part($min=0,$max=255) {
    -	return str_pad( dechex( mt_rand( $min, $max) ), 2, '0', STR_PAD_LEFT);
    +function random_color_part($min=0,$max=255)
    +{
    +    return str_pad( dechex( mt_rand( $min, $max) ), 2, '0', STR_PAD_LEFT);
     }
     
     /*
    @@ -2312,6 +2328,7 @@ function random_color_part($min=0,$max=255) {
      * @param	$max	int	Between 0 and 255
      * @return String
      */
    -function random_color($min=0, $max=255) {
    -	return random_color_part($min, $max) . random_color_part($min, $max) . random_color_part($min, $max);
    +function random_color($min=0, $max=255)
    +{
    +    return random_color_part($min, $max) . random_color_part($min, $max) . random_color_part($min, $max);
     }
    diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php
    index f4319b7d11a..9f04a81fa5f 100644
    --- a/htdocs/core/lib/functionsnumtoword.lib.php
    +++ b/htdocs/core/lib/functionsnumtoword.lib.php
    @@ -21,12 +21,12 @@
      *	\brief			A set of functions for Dolibarr
      *					This file contains all frequently used functions.
      */
    - 
    - 
    +
    +
     /**
      * Function to return number in text.
    - * 
    - * 
    + *
    + *
      * @param	float 	$num			Number to convert
      * @param	Lang	$langs			Language
      * @param	boolean	$currency		0=number to translate | 1=currency to translate
    @@ -36,7 +36,7 @@
     function dol_convertToWord($num, $langs, $currency=false, $centimes=false)
     {
     	global $conf;
    -	
    +
         $num = str_replace(array(',', ' '), '', trim($num));
         if(! $num) {
             return false;
    @@ -48,49 +48,49 @@ function dol_convertToWord($num, $langs, $currency=false, $centimes=false)
         $num = (int) $TNum[0];
         $words = array();
         $list1 = array(
    -    	'', 
    -    	$langs->transnoentitiesnoconv('one'), 
    -    	$langs->transnoentitiesnoconv('two'), 
    -    	$langs->transnoentitiesnoconv('three'), 
    -    	$langs->transnoentitiesnoconv('four'), 
    -    	$langs->transnoentitiesnoconv('five'), 
    -    	$langs->transnoentitiesnoconv('six'), 
    -    	$langs->transnoentitiesnoconv('seven'), 
    -    	$langs->transnoentitiesnoconv('eight'), 
    -    	$langs->transnoentitiesnoconv('nine'), 
    -    	$langs->transnoentitiesnoconv('ten'), 
    +    	'',
    +    	$langs->transnoentitiesnoconv('one'),
    +    	$langs->transnoentitiesnoconv('two'),
    +    	$langs->transnoentitiesnoconv('three'),
    +    	$langs->transnoentitiesnoconv('four'),
    +    	$langs->transnoentitiesnoconv('five'),
    +    	$langs->transnoentitiesnoconv('six'),
    +    	$langs->transnoentitiesnoconv('seven'),
    +    	$langs->transnoentitiesnoconv('eight'),
    +    	$langs->transnoentitiesnoconv('nine'),
    +    	$langs->transnoentitiesnoconv('ten'),
         	$langs->transnoentitiesnoconv('eleven'),
    -        $langs->transnoentitiesnoconv('twelve'), 
    -        $langs->transnoentitiesnoconv('thirteen'), 
    -        $langs->transnoentitiesnoconv('fourteen'), 
    -        $langs->transnoentitiesnoconv('fifteen'), 
    -        $langs->transnoentitiesnoconv('sixteen'), 
    -        $langs->transnoentitiesnoconv('seventeen'), 
    -        $langs->transnoentitiesnoconv('eighteen'), 
    +        $langs->transnoentitiesnoconv('twelve'),
    +        $langs->transnoentitiesnoconv('thirteen'),
    +        $langs->transnoentitiesnoconv('fourteen'),
    +        $langs->transnoentitiesnoconv('fifteen'),
    +        $langs->transnoentitiesnoconv('sixteen'),
    +        $langs->transnoentitiesnoconv('seventeen'),
    +        $langs->transnoentitiesnoconv('eighteen'),
             $langs->transnoentitiesnoconv('nineteen')
         );
         $list2 = array(
    -    	'', 
    -	    $langs->transnoentitiesnoconv('ten'), 
    -	    $langs->transnoentitiesnoconv('twenty'), 
    -	    $langs->transnoentitiesnoconv('thirty'), 
    -	    $langs->transnoentitiesnoconv('forty'), 
    -	    $langs->transnoentitiesnoconv('fifty'), 
    -	    $langs->transnoentitiesnoconv('sixty'), 
    -	    $langs->transnoentitiesnoconv('seventy'), 
    -	    $langs->transnoentitiesnoconv('eighty'), 
    -	    $langs->transnoentitiesnoconv('ninety'), 
    +    	'',
    +	    $langs->transnoentitiesnoconv('ten'),
    +	    $langs->transnoentitiesnoconv('twenty'),
    +	    $langs->transnoentitiesnoconv('thirty'),
    +	    $langs->transnoentitiesnoconv('forty'),
    +	    $langs->transnoentitiesnoconv('fifty'),
    +	    $langs->transnoentitiesnoconv('sixty'),
    +	    $langs->transnoentitiesnoconv('seventy'),
    +	    $langs->transnoentitiesnoconv('eighty'),
    +	    $langs->transnoentitiesnoconv('ninety'),
     	    $langs->transnoentitiesnoconv('hundred')
     	);
         $list3 = array(
    -    	'', 
    -    	$langs->transnoentitiesnoconv('thousand'), 
    -    	$langs->transnoentitiesnoconv('million'), 
    -    	$langs->transnoentitiesnoconv('billion'), 
    -    	$langs->transnoentitiesnoconv('trillion'), 
    +    	'',
    +    	$langs->transnoentitiesnoconv('thousand'),
    +    	$langs->transnoentitiesnoconv('million'),
    +    	$langs->transnoentitiesnoconv('billion'),
    +    	$langs->transnoentitiesnoconv('trillion'),
         	$langs->transnoentitiesnoconv('quadrillion')
         );
    -	
    +
         $num_length = strlen($num);
         $levels = (int) (($num_length + 2) / 3);
         $max_length = $levels * 3;
    @@ -120,11 +120,11 @@ function dol_convertToWord($num, $langs, $currency=false, $centimes=false)
     	$concatWords = implode(' ', $words);
     	// Delete multi whitespaces
     	$concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords));
    -	
    +
     	if(!empty($currency)) {
     		$concatWords .= ' '.$currency;
     	}
    -	
    +
     	// If we need to write cents call again this function for cents
     	if(!empty($TNum[1])) {
     		if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and');
    @@ -133,11 +133,11 @@ function dol_convertToWord($num, $langs, $currency=false, $centimes=false)
     	}
         return $concatWords;
     }
    - 
    - 
    +
    +
     /**
      * Function to return number or amount in text.
    - * 
    + *
      * @deprecated
      * @param	float 	$numero			Number to convert
      * @param	Lang	$langs			Language
    @@ -164,7 +164,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency='number')
     	/*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and
     	in case exist why ask $lang like a parameter?*/
     	if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency')
    -	{	
    +	{
     		if ($numero>=1 && $numero<2) {
     			return ("UN PESO ".$parte_decimal." / 100 M.N.");
     		}
    @@ -229,10 +229,11 @@ function dolNumberToWord($numero, $langs, $numorcurrency='number')
     
     /**
      * hundreds2text
    - * 
    + *
      * @param integer $hundreds     Hundreds
      * @param integer $tens         Tens
      * @param integer $units        Units
    + * @return string
      */
     function hundreds2text($hundreds, $tens, $units)
     {
    diff --git a/htdocs/core/lib/holiday.lib.php b/htdocs/core/lib/holiday.lib.php
    index 56d19d0e0f1..b4b19d4df40 100644
    --- a/htdocs/core/lib/holiday.lib.php
    +++ b/htdocs/core/lib/holiday.lib.php
    @@ -61,3 +61,32 @@ function holiday_prepare_head($object)
     
     	return $head;
     }
    +
    +
    +/**
    + *  Return array head with list of tabs to view object informations
    + *
    +  *  @return array           		head
    + */
    +function holiday_admin_prepare_head()
    +{
    +	global $db, $langs, $conf, $user;
    +
    +	$h = 0;
    +	$head = array();
    +
    +    $head[$h][0] = DOL_URL_ROOT.'/admin/holiday.php';
    +    $head[$h][1] = $langs->trans("Setup");
    +    $head[$h][2] = 'holiday';
    +    $h++;
    +
    +    // Show more tabs from modules
    +    // Entries must be declared in modules descriptor with line
    +    // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
    +    // $this->tabs = array('entity:-tabname);   												to remove a tab
    +    complete_head_from_modules($conf,$langs,null,$head,$h,'holiday_admin');
    +
    +	complete_head_from_modules($conf,$langs,null,$head,$h,'holiday_admin','remove');
    +
    +	return $head;
    +}
    diff --git a/htdocs/core/lib/hrm.lib.php b/htdocs/core/lib/hrm.lib.php
    index 5f7eabc7500..08b0e3be01a 100644
    --- a/htdocs/core/lib/hrm.lib.php
    +++ b/htdocs/core/lib/hrm.lib.php
    @@ -18,7 +18,7 @@
     /**
      * \file    htdocs/core/lib/hrm.lib.php
      * \ingroup HRM
    - * \brief   Library for hrm 
    + * \brief   Library for hrm
      */
     $langs->load('hrm');
     
    diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php
    index 4e7fa860529..94eb4527b74 100644
    --- a/htdocs/core/lib/invoice.lib.php
    +++ b/htdocs/core/lib/invoice.lib.php
    @@ -36,7 +36,7 @@
     function facture_prepare_head($object)
     {
     	global $db, $langs, $conf;
    -	
    +
     	$h = 0;
     	$head = array();
     
    @@ -63,7 +63,7 @@ function facture_prepare_head($object)
     	    $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_facture_demande as pfd";
     	    $sql .= " WHERE pfd.fk_facture = ".$object->id;
             $resql=$db->query($sql);
    -        if ($resql) 
    +        if ($resql)
             {
                 $obj=$db->fetch_object($resql);
                 if ($obj) $nbStandingOrders = $obj->nb;
    @@ -152,12 +152,12 @@ function invoice_admin_prepare_head()
     	$head[$h][1] = $langs->trans("ExtraFieldsLines");
     	$head[$h][2] = 'attributeslines';
     	$h++;
    -	
    +
     	$head[$h][0] = DOL_URL_ROOT.'/compta/facture/admin/facture_rec_cust_extrafields.php';
     	$head[$h][1] = $langs->trans("ExtraFieldsCustomerInvoicesRec");
     	$head[$h][2] = 'attributesrec';
     	$h++;
    -	
    +
     	$head[$h][0] = DOL_URL_ROOT.'/compta/facture/admin/facturedet_rec_cust_extrafields.php';
     	$head[$h][1] = $langs->trans("ExtraFieldsLinesRec");
     	$head[$h][2] = 'attributeslinesrec';
    @@ -169,10 +169,16 @@ function invoice_admin_prepare_head()
     }
     
     
    +/**
    + * Return array head with list of tabs to view object informations.
    + *
    + * @param   Facture     $object     Invoice object
    + * @return array                    head array with tabs
    + */
     function invoice_rec_prepare_head($object)
     {
     	global $db, $langs, $conf;
    -	
    +
     	$h = 0;
     	$head = array();
     
    @@ -191,5 +197,3 @@ function invoice_rec_prepare_head($object)
     
     	return $head;
     }
    -
    -
    diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php
    index 866cf004ca6..f318f493417 100644
    --- a/htdocs/core/lib/invoice2.lib.php
    +++ b/htdocs/core/lib/invoice2.lib.php
    @@ -23,8 +23,8 @@
      *      \brief      Function to rebuild PDF and merge PDF files into one
      */
     
    -require_once(DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php');
    -require_once(DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php');
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     
     /**
    diff --git a/htdocs/core/lib/loan.lib.php b/htdocs/core/lib/loan.lib.php
    index 3f7029dd26b..b61c57b4bc3 100644
    --- a/htdocs/core/lib/loan.lib.php
    +++ b/htdocs/core/lib/loan.lib.php
    @@ -59,7 +59,7 @@ function loan_prepare_head($object)
     	$tab++;
     
     	if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
    -	{		
    +	{
     		$nbNote = (empty($object->note_private)?0:1)+(empty($object->note_public)?0:1);
     		$head[$tab][0] = DOL_URL_ROOT."/loan/note.php?id=".$object->id;
     		$head[$tab][1] = $langs->trans("Notes");
    diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php
    index 8187c15f684..4981e0fffd0 100644
    --- a/htdocs/core/lib/modulebuilder.lib.php
    +++ b/htdocs/core/lib/modulebuilder.lib.php
    @@ -63,7 +63,9 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
         		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Label")), null, 'errors');
         		return -2;
         	}
    -    	if (! preg_match('/^(integer|date|timestamp|varchar|double|html|price)/', $addfieldentry['type']))
    +
    +    	if (! preg_match('/^(price|boolean|sellist|integer|date|timestamp|varchar|double|text|html)/', $addfieldentry['type']))
    +
         	{
         		setEventMessages($langs->trans('BadFormatForType', $objectname), null, 'errors');
         		return -2;
    @@ -259,8 +261,10 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='',
     
                 $type = $val['type'];
                 $type = preg_replace('/:.*$/', '', $type);		// For case type = 'integer:Societe:societe/class/societe.class.php'
    +
                 if ($type == 'html') $type = 'text';            // html modulebuilder type is a text type in database
    -            if ($type == 'price') $type = 'double';            // html modulebuilder type is a text type in database
    +            else if ($type == 'price') $type = 'double';            // html modulebuilder type is a text type in database
    +            else if ($type == 'link' || $type == 'sellist') $type = 'integer';
                 $texttoinsert.= "\t".$key." ".$type;
                 if ($key == 'rowid')  $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
                 if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
    @@ -269,7 +273,7 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='',
                 	if ($val['default'] != '')
                 	{
                 		if (preg_match('/^null$/i', $val['default'])) $texttoinsert.= " DEFAULT NULL";
    -            		else if (preg_match('/varchar/', $val['type'])) $texttoinsert.= " DEFAULT '".$db->escape($val['default'])."'";
    +            		else if (preg_match('/varchar/', $type )) $texttoinsert.= " DEFAULT '".$db->escape($val['default'])."'";
                 		else $texttoinsert.= (($val['default'] > 0)?' DEFAULT '.$val['default']:'');
                 	}
                 }
    @@ -339,5 +343,3 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='',
     
         return $error ? -1 : 1;
     }
    -
    -
    diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php
    index 9e07976f072..0119b0f0ee5 100644
    --- a/htdocs/core/lib/payments.lib.php
    +++ b/htdocs/core/lib/payments.lib.php
    @@ -25,7 +25,8 @@
      * @param Paiement $object Current payment object
      * @return array Tabs for the payment section
      */
    -function payment_prepare_head(Paiement $object) {
    +function payment_prepare_head(Paiement $object)
    +{
     
     	global $langs, $conf;
     
    @@ -60,8 +61,8 @@ function payment_prepare_head(Paiement $object) {
      * @param Paiement $object Current payment object
      * @return array Tabs for the payment section
      */
    -function payment_supplier_prepare_head(Paiement $object) {
    -
    +function payment_supplier_prepare_head(Paiement $object)
    +{
     	global $langs, $conf;
     
     	$h = 0;
    @@ -91,7 +92,7 @@ function payment_supplier_prepare_head(Paiement $object) {
     /**
      * Return array of valid payment mode
      *
    - * @param	string	$paymentmethod		Filter on this payment method
    + * @param	string	$paymentmethod		Filter on this payment method (''=none, 'paypal', ...)
      * @return	array						Array of valid payment method
      */
     function getValidOnlinePaymentMethods($paymentmethod='')
    @@ -126,8 +127,9 @@ function showOnlinePaymentUrl($type,$ref)
     {
     	global $conf, $langs;
     
    -	$langs->load("payment");
    -	$langs->load("paybox");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array('payment', 'paybox'));
    +
     	$servicename='Online';
     
     	$out = img_picto('','object_globe.png').' '.$langs->trans("ToOfferALinkForOnlinePayment",$servicename).'<br>';
    @@ -235,6 +237,24 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
     			}
     		}
     	}
    +	if ($type == 'donation')
    +	{
    +		$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=donation&ref='.($mode?'<font color="#666666">':'');
    +		if ($mode == 1) $out.='donation_ref';
    +		if ($mode == 0) $out.=urlencode($ref);
    +		$out.=($mode?'</font>':'');
    +		if (! empty($conf->global->PAYMENT_SECURITY_TOKEN))
    +		{
    +			if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) $out.='&securekey='.$conf->global->PAYMENT_SECURITY_TOKEN;
    +			else
    +			{
    +				$out.='&securekey='.($mode?'<font color="#666666">':'');
    +				if ($mode == 1) $out.="hash('".$conf->global->PAYMENT_SECURITY_TOKEN."' + '".$type."' + donation_ref)";
    +				if ($mode == 0) $out.= dol_hash($conf->global->PAYMENT_SECURITY_TOKEN . $type . $ref, 2);
    +				$out.=($mode?'</font>':'');
    +			}
    +		}
    +	}
     
     	// For multicompany
     	if (! empty($out) && ! empty($conf->multicompany->enabled)) $out.="&entity=".$conf->entity; // Check the entity because we may have the same reference in several entities
    diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
    index 73de27cafac..5b8a5d6d4c4 100644
    --- a/htdocs/core/lib/pdf.lib.php
    +++ b/htdocs/core/lib/pdf.lib.php
    @@ -261,8 +261,9 @@ function pdf_getHeightForLogo($logo, $url = false)
     /**
      * Function to try to calculate height of a HTML Content
      *
    - * @param TCPDF     $pdf            PDF initialized object
    - * @param string    $htmlcontent    HTML Contect
    + * @param 	TCPDF     $pdf				PDF initialized object
    + * @param 	string    $htmlcontent		HTML Contect
    + * @return 	int							Height
      * @see getStringHeight
      */
     function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent)
    @@ -1203,8 +1204,16 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
     	$note=(! empty($object->lines[$i]->note)?$object->lines[$i]->note:'');
     	$dbatch=(! empty($object->lines[$i]->detail_batch)?$object->lines[$i]->detail_batch:false);
     
    -	if ($issupplierline) $prodser = new ProductFournisseur($db);
    -	else $prodser = new Product($db);
    +	if ($issupplierline)
    +	{
    +		include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
    +		$prodser = new ProductFournisseur($db);
    +	}
    +	else
    +	{
    +		include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    +		$prodser = new Product($db);
    +	}
     
     	if ($idprod)
     	{
    @@ -1282,7 +1291,17 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
     		{
     			if ($idprod)
     			{
    -				if (empty($hidedesc)) $libelleproduitservice.=$desc;
    +				if (empty($hidedesc))
    +				{
    +					if (!empty($conf->global->MAIN_DOCUMENTS_DESCRIPTION_FIRST))
    +					{
    +						$libelleproduitservice=$desc."\n".$libelleproduitservice;
    +					}
    +					else
    +					{
    +						$libelleproduitservice.=$desc;
    +					}
    +				}
     			}
     			else
     			{
    @@ -2086,8 +2105,8 @@ function pdf_getLinkedObjects($object,$outputlangs)
     		}
     		else if ($objecttype == 'shipping')
     		{
    -			$outputlangs->load('orders');
    -			$outputlangs->load('sendings');
    +			$outputlangs->loadLangs(array("orders", "sendings"));
    +
     			foreach($objects as $x => $elementobject)
     			{
     			    $order=null;
    @@ -2161,4 +2180,3 @@ function pdf_getSizeForImage($realpath)
     	}
     	return array('width'=>$width,'height'=>$height);
     }
    -
    diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php
    index 731f8859eba..1c704392c6b 100644
    --- a/htdocs/core/lib/product.lib.php
    +++ b/htdocs/core/lib/product.lib.php
    @@ -190,8 +190,9 @@ function product_prepare_head($object)
     function productlot_prepare_head($object)
     {
         global $db, $langs, $conf, $user;
    -    $langs->load("products");
    -    $langs->load("productbatch");
    +
    +    // Load translation files required by the page
    +    $langs->loadLangs(array("products","productbatch"));
     
         $h = 0;
         $head = array();
    @@ -200,7 +201,7 @@ function productlot_prepare_head($object)
         $head[$h][1] = $langs->trans("Card");
         $head[$h][2] = 'card';
     	$h++;
    -	
    +
     	// Attachments
     	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
         require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
    diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php
    index 4d5779c52d1..1e5046d4d58 100644
    --- a/htdocs/core/lib/project.lib.php
    +++ b/htdocs/core/lib/project.lib.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2006-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2010      Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2011      Juanjo Menent        <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -1047,7 +1048,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr
     
     				// Form to add new time
     				print '<td class="nowrap leftborder" align="center">';
    -				$tableCell=$form->select_date($preselectedday,$lines[$i]->id,1,1,2,"addtime",0,0,1,$disabledtask);
    +				$tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask);
     				print $tableCell;
     				print '</td>';
     
    @@ -1706,4 +1707,3 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks=
     		print '</table></form>';
     	}
     }
    -
    diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php
    index c50661de831..aec26236113 100644
    --- a/htdocs/core/lib/propal.lib.php
    +++ b/htdocs/core/lib/propal.lib.php
    @@ -32,9 +32,7 @@
     function propal_prepare_head($object)
     {
     	global $db, $langs, $conf, $user;
    -	$langs->load("propal");
    -	$langs->load("compta");
    -	$langs->load("companies");
    +	$langs->loadLangs(array('propal', 'compta', 'companies'));
     
     	$h = 0;
     	$head = array();
    @@ -48,6 +46,7 @@ function propal_prepare_head($object)
     	|| (! empty($conf->livraison_bon->enabled) && $user->rights->expedition->livraison->lire))))
     	{
     		$langs->load("sendings");
    +		$text = '';
     		$head[$h][0] = DOL_URL_ROOT.'/expedition/propal.php?id='.$object->id;
     		if ($conf->expedition_bon->enabled) $text=$langs->trans("Shipment");
     		if ($conf->livraison_bon->enabled)  $text.='/'.$langs->trans("Receivings");
    diff --git a/htdocs/core/lib/resource.lib.php b/htdocs/core/lib/resource.lib.php
    index 6ab25c5b57f..defc45823e4 100644
    --- a/htdocs/core/lib/resource.lib.php
    +++ b/htdocs/core/lib/resource.lib.php
    @@ -77,6 +77,16 @@ function resource_prepare_head($object)
     	$head[$h][2] = 'documents';
     	$h++;
     
    +	$head[$h][0] = DOL_URL_ROOT.'/resource/agenda.php?id='.$object->id;
    +	$head[$h][1] = $langs->trans("Events");
    +	if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) ))
    +	{
    +		$head[$h][1].= '/';
    +		$head[$h][1].= $langs->trans("Agenda");
    +	}
    +	$head[$h][2] = 'agenda';
    +	$h++;
    +
     	/*$head[$h][0] = DOL_URL_ROOT.'/resource/info.php?id='.$object->id;
     	$head[$h][1] = $langs->trans('Info');
     	$head[$h][2] = 'info';
    @@ -87,7 +97,13 @@ function resource_prepare_head($object)
     	return $head;
     }
     
    -function resource_admin_prepare_head() {
    +/**
    + * Prepare head for admin tabs
    + *
    + * @return  array               Array of head entries
    + */
    +function resource_admin_prepare_head()
    +{
     
     	global $langs, $conf, $user;
     
    @@ -113,5 +129,4 @@ function resource_admin_prepare_head() {
     	complete_head_from_modules($conf,$langs,null,$head,$h,'resource_admin','remove');
     
     	return $head;
    -
     }
    diff --git a/htdocs/core/lib/salaries.lib.php b/htdocs/core/lib/salaries.lib.php
    index eaaa90a710e..0c121c308d3 100644
    --- a/htdocs/core/lib/salaries.lib.php
    +++ b/htdocs/core/lib/salaries.lib.php
    @@ -20,14 +20,15 @@
     /**
      * Returns an array with the tabs for the "salaries" section
      * It loads tabs from modules looking for the entity salaries
    - *  
    + *
      * @param Paiement $object Current salaries object
      * @return array Tabs for the salaries section
      */
    -function salaries_prepare_head($object) {
    -	
    +function salaries_prepare_head($object)
    +{
    +
     	global $db, $langs, $conf;
    -	
    +
     	$h = 0;
     	$head = array();
     
    @@ -57,7 +58,7 @@ function salaries_prepare_head($object) {
     	$head[$h][1] = $langs->trans("Info");
     	$head[$h][2] = 'info';
     	$h++;
    -    
    +
     	complete_head_from_modules($conf,$langs,$object,$head,$h,'salaries', 'remove');
     
     	return $head;
    diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php
    index 9fa5fb8b7c3..235421a598e 100644
    --- a/htdocs/core/lib/security.lib.php
    +++ b/htdocs/core/lib/security.lib.php
    @@ -174,11 +174,10 @@ function dol_verifyHash($chain, $hash, $type='0')
      *	@param  string	$feature2		Feature to check, second level of permission (optional). Can be a 'or' check with 'level1|level2'.
      *  @param  string	$dbt_keyfield   Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional)
      *  @param  string	$dbt_select     Field name for select if not rowid. Not used if objectid is null (optional)
    - *  @param	Canvas	$objcanvas		Object canvas
      * 	@return	int						Always 1, die process if not allowed
      *  @see dol_check_secure_access_document
      */
    -function restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $objcanvas=null)
    +function restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
     {
     	global $db, $conf;
     	global $hookmanager;
    @@ -663,6 +662,7 @@ function accessforbidden($message='',$printheader=1,$printfooter=1,$showonlymess
         {
             include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php';
             $langs=new Translate('',$conf);
    +        $langs->setDefaultLang();
         }
     
         $langs->load("errors");
    diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php
    index b6a348ea91d..c9f4ece6445 100644
    --- a/htdocs/core/lib/security2.lib.php
    +++ b/htdocs/core/lib/security2.lib.php
    @@ -103,12 +103,12 @@ function checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmod
         			}
         			else
         			{
    -    				dol_syslog("Authentification ko - failed to load file '".$authfile."'",LOG_ERR);
    +    				dol_syslog("Authentification ko - failed to load file '".$authfile."'", LOG_ERR);
         				sleep(1);
    -    				$langs->load('main');
    -    				$langs->load('other');
    -    				$langs->load('errors');
    -    				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode);
    +    				// Load translation files required by the page
    +                    $langs->loadLangs(array('other', 'main', 'errors'));
    +
    +    				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode", $mode);
         			}
         		}
         	}
    @@ -118,18 +118,18 @@ function checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmod
     }
     
     
    -/**
    - * Show Dolibarr default login page.
    - * Part of this code is also duplicated into main.inc.php::top_htmlhead
    - *
    - * @param		Translate	$langs		Lang object (must be initialized by a new).
    - * @param		Conf		$conf		Conf object
    - * @param		Societe		$mysoc		Company object
    - * @return		void
    - */
     if (! function_exists('dol_loginfunction'))
     {
    -	function dol_loginfunction($langs,$conf,$mysoc)
    +    /**
    +     * Show Dolibarr default login page.
    +     * Part of this code is also duplicated into main.inc.php::top_htmlhead
    +     *
    +     * @param       Translate   $langs      Lang object (must be initialized by a new).
    +     * @param       Conf        $conf       Conf object
    +     * @param       Societe     $mysoc      Company object
    +     * @return      void
    +     */
    +    function dol_loginfunction($langs,$conf,$mysoc)
     	{
     		global $dolibarr_main_demo,$db;
     		global $smartphone,$hookmanager;
    @@ -228,11 +228,11 @@ if (! function_exists('dol_loginfunction'))
     
     		if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small))
     		{
    -			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('thumbs/'.$mysoc->logo_small);
    +			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
     		}
     		elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo))
     		{
    -			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode($mysoc->logo);
    +			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/'.$mysoc->logo);
     			$width=128;
     		}
     		elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'))
    @@ -510,4 +510,3 @@ function getRandomPassword($generic=false)
     
     	return $generated_password;
     }
    -
    diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php
    index b79b1d094da..38660cc272a 100644
    --- a/htdocs/core/lib/sendings.lib.php
    +++ b/htdocs/core/lib/sendings.lib.php
    @@ -36,8 +36,8 @@ function shipping_prepare_head($object)
     {
     	global $db, $langs, $conf, $user;
     
    -	$langs->load("sendings");
    -	$langs->load("deliveries");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array("sendings","deliveries"));
     
     	$h = 0;
     	$head = array();
    @@ -121,8 +121,8 @@ function delivery_prepare_head($object)
     {
     	global $langs, $conf, $user;
     
    -	$langs->load("sendings");
    -	$langs->load("deliveries");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array("sendings","deliveries"));
     
     	$h = 0;
     	$head = array();
    diff --git a/htdocs/core/lib/signature.lib.php b/htdocs/core/lib/signature.lib.php
    index b11d809caf2..2790c80c8e0 100644
    --- a/htdocs/core/lib/signature.lib.php
    +++ b/htdocs/core/lib/signature.lib.php
    @@ -28,8 +28,9 @@ function showOnlineSignatureUrl($type,$ref)
     {
     	global $conf, $langs;
     
    -	$langs->load("payment");
    -	$langs->load("paybox");
    +	// Load translation files required by the page
    +    $langs->loadLangs(array("payment","paybox"));
    +
     	$servicename='Online';
     
     	$out = img_picto('','object_globe.png').' '.$langs->trans("ToOfferALinkForOnlineSignature",$servicename).'<br>';
    diff --git a/htdocs/core/lib/stock.lib.php b/htdocs/core/lib/stock.lib.php
    index ac59ab230c7..579944117ab 100644
    --- a/htdocs/core/lib/stock.lib.php
    +++ b/htdocs/core/lib/stock.lib.php
    @@ -39,7 +39,7 @@ function stock_prepare_head($object)
     	$head[$h][2] = 'card';
     	$h++;
     
    -	$head[$h][0] = DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$object->id;
    +	$head[$h][0] = DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$object->id;
     	$head[$h][1] = $langs->trans("StockMovements");
     	$head[$h][2] = 'movements';
     	$h++;
    diff --git a/htdocs/core/lib/supplier_proposal.lib.php b/htdocs/core/lib/supplier_proposal.lib.php
    index 1756c92a32a..a0f52d6de15 100644
    --- a/htdocs/core/lib/supplier_proposal.lib.php
    +++ b/htdocs/core/lib/supplier_proposal.lib.php
    @@ -32,8 +32,9 @@
     function supplier_proposal_prepare_head($object)
     {
     	global $db, $langs, $conf, $user;
    -	$langs->load("supplier_proposal");
    -	$langs->load("compta");
    +
    +	// Load translation files required by the page
    +    $langs->loadLangs(array("supplier_proposal","compta"));
     
     	$h = 0;
     	$head = array();
    diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php
    index 7fac65ab42b..e6ce5c1bddd 100644
    --- a/htdocs/core/lib/ticket.lib.php
    +++ b/htdocs/core/lib/ticket.lib.php
    @@ -105,6 +105,11 @@ function ticket_prepare_head($object)
         // History
         $head[$h][0] = DOL_URL_ROOT.'/ticket/history.php?track_id=' . $object->track_id;
         $head[$h][1] = $langs->trans('Events');
    +    if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) ))
    +    {
    +    	$head[$h][1].= '/';
    +    	$head[$h][1].= $langs->trans("Agenda");
    +    }
         $head[$h][2] = 'tabTicketLogs';
         $h++;
     
    @@ -155,9 +160,9 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $
         	$urllogo = DOL_URL_ROOT . '/theme/login_logo.png';
     
         	if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output . '/logos/thumbs/' . $mysoc->logo_small)) {
    -    		$urllogo = DOL_URL_ROOT . '/viewimage.php?cache=1&amp;modulepart=companylogo&amp;file=' . urlencode('thumbs/' . $mysoc->logo_small);
    +    		$urllogo = DOL_URL_ROOT . '/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file=' . urlencode('logos/thumbs/'.$mysoc->logo_small);
         	} elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output . '/logos/' . $mysoc->logo)) {
    -    		$urllogo = DOL_URL_ROOT . '/viewimage.php?cache=1&amp;modulepart=companylogo&amp;file=' . urlencode($mysoc->logo);
    +    		$urllogo = DOL_URL_ROOT . '/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file=' . urlencode('logos/'.$mysoc->logo);
         		$width = 128;
         	} elseif (is_readable(DOL_DOCUMENT_ROOT . '/theme/dolibarr_logo.png')) {
         		$urllogo = DOL_URL_ROOT . '/theme/dolibarr_logo.png';
    @@ -170,20 +175,3 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $
     
         print '<div style="margin-left: 50px; margin-right: 50px;">';
     }
    -
    -/**
    - * Show footer for new member
    - *
    - * @return void
    - */
    -function llxFooterTicket()
    -{
    -    print '</div>';
    -
    -    printCommonFooter('public');
    -
    -    dol_htmloutput_events();
    -
    -    print "</body>\n";
    -    print "</html>\n";
    -}
    diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php
    index 2cbba69d256..ae469b89552 100644
    --- a/htdocs/core/lib/usergroups.lib.php
    +++ b/htdocs/core/lib/usergroups.lib.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2006-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2010-2017	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2015	    Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Ferran Marcet       <fmarcet@2byte.es>
      *
      * 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
    @@ -322,6 +323,10 @@ function show_theme($fuser,$edit=0,$foruserprofile=false)
     	if (empty($foruserprofile)) $hoverdisabled=(isset($conf->global->THEME_ELDY_USE_HOVER) && $conf->global->THEME_ELDY_USE_HOVER == '0');
     	else $hoverdisabled=(is_object($fuser)?(empty($fuser->conf->THEME_ELDY_USE_HOVER) || $fuser->conf->THEME_ELDY_USE_HOVER == '0'):'');
     
    +	$checkeddisabled='';
    +	if (empty($foruserprofile)) $checkeddisabled=(isset($conf->global->THEME_ELDY_USE_CHECKED) && $conf->global->THEME_ELDY_USE_CHECKED == '0');
    +	else $checkeddisabled=(is_object($fuser)?(empty($fuser->conf->THEME_ELDY_USE_CHECKED) || $fuser->conf->THEME_ELDY_USE_CHECKED == '0'):'');
    +
     	$colspan=2;
     	if ($foruserprofile) $colspan=4;
     
    @@ -809,8 +814,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false)
     	     print '</tr>';
     	     */
     	}
    -	else
    -	{
    +	else {
     		print '<tr class="oddeven">';
     		print '<td>'.$langs->trans("HighlightLinesColor").'</td>';
     		print '<td colspan="'.($colspan-1).'">';
    @@ -837,6 +841,50 @@ function show_theme($fuser,$edit=0,$foruserprofile=false)
     		print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis"));
     		print '</span>';
     		print '</td>';
    +	}
    +
    +	// Use Checked
    +	if ($foruserprofile)
    +	{
    +		/* Must first change option to choose color of highlight instead of yes or no.
    +	     print '<tr class="oddeven">';
    +	     print '<td>'.$langs->trans("HighlightLinesOnMouseHover").'</td>';
    +	     print '<td><input '.$bc[$var].' name="check_THEME_ELDY_USE_HOVER" disabled="disabled" type="checkbox" '.($conf->global->THEME_ELDY_USE_HOVER?" checked":"").'></td>';
    +	     print '<td align="left" class="nowrap" width="20%"><input '.$bc[$var].' name="check_MAIN_THEME"'.($edit?'':' disabled').' type="checkbox" '.($selected_theme?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>';
    +	     print '<td><input '.$bc[$var].' name="check_THEME_ELDY_USE_HOVER"'.($edit?'':' disabled="disabled"').' type="checkbox" '.($hoverdisabled?"":" checked").'>';
    +	     print ' &nbsp; ('.$langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis").')';
    +	     print '</td>';
    +	     print '</tr>';
    +	     */
    +	}
    +	else
    +	{
    +		print '<tr class="oddeven">';
    +		print '<td>'.$langs->trans("HighlightLinesChecked").'</td>';
    +		print '<td colspan="'.($colspan-1).'">';
    +		//print '<input '.$bc[$var].' name="check_THEME_ELDY_USE_HOVER"'.($edit?'':' disabled').' type="checkbox" '.($hoverdisabled?"":" checked").'>';
    +		//print ' &nbsp; ('.$langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis").')';
    +		if ($edit)
    +		{
    +			if ($conf->global->THEME_ELDY_USE_CHECKED == '1') $color='ffefbb';
    +			else $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_USE_CHECKED,array()),'');
    +			print $formother->selectColor($color,'THEME_ELDY_USE_CHECKED','formcolor',1).' ';
    +		}
    +		else
    +		{
    +			if ($conf->global->THEME_ELDY_USE_CHECKED == '1') $color='ffefbb';
    +			else $color = colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_USE_CHECKED,array()),'');
    +			if ($color)
    +			{
    +				if ($color != 'ffefbb') print '<input type="text" class="colorthumb" disabled="disabled" style="padding: 1px; margin-top: 0; margin-bottom: 0; background-color: #'.$color.'" value="'.$color.'">';
    +				else print $langs->trans("Default");
    +			}
    +			else print $langs->trans("None");
    +		}
    +		print ' &nbsp; <span class="nowraponall">('.$langs->trans("Default").': <strong>ffefbb</strong>) ';
    +		print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis"));
    +		print '</span>';
    +		print '</td>';
     		print '</tr>';
     	}
     
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index 4ca0812c9ee..350014b3eb9 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -31,6 +31,7 @@
      * @param	string		$content			Content to replace
      * @param	int			$removephppart		0=Replace PHP sections with a PHP badge. 1=Remove completely PHP sections.
      * @return	boolean							True if OK
    + * @see dolWebsiteOutput for function used to replace content in a web server context
      */
     function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0)
     {
    @@ -39,6 +40,23 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0)
     	if ($removephppart) $replacewith='';
     	$content = preg_replace('/value="<\?php((?!\?>).)*\?>\n*/ims', 'value="'.$replacewith.'"', $content);
     
    +	$replacewith='"callto=#';
    +	if ($removephppart) $replacewith='';
    +	$content = preg_replace('/"callto:<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
    +
    +	$replacewith='"mailto=#';
    +	if ($removephppart) $replacewith='';
    +	$content = preg_replace('/"mailto:<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
    +
    +	$replacewith='src="php';
    +	if ($removephppart) $replacewith='';
    +	$content = preg_replace('/src="<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
    +
    +	$replacewith='href="php';
    +	if ($removephppart) $replacewith='';
    +	$content = preg_replace('/href="<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
    +
    +	//$replacewith='<span class="phptag">...php...</span>';
     	$replacewith='<span class="phptag">...php...</span>';
     	if ($removephppart) $replacewith='';
     	$content = preg_replace('/<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content);
    @@ -48,10 +66,16 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0)
     	// Replace relative link /xxx.php with dolibarr URL
     	$content = preg_replace('/(href=")\/?([^:\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep);
     
    +	// Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/
     	$content = preg_replace('/url\((["\']?)medias\//', 'url(\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +	$content = preg_replace('/data-slide-bg=(["\']?)medias\//', 'data-slide-bg=\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
     
    +	// <img src="medias/image.png... => <img src="dolibarr/viewimage.php/modulepart=medias&file=image.png...
    +	$content = preg_replace('/(<img[^>]*src=")(medias\/)/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
     	// <img src="image.png... => <img src="dolibarr/viewimage.php/modulepart=medias&file=image.png...
    -	$content = preg_replace('/(<img[^>]*src=")(?!(http|'.preg_quote(DOL_URL_ROOT,'/').'\/viewimage))/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +	$content = preg_replace('/(<img[^>]*src=")(?!(http|\/?viewimage|'.preg_quote(DOL_URL_ROOT,'/').'\/viewimage))/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +	// <img src="viewimage.php/modulepart=medias&file=image.png" => <img src="dolibarr/viewimage.php/modulepart=medias&file=image.png"
    +	$content = preg_replace('/(<img[^>]*src=")(\/?viewimage\.php)/', '\1'.DOL_URL_ROOT.'/viewimage.php', $content, -1, $nbrep);
     
     	// action="newpage.php" => action="dolibarr/website/index.php?website=...&pageref=newpage
     	$content = preg_replace('/(action=")\/?([^:\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep);
    @@ -70,23 +94,28 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0)
      *
      * @param   string  $content    Content string
      * @return  void
    - * @see	dolWebsiteSaveContent
    + * @see	dolWebsiteReplacementOfLinks  for function used to replace content in the backoffice context when USEDOLIBARREDITOR is not on
      */
     function dolWebsiteOutput($content)
     {
     	global $db, $langs, $conf, $user;
     	global $dolibarr_main_url_root, $dolibarr_main_data_root;
     
    -	dol_syslog("dolWebsiteOutput start (mode=".(defined('USEDOLIBARRSERVER')?'USEDOLIBARRSERVER':'').')');
    +	dol_syslog("dolWebsiteOutput start (USEDOLIBARRSERVER=".(defined('USEDOLIBARRSERVER')?'1':'')." (USEDOLIBARREDITOR=".(defined('USEDOLIBARREDITOR')?'1':'').')');
     
     	// Define $urlwithroot
     	$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
     	$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
     	//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
     
    -	// Note: This seems never called when page is output inside the website editor (search 'REPLACEMENT OF LINKS When page called by website editor')
    -
    -	if (defined('USEDOLIBARRSERVER'))	// REPLACEMENT OF LINKS When page called from Dolibarr server
    +	if (defined('USEDOLIBARREDITOR'))		// REPLACEMENT OF LINKS When page called from Dolibarr editor
    +	{
    +		// We remove the <head> part of content
    +		$content = preg_replace('/<head>.*<\/head>/ims', '', $content);
    +		$content = preg_replace('/^.*<body(\s[^>]*)*>/ims', '', $content);
    +		$content = preg_replace('/<\/body(\s[^>]*)*>.*$/ims', '', $content);
    +	}
    +	elseif (defined('USEDOLIBARRSERVER'))	// REPLACEMENT OF LINKS When page called from Dolibarr server
     	{
     		global $website;
     
    @@ -98,20 +127,29 @@ function dolWebsiteOutput($content)
     		$content=preg_replace('/(href=")\/?([a-zA-Z0-9\-]+)(\")/', '\1'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2\3', $content, -1, $nbrep);
     		$content=preg_replace('/(href=")\/?([a-zA-Z0-9\-]+)(\?)/', '\1'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2\3', $content, -1, $nbrep);
     
    -		// Fix relative link /document.php with correct URL after the DOL_URL_ROOT:  ...href="/document.php?modulepart="
    +		// Fix relative link /document.php with correct URL after the DOL_URL_ROOT:  href="/document.php?modulepart=" => href="/dolibarr/document.php?modulepart="
     		$content=preg_replace('/(href=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
     		$content=preg_replace('/(src=")(\/?document\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
     
    -		// Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT:  ...href="/viewimage.php?modulepart="
    +		// Fix relative link /viewimage.php with correct URL after the DOL_URL_ROOT: href="/viewimage.php?modulepart=" => href="/dolibarr/viewimage.php?modulepart="
     		$content=preg_replace('/(href=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
    +		$content=preg_replace('/(src=")(\/?viewimage\.php\?[^\"]*modulepart=[^\"]*)(\")/', '\1'.DOL_URL_ROOT.'\2\3', $content, -1, $nbrep);
     
     		// Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/
     		$content=preg_replace('/url\((["\']?)medias\//', 'url(\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +		$content=preg_replace('/data-slide-bg=(["\']?)medias\//', 'data-slide-bg=\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +
    +		// <img src="medias/image.png... => <img src="dolibarr/viewimage.php/modulepart=medias&file=image.png...
    +		$content = preg_replace('/(<img[^>]*src=")(medias\/)/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +		// <img src="image.png... => <img src="dolibarr/viewimage.php/modulepart=medias&file=image.png...
    +		$content = preg_replace('/(<img[^>]*src=")(?!(http|\/?viewimage|'.preg_quote(DOL_URL_ROOT,'/').'\/viewimage))/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep);
    +		// <img src="viewimage.php/modulepart=medias&file=image.png" => <img src="dolibarr/viewimage.php/modulepart=medias&file=image.png"
    +		$content = preg_replace('/(<img[^>]*src=")(\/?viewimage\.php)/', '\1'.DOL_URL_ROOT.'/viewimage.php', $content, -1, $nbrep);
     
     		// action="newpage.php" => action="dolibarr/website/index.php?website=...&pageref=newpage
     		$content = preg_replace('/(action=")\/?([^:\"]*)(\.php\")/', '\1'.DOL_URL_ROOT.'/public/website/index.php?website='.$website->ref.'&pageref=\2"', $content, -1, $nbrep);
     	}
    -	else								// REPLACEMENT OF LINKS When page called from virtual host
    +	else									// REPLACEMENT OF LINKS When page called from virtual host
     	{
     		$symlinktomediaexists=1;
     
    @@ -122,9 +160,13 @@ function dolWebsiteOutput($content)
     		$nbrep=0;
     		if (! $symlinktomediaexists)
     		{
    -			$content=preg_replace('/(<a[^>]*href=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    -			$content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    -			$content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/',  '\1'.$urlwithroot.'/viewimage.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    +			$content=preg_replace('/(<script[^>]*src=")[^\"]*document\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\wrapper.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    +
    +			$content=preg_replace('/(<a[^>]*href=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\1/wrapper.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    +			$content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\1/wrapper.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    +			$content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/',  '\1/wrapper.php\2modulepart=medias\3file=\4\5', $content, -1, $nbrep);
    +
    +			$content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=mycompany([^\"]*)file=([^\"]*)("[^>]*>)/', '\1/wrapper.php\2modulepart=mycompany\3file=\4\5', $content, -1, $nbrep);
     		}
     		else
     		{
    @@ -133,6 +175,8 @@ function dolWebsiteOutput($content)
     			$content=preg_replace('/(<a[^>]*href=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\1medias/\4\5', $content, -1, $nbrep);
     			$content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=medias([^\"]*)file=([^\"]*)("[^>]*>)/', '\1medias/\4\5', $content, -1, $nbrep);
     			$content=preg_replace('/(url\(["\']?)[^\)]*viewimage\.php([^\)]*)modulepart=medias([^\)]*)file=([^\)]*)(["\']?\))/', '\1medias/\4\5', $content, -1, $nbrep);
    +
    +			$content=preg_replace('/(<img[^>]*src=")[^\"]*viewimage\.php([^\"]*)modulepart=mycompany([^\"]*)file=([^\"]*)("[^>]*>)/', '\1/wrapper.php\2modulepart=mycompany\3file=\4\5', $content, -1, $nbrep);
     		}
     	}
     
    @@ -261,9 +305,9 @@ function redirectToContainer($containerref, $containeraliasalt='',$containerid=0
      */
     function includeContainer($containerref)
     {
    -	global $conf, $db, $langs, $mysoc, $user, $website;
    +	global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs;	// Very important. Required to have var available when running inluded containers.
     	global $includehtmlcontentopened;
    -	global $websitekey;
    +	global $websitekey, $websitepagefile;
     
     	$MAXLEVEL=20;
     
    @@ -486,6 +530,31 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify
     
     
     
    +/**
    + * Save content of a page on disk
    + *
    + * @param	string		$filemaster			Full path of filename master.inc.php for website to generate
    + * @return	boolean							True if OK
    + */
    +function dolSaveMasterFile($filemaster)
    +{
    +	global $conf;
    +
    +	// Now generate the master.inc.php page
    +	dol_syslog("We regenerate the master file");
    +	dol_delete_file($filemaster);
    +
    +	$mastercontent = '<?php'."\n";
    +	$mastercontent.= '// File generated to link to the master file - DO NOT MODIFY - It is just an include'."\n";
    +	$mastercontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n";
    +	$mastercontent.= '?>'."\n";
    +	$result = file_put_contents($filemaster, $mastercontent);
    +	if (! empty($conf->global->MAIN_UMASK))
    +		@chmod($filemaster, octdec($conf->global->MAIN_UMASK));
    +
    +	return $result;
    +}
    +
     /**
      * Save content of a page on disk
      *
    @@ -508,10 +577,11 @@ function dolSavePageAlias($filealias, $object, $objectpage)
     	$aliascontent.= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n";
     	$aliascontent.= '?>'."\n";
     	$result = file_put_contents($filealias, $aliascontent);
    -	if (! empty($conf->global->MAIN_UMASK))
    -		@chmod($filealias, octdec($conf->global->MAIN_UMASK));
    +	if (! empty($conf->global->MAIN_UMASK)) {
    +        @chmod($filealias, octdec($conf->global->MAIN_UMASK));
    +    }
     
    -		return ($result?true:false);
    +	return ($result?true:false);
     }
     
     
    @@ -537,8 +607,8 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     
     	$tplcontent ='';
     	$tplcontent.= "<?php // BEGIN PHP\n";
    -	$tplcontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -	$tplcontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n";
    +	$tplcontent.= '$websitekey=basename(dirname(__FILE__)); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
    +	$tplcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Not already loaded"."\n";
     	$tplcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     	$tplcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
     	$tplcontent.= "ob_start();\n";
    @@ -554,10 +624,11 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     	$tplcontent.= '<meta name="title" content="'.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="description" content="'.dol_string_nohtmltag($objectpage->description, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.' '.DOL_VERSION.' (https://www.dolibarr.org)" />'."\n";
    +	$tplcontent.= '<link href="/'.(($objectpage->id == $object->fk_default_home) ? '' : ($objectpage->pageurl.'.php')).'" rel="canonical" />'."\n";
     	$tplcontent.= '<!-- Include link to CSS file -->'."\n";
    -	$tplcontent.= '<link rel="stylesheet" href="styles.css.php?websiteid='.$object->id.'" type="text/css" />'."\n";
    +	$tplcontent.= '<link rel="stylesheet" href="styles.css.php?website=<?php echo $websitekey; ?>" type="text/css" />'."\n";
     	$tplcontent.= '<!-- Include HTML header from common file -->'."\n";
    -	$tplcontent.= '<?php print preg_replace(\'/<\/?html>/ims\', \'\', file_get_contents(DOL_DATA_ROOT."/website/'.$object->ref.'/htmlheader.html")); ?>'."\n";
    +	$tplcontent.= '<?php print preg_replace(\'/<\/?html>/ims\', \'\', file_get_contents(DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html")); ?>'."\n";
     	$tplcontent.= '<!-- Include HTML header from page header block -->'."\n";
     	$tplcontent.= preg_replace('/<\/?html>/ims', '', $objectpage->htmlheader)."\n";
     	$tplcontent.= '</head>'."\n";
    @@ -582,26 +653,28 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     
     
     /**
    - * Save content of the index.php page
    + * Save content of the index.php and wrapper.php page
      *
      * @param	string		$pathofwebsite			Path of website root
      * @param	string		$fileindex				Full path of file index.php
      * @param	string		$filetpl				File tpl to index.php page redirect to
    + * @param	string		$filewrapper			Full path of file wrapper.php
      * @return	boolean								True if OK
      */
    -function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl)
    +function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
     {
     	global $conf;
     
    -	$result=0;
    +	$result1=false;
    +	$result2=false;
     
     	dol_mkdir($pathofwebsite);
    -	dol_delete_file($fileindex);
     
    +	dol_delete_file($fileindex);
     	$indexcontent = '<?php'."\n";
     	$indexcontent.= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
    -	$indexcontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -	$indexcontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
    +	$indexcontent.= '$websitekey=basename(dirname(__FILE__)); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
    +	$indexcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
     	$indexcontent.= 'if (! empty($_GET[\'pageref\']) || ! empty($_GET[\'pagealiasalt\']) || ! empty($_GET[\'pageid\'])) {'."\n";
     	$indexcontent.= "	require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     	$indexcontent.= "	require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
    @@ -609,11 +682,25 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl)
     	$indexcontent.= "}\n";
     	$indexcontent.= "include_once './".basename($filetpl)."'\n";
     	$indexcontent.= '// END PHP ?>'."\n";
    -	$result = file_put_contents($fileindex, $indexcontent);
    +	$result1 = file_put_contents($fileindex, $indexcontent);
     	if (! empty($conf->global->MAIN_UMASK))
     		@chmod($fileindex, octdec($conf->global->MAIN_UMASK));
     
    -	return $result;
    +	dol_delete_file($filewrapper);
    +	$wrappercontent = '<?php'."\n";
    +	$wrappercontent.= "// BEGIN PHP File generated to provide a wrapper.php - DO NOT MODIFY - It is just a generated wrapper.\n";
    +	$wrappercontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    +	$wrappercontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
    +	$wrappercontent.= '$original_file=str_replace("../","/", GETPOST("file","alpha"));'."\n";
    +	$wrappercontent.= 'if ($_GET["modulepart"] == "mycompany" && preg_match(\'/^\/?logos\//\', $original_file)) readfile(dol_osencode($conf->mycompany->dir_output."/".$original_file));'."\n";
    +	$wrappercontent.= "else print 'Bad value for modulepart or file';\n";
    +	$wrappercontent.= 'if (is_object($db)) $db->close();'."\n";
    +	$wrappercontent.= '// END PHP ?>'."\n";
    +	$result2 = file_put_contents($filewrapper, $wrappercontent);
    +	if (! empty($conf->global->MAIN_UMASK))
    +		@chmod($filewrapper, octdec($conf->global->MAIN_UMASK));
    +
    +	return ($result1 && $result2);
     }
     
     
    @@ -751,5 +838,3 @@ function dolSaveHtaccessFile($filehtaccess, $htaccess)
     
     		return true;
     }
    -
    -
    diff --git a/htdocs/core/lib/xcal.lib.php b/htdocs/core/lib/xcal.lib.php
    index b0a30697413..10d68475c97 100644
    --- a/htdocs/core/lib/xcal.lib.php
    +++ b/htdocs/core/lib/xcal.lib.php
    @@ -64,7 +64,7 @@ function build_calfile($format,$title,$desc,$events_array,$outputfile)
             && $conf->global->MAIN_AGENDA_EXPORT_CACHE > 60){
     	        $hh=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE,'hour');
     	        $mm=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE,'min');
    -	        $ss=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE,'sec'); 
    +	        $ss=convertSecondToTime($conf->global->MAIN_AGENDA_EXPORT_CACHE,'sec');
     	        fwrite($calfileh,"X-PUBLISHED-TTL: P".$hh."H".$mm."M".$ss."S\n");
             }
     
    @@ -263,7 +263,6 @@ function build_calfile($format,$title,$desc,$events_array,$outputfile)
     				$comment ['enddate']		= $enddate;
     				fwrite($calfileh,"COMMENT:" . serialize ($comment) . "\n");
     				*/
    -
     			}
     		}
     
    @@ -520,4 +519,3 @@ function quotedPrintDecode($str)
     	$out = quoted_printable_decode($out);	// Available with PHP 4+
     	return trim($out);
     }
    -
    diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php
    index 25d5f2dc30c..25cc45c2b6c 100644
    --- a/htdocs/core/login/functions_dolibarr.php
    +++ b/htdocs/core/login/functions_dolibarr.php
    @@ -111,8 +111,10 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=
     				{
     					dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko bad password for '".$usertotest."'");
     					sleep(2);      // Anti brut force protection
    -					$langs->load('main');
    -					$langs->load('errors');
    +
    +					// Load translation files required by the page
    +                    $langs->loadLangs(array('main', 'errors'));
    +
     					$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
     				}
     
    @@ -137,8 +139,10 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest=
     			{
     				dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ko user not found for '".$usertotest."'");
     				sleep(1);
    -				$langs->load('main');
    -				$langs->load('errors');
    +
    +				// Load translation files required by the page
    +                $langs->loadLangs(array('main', 'errors'));
    +
     				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
     			}
     		}
    diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php
    index d468c882b2d..4587dbae11b 100644
    --- a/htdocs/core/login/functions_ldap.php
    +++ b/htdocs/core/login/functions_ldap.php
    @@ -54,8 +54,10 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
     	{
     		dol_syslog("functions_ldap::check_user_password_ldap Authentification ko failed to connect to LDAP. LDAP functions are disabled on this PHP");
     		sleep(1);
    -		$langs->load('main');
    -		$langs->load('other');
    +
    +		// Load translation files required by the page
    +        $langs->loadLangs(array('main', 'other'));
    +
     		$_SESSION["dol_loginmesg"]=$langs->trans("ErrorLDAPFunctionsAreDisabledOnThisPHP").' '.$langs->trans("TryAnotherConnectionMode");
     		return;
     	}
    @@ -201,14 +203,15 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
     					}
     					unset($usertmp);
     				}
    -
     			}
     			if ($result == 1)
     			{
     				dol_syslog("functions_ldap::check_user_password_ldap Authentification ko bad user/password for '".$usertotest."'");
     				sleep(1);
    -				$langs->load('main');
    -				$langs->load('other');
    +
    +				// Load translation files required by the page
    +                $langs->loadLangs(array('main', 'other'));
    +
     				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
     			}
     		}
    @@ -230,9 +233,10 @@ function check_user_password_ldap($usertotest,$passwordtotest,$entitytotest)
     				dol_syslog("functions_ldap::check_user_password_ldap ".$ldap->ldapErrorCode." ".$ldap->ldapErrorText);
     			}
     			sleep(2);      // Anti brut force protection
    -			$langs->load('main');
    -			$langs->load('other');
    -			$langs->load('errors');
    +
    +			// Load translation files required by the page
    +            $langs->loadLangs(array('main', 'other', 'errors'));
    +;
     			$_SESSION["dol_loginmesg"]=($ldap->error?$ldap->error:$langs->trans("ErrorBadLoginPassword"));
     		}
     
    diff --git a/htdocs/core/login/functions_openid.php b/htdocs/core/login/functions_openid.php
    index 83543c43dd5..79cf1a09cb9 100644
    --- a/htdocs/core/login/functions_openid.php
    +++ b/htdocs/core/login/functions_openid.php
    @@ -70,7 +70,7 @@ function check_user_password_openid($usertotest,$passwordtotest,$entitytotest)
             $openid = new SimpleOpenID();
             $openid->SetIdentity($_GET['openid_identity']);
             $openid_validation_result = $openid->ValidateWithServer();
    -        if ($openid_validation_result == true)
    +        if ($openid_validation_result === true)
             {
                 // OK HERE KEY IS VALID
     
    @@ -90,7 +90,7 @@ function check_user_password_openid($usertotest,$passwordtotest,$entitytotest)
                     }
                 }
             }
    -        else if($openid->IsError() == true)
    +        else if($openid->IsError() === true)
             {
                 // ON THE WAY, WE GOT SOME ERROR
                 $error = $openid->GetError();
    diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql
    index c8d2692c2f5..682746b3412 100644
    --- a/htdocs/core/menus/init_menu_auguria.sql
    +++ b/htdocs/core/menus/init_menu_auguria.sql
    @@ -120,7 +120,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3100__+MAX_llx_menu__, 'products', 'stock', 3__+MAX_llx_menu__, '/product/stock/index.php?leftmenu=stock', 'Stock', 0, 'stocks', '$user->rights->stock->lire', '', 2, 3, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3101__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/card.php?action=create', 'MenuNewWarehouse', 1, 'stocks', '$user->rights->stock->creer', '', 2, 0, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3102__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/list.php', 'List', 1, 'stocks', '$user->rights->stock->lire', '', 2, 1, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/mouvement.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/movement_list.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled && $conf->supplier_order->enabled', __HANDLER__, 'left', 3105__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/replenish.php', 'Replenishments', 1, 'stocks', '$user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire', '', 2, 4, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3106__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/massstockmove.php', 'MassStockTransferShort', 1, 'stocks', '$user->rights->stock->mouvement->creer', '', 2, 5, __ENTITY__);
     
    @@ -222,9 +222,9 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2303__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/index.php?leftmenu=tax_vat', 'ReportByMonth', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 2, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2304__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/clients.php?leftmenu=tax_vat', 'ReportByCustomers', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 3, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2305__+MAX_llx_menu__, 'billing', '', 2300__+MAX_llx_menu__, '/compta/tva/quadri_detail.php?leftmenu=tax_vat', 'ReportByQuarter', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 4, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1', __HANDLER__, 'left', 2350__+MAX_llx_menu__, 'billing', 'tax_various', 2200__+MAX_llx_menu__, '/compta/bank/various_payment/index.php?leftmenu=tax_various&amp;mainmenu=billing', 'MenuVariousPayment', 1, 'banks', '$user->rights->banque->lire', '', 0, 1, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $leftmenu=="tax_various"', __HANDLER__, 'left', 2351__+MAX_llx_menu__, 'billing', '', 2350__+MAX_llx_menu__, '/compta/bank/various_payment/card.php?leftmenu=tax_various&amp;action=create', 'MenuNewVariousPayment', 2, 'various_payment', '$user->rights->banque->modifier', '', 0, 2, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $leftmenu=="tax_various"', __HANDLER__, 'left', 2352__+MAX_llx_menu__, 'billing', '', 2350__+MAX_llx_menu__, '/compta/bank/various_payment/index.php?leftmenu=tax_various', 'List', 2, 'various_payment', '$user->rights->banque->lire', '', 0, 3, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)', __HANDLER__, 'left', 2350__+MAX_llx_menu__, 'billing', 'tax_various', 2200__+MAX_llx_menu__, '/compta/bank/various_payment/list.php?leftmenu=tax_various&amp;mainmenu=billing', 'MenuVariousPayment', 1, 'banks', '$user->rights->banque->lire', '', 0, 1, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $leftmenu=="tax_various"', __HANDLER__, 'left', 2351__+MAX_llx_menu__, 'billing', '', 2350__+MAX_llx_menu__, '/compta/bank/various_payment/card.php?leftmenu=tax_various&amp;action=create', 'New', 2, 'various_payment', '$user->rights->banque->modifier', '', 0, 2, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->banque->enabled && $leftmenu=="tax_various"', __HANDLER__, 'left', 2352__+MAX_llx_menu__, 'billing', '', 2350__+MAX_llx_menu__, '/compta/bank/various_payment/list.php?leftmenu=tax_various', 'List', 2, 'various_payment', '$user->rights->banque->lire', '', 0, 3, __ENTITY__);
     -- Accounting Expert
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->accounting->enabled', __HANDLER__, 'left', 2400__+MAX_llx_menu__, 'accountancy', 'accountancy', 9__+MAX_llx_menu__, '/accountancy/index.php?leftmenu=accountancy', 'MenuAccountancy', 0, 'accountancy', '! empty($conf->accounting->enabled) || $user->rights->accounting->bind->write || $user->rights->accounting->bind->write || $user->rights->compta->resultat->lire', '', 0, 7, __ENTITY__);
     	-- Setup
    @@ -311,10 +311,12 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 2650__+MAX_llx_menu__, 'accountancy', 'cat', 14__+MAX_llx_menu__, '/categories/index.php?leftmenu=bank&amp;type=5', 'Categories', 0, 'categories', '$user->rights->categorie->lire', '', 2, 4, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->categorie->enabled', __HANDLER__, 'left', 2651__+MAX_llx_menu__, 'accountancy', '', 2650__+MAX_llx_menu__, '/categories/card.php?leftmenu=bank&amp;action=create&amp;type=5', 'NewCategory', 1, 'categories', '$user->rights->categorie->creer', '', 2, 0, __ENTITY__);
     -- Project
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3600__+MAX_llx_menu__, 'project', 'projects', 7__+MAX_llx_menu__, '/projet/index.php?leftmenu=projects', 'Projects', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3601__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/card.php?leftmenu=projects&amp;action=create', 'NewProject', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3600__+MAX_llx_menu__, 'project', 'projects', 7__+MAX_llx_menu__, '/projet/index.php?leftmenu=projects', 'LeadsOrProjects', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3601__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/card.php?leftmenu=projects&amp;action=create', 'New', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3602__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/list.php?leftmenu=projects', 'List', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3603__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/stats/index.php?leftmenu=projects', 'Statistics', 1, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled && $conf->global->PROJECT_USE_OPPORTUNITIES != 0', __HANDLER__, 'left', 3603__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/list.php?leftmenu=projects&search_opp_status=openedopp&search_status=99', 'ListOpenLeads', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled && $conf->global->PROJECT_USE_OPPORTUNITIES != 2', __HANDLER__, 'left', 3604__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/list.php?leftmenu=projects&search_opp_status=notopenedopp&search_status=99', 'ListOpenProjects', 1, 'projects', '$user->rights->projet->lire', '', 2, 2, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled', __HANDLER__, 'left', 3605__+MAX_llx_menu__, 'project', '', 3600__+MAX_llx_menu__, '/projet/stats/index.php?leftmenu=projects', 'Statistics', 1, 'projects', '$user->rights->projet->lire', '', 2, 3, __ENTITY__);
     
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled && !$conf->global->PROJECT_HIDE_TASKS', __HANDLER__, 'left', 3700__+MAX_llx_menu__, 'project', '', 7__+MAX_llx_menu__, '/projet/activity/index.php?leftmenu=projects', 'Activities', 0, 'projects', '$user->rights->projet->lire', '', 2, 0, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->projet->enabled && !$conf->global->PROJECT_HIDE_TASKS', __HANDLER__, 'left', 3701__+MAX_llx_menu__, 'project', '', 3700__+MAX_llx_menu__, '/projet/tasks.php?leftmenu=projects&amp;action=create', 'NewTask', 1, 'projects', '$user->rights->projet->creer', '', 2, 1, __ENTITY__);
    diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php
    index fee6ae6c595..9878d8a2ca8 100644
    --- a/htdocs/core/menus/standard/auguria.lib.php
    +++ b/htdocs/core/menus/standard/auguria.lib.php
    @@ -273,7 +273,7 @@ function print_left_auguria_menu($db,$menu_array_before,$menu_array_after,&$tabM
     		$mysoc->logo_mini=$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI;
     		if (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini))
     		{
    -			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('thumbs/'.$mysoc->logo_mini);
    +			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_mini);
     		}
     		else
     		{
    @@ -517,7 +517,7 @@ function print_left_auguria_menu($db,$menu_array_before,$menu_array_after,&$tabM
     				$tmp=explode('?',$menu_array[$i]['url'],2);
     				$url = $shorturl = $tmp[0];
     				$param = (isset($tmp[1])?$tmp[1]:'');    // params in url of the menu link
    -				
    +
     				// Complete param to force leftmenu to '' to close open menu when we click on a link with no leftmenu defined.
     				if ((! preg_match('/mainmenu/i',$param)) && (! preg_match('/leftmenu/i',$param)) && ! empty($menu_array[$i]['mainmenu']))
     				{
    diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php
    index df31b9c9d8f..33c02ce5f1c 100644
    --- a/htdocs/core/menus/standard/auguria_menu.php
    +++ b/htdocs/core/menus/standard/auguria_menu.php
    @@ -28,7 +28,11 @@
      */
     class MenuManager
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $type_user;								// Put 0 for internal users, 1 for external users
     	var $atarget="";                            // To store default target to use onto links
     	var $name="auguria";
    diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
    index 6325643cf87..bb13a0c2265 100644
    --- a/htdocs/core/menus/standard/eldy.lib.php
    +++ b/htdocs/core/menus/standard/eldy.lib.php
    @@ -95,8 +95,8 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode
     	$showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal);
     	if ($showmode)
     	{
    -		$langs->load("companies");
    -		$langs->load("suppliers");
    +	    // Load translation files required by the page
    +        $langs->loadLangs(array("companies","suppliers"));
     
     		$classname="";
     		if ($_SESSION["mainmenu"] && $_SESSION["mainmenu"] == "companies") { $classname='class="tmenusel"'; $_SESSION['idmenu']=''; }
    @@ -189,8 +189,8 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode
     	$showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal);
     	if ($showmode)
     	{
    -		$langs->load("compta");
    -		$langs->load("banks");
    +	    // Load translation files required by the page
    +        $langs->loadLangs(array("compta","banks"));
     
     		$classname="";
     		if ($_SESSION["mainmenu"] && $_SESSION["mainmenu"] == "bank") { $classname='class="tmenusel"'; $_SESSION['idmenu']=''; }
    @@ -236,7 +236,21 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode
     		else $classname = 'class="tmenu"';
     		$idsel='project';
     
    -		$menu->add('/projet/index.php?mainmenu=project&amp;leftmenu=', $langs->trans("Projects"), 0, $showmode, $atarget, "project", '', 70, $id, $idsel, $classname);
    +		$title = $langs->trans("LeadsOrProjects");	// Leads and opportunities by default
    +		$showmodel = $showmodep = $showmode;
    +		if (empty($conf->global->PROJECT_USE_OPPORTUNITIES))
    +		{
    +			$title = $langs->trans("Projects");
    +			$showmodel = 0;
    +		}
    +		if ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) {
    +			$title = $langs->trans("Leads");
    +			$showmodep = 0;
    +		}
    +
    +		$menu->add('/projet/index.php?mainmenu=project&amp;leftmenu=', $title, 0, $showmode, $atarget, "project", '', 70, $id, $idsel, $classname);
    +		//$menu->add('/projet/index.php?mainmenu=project&amp;leftmenu=&search_opp_status=openedopp', $langs->trans("ListLeads"), 0, $showmodel & $conf->global->PROJECT_USE_OPPORTUNITIES, $atarget, "project", '', 70, $id, $idsel, $classname);
    +		//$menu->add('/projet/index.php?mainmenu=project&amp;leftmenu=&search_opp_status=notopenedopp', $langs->trans("ListProjects"), 0, $showmodep, $atarget, "project", '', 70, $id, $idsel, $classname);
     	}
     
     	// HRM
    @@ -467,7 +481,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     		$mysoc->logo_mini=$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI;
     		if (! empty($mysoc->logo_mini) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_mini))
     		{
    -			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('thumbs/'.$mysoc->logo_mini);
    +			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_mini);
     		}
     		else
     		{
    @@ -526,8 +540,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     
     			if ($usemenuhider || empty($leftmenu) || $leftmenu=="setup")
     			{
    -				$langs->load("admin");
    -				$langs->load("help");
    +			    // Load translation files required by the page
    +                $langs->loadLangs(array("admin","help"));
     
     				$warnpicto='';
     				if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY))
    @@ -563,8 +577,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     			$newmenu->add("/admin/tools/index.php?mainmenu=home&amp;leftmenu=admintools", $langs->trans("AdminTools"), 0, $user->admin, '', $mainmenu, 'admintools', 0, '', '', '', '<i class="fa fa-server fa-fw paddingright"></i>');
     			if ($usemenuhider || empty($leftmenu) || preg_match('/^admintools/',$leftmenu))
     			{
    -				$langs->load("admin");
    -				$langs->load("help");
    +			    // Load translation files required by the page
    +                $langs->loadLangs(array('admin', 'help'));
     
     				$newmenu->add('/admin/system/dolibarr.php?mainmenu=home&amp;leftmenu=admintools_info', $langs->trans('InfoDolibarr'), 1);
     				if ($usemenuhider || empty($leftmenu) || $leftmenu=='admintools_info') $newmenu->add('/admin/system/modules.php?mainmenu=home&amp;leftmenu=admintools_info', $langs->trans('Modules'), 2);
    @@ -612,7 +626,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     					$newmenu->add("/user/group/list.php?leftmenu=users", $langs->trans("ListOfGroups"), 2, (($conf->global->MAIN_USE_ADVANCED_PERMS?$user->rights->user->group_advance->read:$user->rights->user->user->lire) || $user->admin) && !(! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global->MULTICOMPANY_TRANSVERSE_MODE));
     				}
     			}
    -
     		}
     
     
    @@ -670,6 +683,25 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$newmenu->add("/societe/card.php?leftmenu=suppliers&amp;action=create&amp;type=f",$langs->trans("MenuNewSupplier"), 2, $user->rights->societe->creer && ($user->rights->fournisseur->lire || $user->rights->supplier_proposal->lire));
     			}
     
    +			// Categories
    +			if (! empty($conf->categorie->enabled))
    +			{
    +				$langs->load("categories");
    +				if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))
    +				{
    +					// Categories prospects/customers
    +					$menutoshow=$langs->trans("CustomersProspectsCategoriesShort");
    +					if (! empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) $menutoshow=$langs->trans("CustomersCategoriesShort");
    +					if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $menutoshow=$langs->trans("ProspectsCategoriesShort");
    +					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=2", $menutoshow, 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    +				}
    +				// Categories suppliers
    +				if (! empty($conf->fournisseur->enabled))
    +				{
    +					$newmenu->add("/categories/index.php?leftmenu=catfournish&amp;type=1", $langs->trans("SuppliersCategoriesShort"), 1, $user->rights->categorie->lire);
    +				}
    +			}
    +
     			// Contacts
     			$newmenu->add("/societe/index.php?leftmenu=thirdparties", (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")), 0, $user->rights->societe->contact->lire, '', $mainmenu, 'contacts');
     			$newmenu->add("/contact/card.php?leftmenu=contacts&amp;action=create", (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")), 1, $user->rights->societe->contact->creer);
    @@ -684,25 +716,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     			if (! empty($conf->categorie->enabled))
     			{
     				$langs->load("categories");
    -				if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))
    -				{
    -					// Categories prospects/customers
    -				    $menutoshow=$langs->trans("CustomersProspectsCategoriesShort");
    -				    if (! empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) $menutoshow=$langs->trans("CustomersCategoriesShort");
    -				    if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $menutoshow=$langs->trans("ProspectsCategoriesShort");
    -					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=2", $menutoshow, 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    -				    $newmenu->add("/categories/card.php?action=create&amp;type=2", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
    -				}
     				// Categories Contact
    -				$newmenu->add("/categories/index.php?leftmenu=catcontact&amp;type=4", $langs->trans("ContactCategoriesShort"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    -				$newmenu->add("/categories/card.php?action=create&amp;type=4", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
    -				// Categories suppliers
    -				if (! empty($conf->fournisseur->enabled))
    -				{
    -					$newmenu->add("/categories/index.php?leftmenu=catfournish&amp;type=1", $langs->trans("SuppliersCategoriesShort"), 0, $user->rights->categorie->lire);
    -					$newmenu->add("/categories/card.php?action=create&amp;type=1", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
    -				}
    -				//if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
    +				$newmenu->add("/categories/index.php?leftmenu=catcontact&amp;type=4", $langs->trans("ContactCategoriesShort"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
     			}
     		}
     
    @@ -788,10 +803,9 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$newmenu->add("/fichinter/index.php?leftmenu=ficheinter", $langs->trans("Interventions"), 0, $user->rights->ficheinter->lire, '', $mainmenu, 'ficheinter', 2200);
     				$newmenu->add("/fichinter/card.php?action=create&amp;leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer, '', '', '', 201);
     				$newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("List"), 1, $user->rights->ficheinter->lire, '', '', '', 202);
    -
    +				$newmenu->add("/fichinter/card-red.php?leftmenu=ficheinter", $langs->trans("ModelList"), 1, $user->rights->ficheinter->lire, '', '', '', 203);
     				$newmenu->add("/fichinter/stats/index.php?leftmenu=ficheinter", $langs->trans("Statistics"), 1, $user->rights->fournisseur->commande->lire);
     			}
    -
     		}
     
     
    @@ -950,12 +964,12 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				}
     
     				// Various payment
    -				if (! empty($conf->banque->enabled) && $conf->global->MAIN_FEATURES_LEVEL >= 1)
    +				if (! empty($conf->banque->enabled) && empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT))
     				{
     					$langs->load("banks");
    -					$newmenu->add("/compta/bank/various_payment/index.php?leftmenu=tax_various&amp;mainmenu=billing",$langs->trans("MenuVariousPayment"),1,$user->rights->banque->lire, '', $mainmenu, 'tax_various');
    -					if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_various/i',$leftmenu)) $newmenu->add("/compta/bank/various_payment/card.php?leftmenu=tax_various&action=create",$langs->trans("MenuNewVariousPayment"), 2, $user->rights->banque->modifier);
    -					if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_various/i',$leftmenu)) $newmenu->add("/compta/bank/various_payment/index.php?leftmenu=tax_various",$langs->trans("List"),2,$user->rights->banque->lire);
    +					$newmenu->add("/compta/bank/various_payment/list.php?leftmenu=tax_various&amp;mainmenu=billing",$langs->trans("MenuVariousPayment"),1,$user->rights->banque->lire, '', $mainmenu, 'tax_various');
    +					if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_various/i',$leftmenu)) $newmenu->add("/compta/bank/various_payment/card.php?leftmenu=tax_various&action=create",$langs->trans("New"), 2, $user->rights->banque->modifier);
    +					if ($usemenuhider || empty($leftmenu) || preg_match('/^tax_various/i',$leftmenu)) $newmenu->add("/compta/bank/various_payment/list.php?leftmenu=tax_various",$langs->trans("List"),2,$user->rights->banque->lire);
     				}
     			}
     		}
    @@ -1179,10 +1193,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     		 */
     		if ($mainmenu == 'bank')
     		{
    -			$langs->load("withdrawals");
    -			$langs->load("banks");
    -			$langs->load("bills");
    -			$langs->load('categories');
    +		    // Load translation files required by the page
    +            $langs->loadLangs(array("withdrawals","banks","bills","categories"));
     
     			// Bank-Caisse
     			if (! empty($conf->banque->enabled))
    @@ -1199,10 +1211,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     
                 if (! empty($conf->categorie->enabled)) {
                     $langs->load("categories");
    -                $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags');
    -                $newmenu->add("/categories/card.php?action=create&amp;type=5",$langs->trans("NewCategory"),1,$user->rights->categorie->creer);
    -                $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),0,$user->rights->categorie->creer, '', $mainmenu, 'tags');
    -                $newmenu->add("/compta/bank/categ.php",$langs->trans("NewCategory"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
    +                $newmenu->add("/categories/index.php?type=5",$langs->trans("Rubriques"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
    +                $newmenu->add("/compta/bank/categ.php",$langs->trans("RubriquesTransactions"),1,$user->rights->categorie->creer, '', $mainmenu, 'tags');
     	    }
     
     			// Prelevements
    @@ -1230,7 +1240,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				if (preg_match('/checks/',$leftmenu)) $newmenu->add("/compta/paiement/cheque/card.php?leftmenu=checks_bis&amp;action=new&amp;mainmenu=bank",$langs->trans("NewChequeDeposit"),1,$user->rights->banque->cheque);
     				if (preg_match('/checks/',$leftmenu)) $newmenu->add("/compta/paiement/cheque/list.php?leftmenu=checks_bis&amp;mainmenu=bank",$langs->trans("List"),1,$user->rights->banque->cheque);
     			}
    -
     		}
     
     		/*
    @@ -1262,6 +1271,14 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				{
     					$newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=0", $langs->trans("Statistics"), 1, $user->rights->produit->lire && $user->rights->propale->lire);
     				}
    +
    +				// Categories
    +				if (! empty($conf->categorie->enabled))
    +				{
    +					$langs->load("categories");
    +					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    +					//if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
    +				}
     			}
     
     			// Services
    @@ -1274,15 +1291,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				{
     					$newmenu->add("/product/stats/card.php?id=all&leftmenu=stats&type=1", $langs->trans("Statistics"), 1, $user->rights->service->lire && $user->rights->propale->lire);
     				}
    -			}
    -
    -			// Categories
    -			if (! empty($conf->categorie->enabled))
    -			{
    -				$langs->load("categories");
    -				$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=0", $langs->trans("Categories"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    -				$newmenu->add("/categories/card.php?action=create&amp;type=0", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
    -				//if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
    +				// Categories
    +				if (! empty($conf->categorie->enabled))
    +				{
    +					$langs->load("categories");
    +					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=0", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    +					//if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
    +				}
     			}
     
     			// Warehouse
    @@ -1292,7 +1307,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$newmenu->add("/product/stock/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock');
     				$newmenu->add("/product/stock/card.php?action=create", $langs->trans("MenuNewWarehouse"), 1, $user->rights->stock->creer);
     				$newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->rights->stock->lire);
    -				$newmenu->add("/product/stock/mouvement.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire);
    +				$newmenu->add("/product/stock/movement_list.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire);
     
                     $newmenu->add("/product/stock/massstockmove.php", $langs->trans("MassStockTransferShort"), 1, $user->rights->stock->mouvement->creer);
                     if ($conf->supplier_order->enabled) $newmenu->add("/product/stock/replenish.php", $langs->trans("Replenishment"), 1, $user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire);
    @@ -1331,7 +1346,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				if ($usemenuhider || empty($leftmenu) || $leftmenu=="sendings") $newmenu->add("/expedition/list.php?leftmenu=sendings&viewstatut=2", $langs->trans("StatusSendingProcessedShort"), 2, $user->rights->expedition->lire);
     				$newmenu->add("/expedition/stats/index.php?leftmenu=sendings", $langs->trans("Statistics"), 1, $user->rights->expedition->lire);
     			}
    -
     		}
     
     		/*
    @@ -1345,19 +1359,50 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     
     				$search_project_user = GETPOST('search_project_user','int');
     
    -				// Project affected to user
    -				$newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("Projects"), 0, $user->rights->projet->lire, '', $mainmenu, 'projects');
    -				$newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("NewProject"), 1, $user->rights->projet->creer);
    -				$newmenu->add("/projet/list.php?leftmenu=projects".($search_project_user?'&search_project_user='.$search_project_user:'')."&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire);
    +				$tmpentry=array('enabled'=>(! empty($conf->projet->enabled)),
    +				'perms'=>(! empty($user->rights->projet->lire)),
    +				'module'=>'projet');
    +				$showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal);
    +
    +				$titleboth=$langs->trans("LeadsOrProjects");
    +				$titlenew = $langs->trans("NewLeadOrProject");	// Leads and opportunities by default
    +				if ($conf->global->PROJECT_USE_OPPORTUNITIES == 0)
    +				{
    +					$titleboth=$langs->trans("Projects");
    +					$titlenew = $langs->trans("NewProject");
    +				}
    +				if ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) {	// 2 = leads only
    +					$titleboth=$langs->trans("Leads");
    +					$titlenew = $langs->trans("NewLead");
    +				}
    +
    +				// Project assigned to user
    +				$newmenu->add("/projet/index.php?leftmenu=projects".($search_project_user?'&search_project_user='.$search_project_user:''), $titleboth, 0, $user->rights->projet->lire, '', $mainmenu, 'projects');
    +				$newmenu->add("/projet/card.php?leftmenu=projects&action=create".($search_project_user?'&search_project_user='.$search_project_user:''), $titlenew, 1, $user->rights->projet->creer);
    +
    +				if ($conf->global->PROJECT_USE_OPPORTUNITIES == 0)
    +				{
    +					$newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user?'&search_project_user='.$search_project_user:'').'&search_status=99', $langs->trans("List"), 1, $showmode, '', 'project', 'list');
    +				}
    +				elseif ($conf->global->PROJECT_USE_OPPORTUNITIES == 1)
    +				{
    +					$newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("List"), 1, $showmode, '', 'project', 'list');
    +					$newmenu->add('/projet/list.php?mainmenu=project&amp;leftmenu=list&search_opp_status=openedopp&search_status=99&contextpage=lead', $langs->trans("ListOpenLeads"), 2, $showmode);
    +					$newmenu->add('/projet/list.php?mainmenu=project&amp;leftmenu=list&search_opp_status=notopenedopp&search_status=99&contextpage=project', $langs->trans("ListOpenProjects"), 2, $showmode);
    +				}
    +				elseif ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) {	// 2 = leads only
    +					$newmenu->add('/projet/list.php?mainmenu=project&amp;leftmenu=list&search_opp_status=openedopp&search_status=99', $langs->trans("List"), 2, $showmode);
    +				}
     
    -				// All project i have permission on
    -				/*
    -				$newmenu->add("/projet/index.php?leftmenu=projects", $langs->trans("Projects"), 0, $user->rights->projet->lire && $user->rights->projet->lire, '', $mainmenu, 'projects');
    -				$newmenu->add("/projet/card.php?leftmenu=projects&action=create", $langs->trans("NewProject"), 1, $user->rights->projet->creer && $user->rights->projet->creer);
    -				$newmenu->add("/projet/list.php?leftmenu=projects&search_status=99", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire);
    -                */
     				$newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire);
     
    +				// Categories
    +				if (! empty($conf->categorie->enabled))
    +				{
    +					$langs->load("categories");
    +					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=6", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    +				}
    +
     				if (empty($conf->global->PROJECT_HIDE_TASKS))
     				{
     					// Project affected to user
    @@ -1367,22 +1412,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				    $newmenu->add("/projet/tasks/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire);
     
     				    $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user?'&search_project_user='.$search_project_user:''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire);
    -
    -					// All project i have permission on
    -					/*$newmenu->add("/projet/activity/index.php", $langs->trans("Activities"), 0, $user->rights->projet->lire && $user->rights->projet->lire);
    -					$newmenu->add("/projet/tasks.php?action=create", $langs->trans("NewTask"), 1, $user->rights->projet->creer && $user->rights->projet->creer);
    -					$newmenu->add("/projet/tasks/list.php", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire);
    -					$newmenu->add("/projet/activity/perweek.php", $langs->trans("NewTimeSpent"), 1, $user->rights->projet->creer && $user->rights->projet->lire);
    -					*/
    -				}
    -
    -				// Categories
    -				if (! empty($conf->categorie->enabled))
    -				{
    -					$langs->load("categories");
    -					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=6", $langs->trans("Categories"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    -					$newmenu->add("/categories/card.php?action=create&amp;type=6", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
    -					//if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
     				}
     			}
     		}
    @@ -1405,8 +1434,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     			// Leave/Holiday/Vacation module
     			if (! empty($conf->holiday->enabled))
     			{
    -				$langs->load("holiday");
    -				$langs->load("trips");
    +			    // Load translation files required by the page
    +                $langs->loadLangs(array("holiday","trips"));
     
     				$newmenu->add("/holiday/list.php?leftmenu=hrm", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'hrm');
     				$newmenu->add("/holiday/card.php?action=request", $langs->trans("New"), 1,$user->rights->holiday->write);
    @@ -1502,8 +1531,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     		{
     			if (! empty($conf->adherent->enabled))
     			{
    -				$langs->load("members");
    -				$langs->load("compta");
    +				// Load translation files required by the page
    +                $langs->loadLangs(array("members","compta"));
     
     				$newmenu->add("/adherents/index.php?leftmenu=members&amp;mainmenu=members",$langs->trans("Members"),0,$user->rights->adherent->lire, '', $mainmenu, 'members');
     				$newmenu->add("/adherents/card.php?leftmenu=members&amp;action=create",$langs->trans("NewMember"),1,$user->rights->adherent->creer);
    @@ -1514,23 +1543,21 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$newmenu->add("/adherents/list.php?leftmenu=members&amp;statut=1&amp;filter=outofdate",$langs->trans("MenuMembersNotUpToDate"),2,$user->rights->adherent->lire);
     				$newmenu->add("/adherents/list.php?leftmenu=members&amp;statut=0",$langs->trans("MenuMembersResiliated"),2,$user->rights->adherent->lire);
     				$newmenu->add("/adherents/stats/index.php?leftmenu=members",$langs->trans("MenuMembersStats"),1,$user->rights->adherent->lire);
    -				if (! empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu=='none' || $leftmenu=="members" || $leftmenu=="export")) $newmenu->add("/adherents/htpasswd.php?leftmenu=export",$langs->trans("Filehtpasswd"),1,$user->rights->adherent->export);
    +
     				$newmenu->add("/adherents/cartes/carte.php?leftmenu=export",$langs->trans("MembersCards"),1,$user->rights->adherent->export);
    +				if (! empty($conf->global->MEMBER_LINK_TO_HTPASSWDFILE) && ($usemenuhider || empty($leftmenu) || $leftmenu=='none' || $leftmenu=="members" || $leftmenu=="export")) $newmenu->add("/adherents/htpasswd.php?leftmenu=export",$langs->trans("Filehtpasswd"),1,$user->rights->adherent->export);
    +
    +				if (! empty($conf->categorie->enabled))
    +				{
    +					$langs->load("categories");
    +					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=3", $langs->trans("Categories"), 1, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    +				}
     
     				$newmenu->add("/adherents/index.php?leftmenu=members&amp;mainmenu=members",$langs->trans("Subscriptions"),0,$user->rights->adherent->cotisation->lire);
     				$newmenu->add("/adherents/list.php?leftmenu=members&amp;statut=-1,1&amp;mainmenu=members",$langs->trans("NewSubscription"),1,$user->rights->adherent->cotisation->creer);
     				$newmenu->add("/adherents/subscription/list.php?leftmenu=members",$langs->trans("List"),1,$user->rights->adherent->cotisation->lire);
     				$newmenu->add("/adherents/stats/index.php?leftmenu=members",$langs->trans("MenuMembersStats"),1,$user->rights->adherent->lire);
     
    -
    -				if (! empty($conf->categorie->enabled))
    -				{
    -					$langs->load("categories");
    -					$newmenu->add("/categories/index.php?leftmenu=cat&amp;type=3", $langs->trans("Categories"), 0, $user->rights->categorie->lire, '', $mainmenu, 'cat');
    -					$newmenu->add("/categories/card.php?action=create&amp;type=3", $langs->trans("NewCategory"), 1, $user->rights->categorie->creer);
    -					//if ($usemenuhider || empty($leftmenu) || $leftmenu=="cat") $newmenu->add("/categories/list.php", $langs->trans("List"), 1, $user->rights->categorie->lire);
    -				}
    -
     				//$newmenu->add("/adherents/index.php?leftmenu=export&amp;mainmenu=members",$langs->trans("Tools"),0,$user->rights->adherent->export, '', $mainmenu, 'export');
     				//if (! empty($conf->export->enabled) && ($usemenuhider || empty($leftmenu) || $leftmenu=="export")) $newmenu->add("/exports/index.php?leftmenu=export",$langs->trans("Datas"),1,$user->rights->adherent->export);
     
    @@ -1539,7 +1566,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$newmenu->add("/adherents/type.php?leftmenu=setup&amp;mainmenu=members&amp;action=create",$langs->trans("New"),1,$user->rights->adherent->configurer);
     				$newmenu->add("/adherents/type.php?leftmenu=setup&amp;mainmenu=members",$langs->trans("List"),1,$user->rights->adherent->configurer);
     			}
    -
     		}
     
     		// Add personalized menus and modules menus
    @@ -1599,7 +1625,6 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$i++;
     			}
     		}
    -
     	}
     
     	// Build final $menu_array = $menu_array_before +$newmenu->liste + $menu_array_after
    diff --git a/htdocs/core/menus/standard/eldy_menu.php b/htdocs/core/menus/standard/eldy_menu.php
    index 11f1de43a1f..543dbd111bb 100644
    --- a/htdocs/core/menus/standard/eldy_menu.php
    +++ b/htdocs/core/menus/standard/eldy_menu.php
    @@ -27,7 +27,11 @@
      */
     class MenuManager
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $type_user;									// Put 0 for internal users, 1 for external users
     	var $atarget="";                                // To store default target to use onto links
     	var $name="eldy";
    @@ -311,8 +315,6 @@ class MenuManager
     	        				}
     	        				print '</li>'."\n";
            					}
    -
    -
            				}
             			//var_dump($submenu);
             			print '</ul>';
    @@ -331,6 +333,5 @@ class MenuManager
             //print 'xx'.$mode;
             return 0;
         }
    -
     }
     
    diff --git a/htdocs/core/menus/standard/empty.php b/htdocs/core/menus/standard/empty.php
    index f761b593fb7..4d7296b276b 100644
    --- a/htdocs/core/menus/standard/empty.php
    +++ b/htdocs/core/menus/standard/empty.php
    @@ -25,7 +25,11 @@
      */
     class MenuManager
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    
     	var $type_user=0;					// Put 0 for internal users, 1 for external users
     	var $atarget="";               		// To store default target to use onto links
     
    @@ -53,7 +57,6 @@ class MenuManager
     	 */
     	function loadMenu()
     	{
    -
     	}
     
     
    @@ -308,8 +311,6 @@ class MenuManager
     		                    }
     		                    print '</li>'."\n";
     		                }
    -
    -
     		            }
     		            //var_dump($submenu);
     		            print '</ul>';
    diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php
    index 52d65f85678..dfaaa6b26b4 100644
    --- a/htdocs/core/modules/DolibarrModules.class.php
    +++ b/htdocs/core/modules/DolibarrModules.class.php
    @@ -33,7 +33,7 @@
      *
      * Parent class for module descriptor class files
      */
    -class DolibarrModules           // Can not be abstract, because we need to instantiate it into unActivateModule to be able to disable a module whose files were removed.
    +class DolibarrModules // Can not be abstract, because we need to instantiate it into unActivateModule to be able to disable a module whose files were removed.
     {
     	/**
     	 * @var DoliDb Database handler
    @@ -83,10 +83,9 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	public $familyinfo;
     
     	/**
    -	 * @var int Module position
    -	 * @since 3.9.0
    +	 * @var string	Module position on 2 digits
     	 */
    -	public $module_position=500;
    +	public $module_position='50';
     
     	/**
     	 * @var string Module name
    @@ -338,7 +337,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     
     	/**
     	 * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
     	 */
     	public $phpmin;
     
    @@ -378,8 +377,8 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 *
     	 * @param   array  		$array_sql  SQL requests to be executed when enabling module
     	 * @param   string      $options    String with options when disabling module:
    -	 *                                    'noboxes' = Do not insert boxes
    -	 *                                    'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation
    +	 *                                  - 'noboxes' = Do not insert boxes
    +	 *                                  - 'newboxdefonly' = For boxes, insert def of boxes only and not boxes activation
     	 *
     	 * @return  int                         1 if OK, 0 if KO
     	 */
    @@ -465,11 +464,11 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     	/**
    -	 * Disable function. Deletes the module constant and boxes from the database.
    +	 * Disable function. Deletes the module constants and boxes from the database.
     	 *
     	 * @param   string[]    $array_sql  SQL requests to be executed when module is disabled
     	 * @param   string      $options	Options when disabling module:
    -	 *                                    'newboxdefonly|noboxes' = We don't remove boxes.
    +	 *                                  - 'newboxdefonly|noboxes' = We don't remove boxes.
     	 *
     	 * @return  int                     1 if OK, 0 if KO
     	 */
    @@ -554,7 +553,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		}
     		else
     		{
    -			// If module name translation using it's unique id does not exists, we try to use its name to find translation
    +			// If module name translation using it's unique id does not exist, we try to use its name to find translation
     			if (is_array($this->langfiles))
     			{
     				foreach($this->langfiles as $val)
    @@ -614,9 +613,9 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     
     	/**
     	 * Gives the long description of a module. First check README-la_LA.md then README.md
    -	 * If not markdown files found, it return translated value of the key ->descriptionlong.
    +	 * If no markdown files found, it returns translated value of the key ->descriptionlong.
     	 *
    -	 * @return  string                  Long description of a module from README.md of from property.
    +	 * @return  string     Long description of a module from README.md of from property.
     	 */
     	function getDescLong()
     	{
    @@ -999,6 +998,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create tables and keys required by module.
     	 * Files module.sql and module.key.sql with create table and create keys
    @@ -1010,6 +1010,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function _load_tables($reldir)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$error=0;
    @@ -1117,6 +1118,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds boxes
     	 *
    @@ -1126,6 +1128,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_boxes($option='')
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php';
     
     		global $conf;
    @@ -1172,7 +1175,6 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     							dol_syslog(get_class($this)."::insert_boxes", LOG_DEBUG);
     							$resql=$this->db->query($sql);
     							if (! $resql) $err++;
    -
     						}
     						if (! $err && ! preg_match('/newboxdefonly/',$option))
     						{
    @@ -1216,6 +1218,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes boxes
     	 *
    @@ -1223,6 +1226,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_boxes()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1291,6 +1295,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds cronjobs
     	 *
    @@ -1298,6 +1303,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_cronjobs()
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT . '/core/class/infobox.class.php';
     
     		global $conf;
    @@ -1321,11 +1327,13 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     				$comment = isset($this->cronjobs[$key]['comment'])?$this->cronjobs[$key]['comment']:'';
     				$frequency = isset($this->cronjobs[$key]['frequency'])?$this->cronjobs[$key]['frequency']:'';
     				$unitfrequency = isset($this->cronjobs[$key]['unitfrequency'])?$this->cronjobs[$key]['unitfrequency']:'';
    -				$status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:'';
     				$priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:'';
    +				$datestart = isset($this->cronjobs[$key]['datestart'])?$this->cronjobs[$key]['datestart']:'';
    +				$dateend = isset($this->cronjobs[$key]['dateend'])?$this->cronjobs[$key]['dateend']:'';
    +				$status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:'';
     				$test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:'';					// Line must be enabled or not (so visible or not)
     
    -				// Search if boxes def already present
    +				// Search if cron entry already present
     				$sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob";
     				$sql.= " WHERE module_name = '".$this->db->escape(empty($this->rights_class)?strtolower($this->name):$this->rights_class)."'";
     				if ($class) $sql.= " AND classesname = '".$this->db->escape($class)."'";
    @@ -1346,7 +1354,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     
     						if (! $err)
     						{
    -							$sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, label, jobtype, classesname, objectname, methodename, command, params, note,";
    +							$sql = "INSERT INTO ".MAIN_DB_PREFIX."cronjob (module_name, datec, datestart, dateend, label, jobtype, classesname, objectname, methodename, command, params, note,";
     							if(is_int($frequency)){ $sql.= ' frequency,'; }
     							if(is_int($unitfrequency)){ $sql.= ' unitfrequency,'; }
     							if(is_int($priority)){ $sql.= ' priority,'; }
    @@ -1355,7 +1363,8 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     							$sql.= " VALUES (";
     							$sql.= "'".$this->db->escape(empty($this->rights_class)?strtolower($this->name):$this->rights_class)."', ";
     							$sql.= "'".$this->db->idate($now)."', ";
    -							$sql.= "'".$this->db->idate($now)."', ";
    +							$sql.= ($datestart ? "'".$this->db->idate($datestart)."'" : "NULL").", ";
    +							$sql.= ($dateend   ? "'".$this->db->idate($dateend)."'"   : "NULL").", ";
     							$sql.= "'".$this->db->escape($label)."', ";
     							$sql.= "'".$this->db->escape($jobtype)."', ";
     							$sql.= ($class?"'".$this->db->escape($class)."'":"null").",";
    @@ -1374,7 +1383,6 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     
     							$resql=$this->db->query($sql);
     							if (! $resql) $err++;
    -
     						}
     
     						if (! $err)
    @@ -1390,7 +1398,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     					// else box already registered into database
     				}
     				else
    -			  {
    +				{
     					$this->error=$this->db->lasterror();
     					$err++;
     				}
    @@ -1401,6 +1409,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes boxes
     	 *
    @@ -1408,6 +1417,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_cronjobs()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1432,6 +1442,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes tabs
     	 *
    @@ -1439,6 +1450,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_tabs()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1457,6 +1469,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds tabs
     	 *
    @@ -1464,6 +1477,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_tabs()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1524,6 +1538,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds constants
     	 *
    @@ -1531,6 +1546,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_const()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1593,6 +1609,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes constants tagged 'deleteonunactive'
     	 *
    @@ -1600,6 +1617,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_const()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1628,6 +1646,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds access rights
     	 *
    @@ -1638,6 +1657,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_permissions($reinitadminperms=0, $force_entity=null, $notrigger=0)
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		$err=0;
    @@ -1717,7 +1737,6 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     									break;
     								}
     								else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO);
    -
     							}
     
     							$this->db->free($resqlinsert);
    @@ -1769,7 +1788,6 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     					$user->clearrights();
     					$user->getrights();
     				}
    -
     			}
     			$this->db->free($resql);
     		}
    @@ -1783,6 +1801,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes access rights
     	 *
    @@ -1790,6 +1809,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_permissions()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1808,6 +1828,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds menu entries
     	 *
    @@ -1815,6 +1836,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_menus()
     	{
    +        // phpcs:enable
     		global $user;
     
     		if (! is_array($this->menu) || empty($this->menu)) return 0;
    @@ -1917,6 +1939,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes menu entries
     	 *
    @@ -1924,6 +1947,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_menus()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -1946,6 +1970,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Creates directories
     	 *
    @@ -1953,6 +1978,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function create_dirs()
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		$err=0;
    @@ -2004,6 +2030,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds directories definitions
     	 *
    @@ -2014,6 +2041,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_dirs($name,$dir)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -2048,6 +2076,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes directories
     	 *
    @@ -2055,6 +2084,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_dirs()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    @@ -2073,6 +2103,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $err;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Adds generic parts
     	 *
    @@ -2080,6 +2111,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function insert_module_parts()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$error=0;
    @@ -2151,6 +2183,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     		return $error;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Removes generic parts
     	 *
    @@ -2158,6 +2191,7 @@ class DolibarrModules           // Can not be abstract, because we need to insta
     	 */
     	function delete_module_parts()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$err=0;
    diff --git a/htdocs/core/modules/action/modules_action.php b/htdocs/core/modules/action/modules_action.php
    index 2971b6f59ee..cbb578578e2 100644
    --- a/htdocs/core/modules/action/modules_action.php
    +++ b/htdocs/core/modules/action/modules_action.php
    @@ -28,17 +28,22 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModeleAction extends CommonDocGenerator
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return list of active generation modules
          *
    -	 * 	@param	DoliDB		$db					Database handler
    +     * 	@param	DoliDB		$db					Database handler
          *  @param	integer		$maxfilenamelength  Max length of value to show
          * 	@return	array							List of templates
          */
         static function liste_modeles($db,$maxfilenamelength=0)
         {
    +        // phpcs:enable
             global $conf;
     
             $type='action';
    @@ -50,6 +55,8 @@ abstract class ModeleAction extends CommonDocGenerator
             return $liste;
         }
     }
    +
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *  Create an product document on disk using template defined into PRODUCT_ADDON_PDF
      *
    @@ -64,6 +71,7 @@ abstract class ModeleAction extends CommonDocGenerator
      */
     function action_create($db, $object, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
     {
    +    // phpcs:enable
     	global $conf,$langs,$user;
     	$langs->load("action");
     
    diff --git a/htdocs/core/modules/action/rapport.pdf.php b/htdocs/core/modules/action/rapport.pdf.php
    index 504164cd431..66c4f0a3e45 100644
    --- a/htdocs/core/modules/action/rapport.pdf.php
    +++ b/htdocs/core/modules/action/rapport.pdf.php
    @@ -35,19 +35,33 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
      */
     class CommActionRapport
     {
    -	var $db;
    -	var $description;
    -	var $date_edition;
    -	var $year;
    -	var $month;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $title;
    -	var $subject;
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
     
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	public $date_edition;
    +
    +	public $year;
    +
    +	public $month;
    +
    +	public $title;
    +
    +	public $subject;
    +
    +	public $marge_gauche;
    +
    +	public	$marge_droite;
    +
    +	public	$marge_haute;
    +
    +	public	$marge_basse;
     
     
     	/**
    @@ -59,9 +73,10 @@ class CommActionRapport
     	 */
     	function __construct($db, $month, $year)
     	{
    -		global $conf,$langs;
    -		$langs->load("commercial");
    -		$langs->load("projects");
    +		global $conf, $langs;
    +
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("commercial","projects"));
     
     		$this->db = $db;
     		$this->description = "";
    @@ -84,6 +99,7 @@ class CommActionRapport
             $this->subject=$langs->transnoentitiesnoconv("ActionsReport").' '.$this->year."-".$this->month;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *      Write the object to document file to disk
          *
    @@ -94,17 +110,15 @@ class CommActionRapport
     	 */
     	function write_file($socid = 0, $catid = 0, $outputlangs='')
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products"));
     
             $dir = $conf->agenda->dir_temp."/";
     		$file = $dir . "actions-".$this->month."-".$this->year.".pdf";
    @@ -345,4 +359,3 @@ class CommActionRapport
     		return $y;
     	}
     }
    -
    diff --git a/htdocs/core/modules/bank/doc/pdf_ban.modules.php b/htdocs/core/modules/bank/doc/pdf_ban.modules.php
    index 9941742d8d7..97a91951e81 100644
    --- a/htdocs/core/modules/bank/doc/pdf_ban.modules.php
    +++ b/htdocs/core/modules/bank/doc/pdf_ban.modules.php
    @@ -35,9 +35,18 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     class pdf_ban extends ModeleBankAccountDoc
     {
    -	var $emetteur;	// Objet societe qui emet
    -	var $version = 'development';
    -	
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'development';
    +
     	/**
     	 *	Constructor
     	 *
    @@ -47,15 +56,13 @@ class pdf_ban extends ModeleBankAccountDoc
     	{
     		global $conf,$langs,$mysoc;
     
    -		$langs->load("main");
    -		$langs->load("bank");
    -		$langs->load("withdrawals");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","bank","withdrawals","companies"));
     
     		$this->db = $db;
     		$this->name = "ban";
     		$this->description = $langs->trans("DocumentModelBan").' (Volunteer wanted to finish)';
    -		
    +
     		// Dimension page pour format A4
     		$this->type = 'pdf';
     		$formatarray=pdf_getFormat();
    @@ -85,6 +92,7 @@ class pdf_ban extends ModeleBankAccountDoc
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Fonction generant le projet sur le disque
     	 *
    @@ -94,16 +102,15 @@ class pdf_ban extends ModeleBankAccountDoc
     	 */
     	function write_file($object,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf, $hookmanager, $langs, $user;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("projects");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
     
     		if ($conf->bank->dir_output)
     		{
    @@ -121,7 +128,7 @@ class pdf_ban extends ModeleBankAccountDoc
     		        $dir = $conf->bank->dir_output . "/" . $objectref;
     		        $file = $dir . "/" . $objectref . ".pdf";
     		    }
    -		    
    +
     			if (! file_exists($dir))
     			{
     				if (dol_mkdir($dir) < 0)
    @@ -210,9 +217,9 @@ class pdf_ban extends ModeleBankAccountDoc
     
     				$pdf->SetXY($this->marge_gauche, $curY);
     				$pdf->MultiCell(200, 3, $outputlangs->trans("BAN").' : '.$object->account_number, 0, 'L');
    -				
    -				
    -				
    +
    +
    +
     				// Show square
     				if ($pagenb == 1)
     				{
    @@ -250,7 +257,7 @@ class pdf_ban extends ModeleBankAccountDoc
     				@chmod($file, octdec($conf->global->MAIN_UMASK));
     
     				$this->result = array('fullpath'=>$file);
    -				
    +
     				return 1;   // Pas d'erreur
     			}
     			else
    @@ -282,8 +289,6 @@ class pdf_ban extends ModeleBankAccountDoc
     		global $conf,$mysoc;
     
             $default_font_size = pdf_getPDFFontSize($outputlangs);
    -
    -
     	}
     
     	/**
    @@ -370,7 +375,6 @@ class pdf_ban extends ModeleBankAccountDoc
     	    	}
     	    }
             */
    -
     	}
     
     	/**
    @@ -388,6 +392,4 @@ class pdf_ban extends ModeleBankAccountDoc
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		//return pdf_pagefoot($pdf,$outputlangs,'BANK_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php
    index 2061b03d2ae..9b49be6063f 100644
    --- a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php
    +++ b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php
    @@ -35,9 +35,18 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     class pdf_sepamandate extends ModeleBankAccountDoc
     {
    -	var $emetteur;	// Objet societe qui emet
    -	var $version = 'dolibarr';
    -	
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
     	/**
     	 *	Constructor
     	 *
    @@ -45,8 +54,8 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    -		
    +		global $conf, $langs, $mysoc;
    +
     		// Translations
     		$langs->loadLangs(array("main", "bank", "withdrawals", "companies"));
     
    @@ -83,8 +92,9 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	}
     
     
    -	/**
    -	 *	Fonction generant le projet sur le disque
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +	 *  Fonction generant le projet sur le disque
     	 *
     	 *	@param	    Project		$object   		    Object project a generer
     	 *	@param	    Translate	$outputlangs	    Lang output object
    @@ -97,15 +107,16 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	 */
     	function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
     	{
    +        // phpcs:enable
     		global $conf, $hookmanager, $langs, $user, $mysoc;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "dict", "withdrawals", "companies", "projects", "bills"));
    -		
    +
     		if (! empty($conf->bank->dir_output))
     		{
     			//$nblignes = count($object->lines);  // This is set later with array of tasks
    @@ -124,7 +135,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     		        else $dir = $conf->bank->dir_output . "/" . $objectref;
     		        $file = $dir . "/" . $langs->transnoentitiesnoconv("SepaMandateShort").' '.$objectref . "-".dol_sanitizeFileName($object->rum).".pdf";
     		    }
    -		    
    +
     			if (! file_exists($dir))
     			{
     				if (dol_mkdir($dir) < 0)
    @@ -212,55 +223,55 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				$nexY = $tab_top + 7;
     
     				$posY = $curY;
    -				
    +
     				$pdf->SetFont('','', $default_font_size);
    -				
    +
     				$pdf->line($this->marge_gauche, $posY, $this->page_largeur - $this->marge_droite, $posY);
     				$posY+=2;
    -				
    +
     				$pdf->SetXY($this->marge_gauche, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("RUMLong").' ('.$outputlangs->transnoentitiesnoconv("RUM").')'.' : '.$object->rum, 0, 'L');
    -				
    +
     				$posY=$pdf->GetY();
     				$posY+=2;
     				$pdf->SetXY($this->marge_gauche, $posY);
     				$ics='';
     				if (! empty($conf->global->PRELEVEMENT_ICS)) $ics=$conf->global->PRELEVEMENT_ICS;
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("CreditorIdentifier").' ('.$outputlangs->transnoentitiesnoconv("ICS").')'.' : '.$ics, 0, 'L');
    -				
    +
     				$posY=$pdf->GetY();
     				$posY+=1;
     				$pdf->SetXY($this->marge_gauche, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("CreditorName").' : '.$mysoc->name, 0, 'L');
    -				
    +
     				$posY=$pdf->GetY();
     				$posY+=1;
     				$pdf->SetXY($this->marge_gauche, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("Address").' : ', 0, 'L');
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $mysoc->getFullAddress(), 0, 'L');
    -				
    +
     				$posY=$pdf->GetY();
     				$posY+=3;
    -				
    +
     				$pdf->line($this->marge_gauche, $posY, $this->page_largeur - $this->marge_droite, $posY);
    -				
    +
     				$pdf->SetFont('','', $default_font_size - 1);
    -				
    +
     				$posY+=8;
     				$pdf->SetXY($this->marge_gauche, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 8, $outputlangs->transnoentitiesnoconv("SEPALegalText", $mysoc->name, $mysoc->name), 0, 'L');
    -				
    +
     				// Your data form
     				$posY=$pdf->GetY();
     				$posY+=8;
     				$pdf->line($this->marge_gauche, $posY, $this->page_largeur - $this->marge_droite, $posY);
     				$posY+=2;
    -				
    +
     				$pdf->SetFont('','', $default_font_size);
    -				
    +
     				$pdf->SetXY($this->marge_gauche, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("SEPAFillForm"), 0, 'C');
    -				
    +
     				$thirdparty=new Societe($this->db);
     				if ($object->socid > 0) $thirdparty->fetch($object->socid);
     
    @@ -275,7 +286,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("SEPAFormYourName").' * : ', 0, 'L');
     				$pdf->SetXY(80, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $sepaname, 0, 'L');
    -				
    +
     			    $address = '______________________________________________';
     				if ($thirdparty->id > 0)
     				{
    @@ -293,7 +304,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc
         				$pdf->SetXY(80, $posY);
         				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $address, 0, 'L');
     				}
    -				
    +
     				$ban = '__________________________________________________';
     				if (! empty($object->iban)) $ban = $object->iban;
     				$posY=$pdf->GetY();
    @@ -302,7 +313,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("SEPAFormYourBAN").' * : ', 0, 'L');
     				$pdf->SetXY(80, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $ban, 0, 'L');
    -				
    +
     				$bic = '__________________________________________________';
     				if (! empty($object->bic)) $bic = $object->bic;
     				$posY=$pdf->GetY();
    @@ -311,8 +322,8 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $outputlangs->transnoentitiesnoconv("SEPAFormYourBIC").' * : ', 0, 'L');
     				$pdf->SetXY(80, $posY);
     				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $bic, 0, 'L');
    -				
    -				
    +
    +
     				$posY=$pdf->GetY();
     				$posY+=1;
     				$pdf->SetXY($this->marge_gauche, $posY);
    @@ -338,13 +349,13 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				    $txt = '('.$langs->transnoentitiesnoconv("PleaseCheckOne").')';
         				$pdf->MultiCell($this->page_largeur - $this->marge_gauche - $this->marge_droite, 3, $txt, 0, 'L');
     				}
    -				
    +
     				$posY=$pdf->GetY();
     				$posY+=3;
     				$pdf->line($this->marge_gauche, $posY, $this->page_largeur - $this->marge_droite, $posY);
     				$posY+=3;
    -				
    -				
    +
    +
     				// Show square
     				if ($pagenb == 1)
     				{
    @@ -362,10 +373,10 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				var_dump($heightforfreetext);
     				var_dump($heightforfooter);
     				var_dump($bottomlasttab);*/
    -				
    +
     				// Affiche zone infos
     				$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
    -				
    +
     				/*
     				 * Pied de page
     				 */
    @@ -391,7 +402,7 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     				@chmod($file, octdec($conf->global->MAIN_UMASK));
     
     				$this->result = array('fullpath'=>$file);
    -				
    +
     				return 1;   // Pas d'erreur
     			}
     			else
    @@ -423,10 +434,10 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     		global $conf,$mysoc;
     
             $default_font_size = pdf_getPDFFontSize($outputlangs);
    -
     	}
     
    -	
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -438,30 +449,32 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    global $conf, $mysoc;
    -	
    +        // phpcs:enable
    +        global $conf, $mysoc;
    +
     	    $default_font_size = pdf_getPDFFontSize($outputlangs);
    -	
    +
     	    $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?1:$conf->global->PDF_DIFFSIZE_TITLE);
     
     	    $posy+=$this->_signature_area($pdf, $object, $posy, $outputlangs);
    -   
    +
     	    $pdf->SetXY($this->marge_gauche, $posy);
     	    $pdf->SetFont('','', $default_font_size);
     	    $pdf->MultiCell(100, 3, $outputlangs->transnoentitiesnoconv("PleaseReturnMandate", $mysoc->email).':', 0, 'L', 0);
     	    $posy=$pdf->GetY()+2;
    -	     
    +
     	    $pdf->SetXY($this->marge_gauche, $posy);
     	    $pdf->SetFont('','', $default_font_size - $diffsizetitle);
     	    $pdf->MultiCell(100, 6, $mysoc->name, 0, 'L', 0);
     		$pdf->MultiCell(100, 6, $outputlangs->convToOutputCharset($mysoc->getFullAddress()), 0, 'L', 0);
     		$posy=$pdf->GetY()+2;
    -		
    +
     	    return $posy;
     	}
    -	
    -	
    -	
    +
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show area for the customer to sign
     	 *
    @@ -473,19 +486,20 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	 */
     	function _signature_area(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     	    $default_font_size = pdf_getPDFFontSize($outputlangs);
     	    $tab_top = $posy + 4;
     	    $tab_hl = 4;
    -	
    +
     	    $posx = $this->marge_gauche;
     	    $pdf->SetXY($posx, $tab_top + 0);
    -	    
    +
     	    $pdf->SetFont('','', $default_font_size - 2);
    -	    
    +
     	    $pdf->MultiCell(100, 3, $outputlangs->transnoentitiesnoconv("DateOfSignature"), 0, 'L', 0);
     	    $pdf->MultiCell(100, 3, ' ');
     	    $pdf->MultiCell(100, 3, '______________________', 0, 'L', 0);
    -	    
    +
     	    $posx = 120;
     	    $largcol = ($this->page_largeur - $this->marge_droite - $posx);
     	    $useborder=0;
    @@ -494,14 +508,14 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	    $pdf->SetFillColor(255,255,255);
     	    $pdf->SetXY($posx, $tab_top + 0);
     	    $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentitiesnoconv("Signature"), 0, 'L', 1);
    -	
    +
     	    $pdf->SetXY($posx, $tab_top + $tab_hl);
     	    $pdf->MultiCell($largcol, $tab_hl*3, '', 1, 'R');
    -	
    +
     	    return ($tab_hl*7);
     	}
    -	
    -	
    +
    +
     	/**
     	 *  Show top header of page.
     	 *
    @@ -592,7 +606,6 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     	    	}
     	    }
             */
    -
     	}
     
     	/**
    @@ -610,6 +623,4 @@ class pdf_sepamandate extends ModeleBankAccountDoc
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'PAYMENTORDER_FREE_TEXT',null,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/bank/modules_bank.php b/htdocs/core/modules/bank/modules_bank.php
    index b0a121d7dc5..faae304222d 100644
    --- a/htdocs/core/modules/bank/modules_bank.php
    +++ b/htdocs/core/modules/bank/modules_bank.php
    @@ -31,27 +31,31 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModeleBankAccountDoc extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
    -	 */
    -	static function liste_modeles($db,$maxfilenamelength=0)
    +     */
    +	static function liste_modeles($db, $maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
    -		$type='bankaccount';
    -		$liste=array();
    +		$type = 'bankaccount';
    +		$list = array();
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -		$liste=getListOfModels($db,$type,$maxfilenamelength);
    +		$list = getListOfModels($db, $type, $maxfilenamelength);
     
    -		return $liste;
    +		return $list;
     	}
     }
    -
    diff --git a/htdocs/core/modules/barcode/doc/phpbarcode.modules.php b/htdocs/core/modules/barcode/doc/phpbarcode.modules.php
    index d04c6a70c04..c9068dc4d26 100644
    --- a/htdocs/core/modules/barcode/doc/phpbarcode.modules.php
    +++ b/htdocs/core/modules/barcode/doc/phpbarcode.modules.php
    @@ -32,8 +32,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/barcode.lib.php';    // This is to inc
      */
     class modPhpbarcode extends ModeleBarCode
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error='';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -109,7 +117,7 @@ class modPhpbarcode extends ModeleBarCode
     	 *	@param  string	 	$encoding		  Mode of encoding
     	 *	@param  string	 	$readable		  Code can be read
     	 *	@param	integer		$scale			  Scale
    -	 *  @param  integer     $nooutputiferror  No output if error 
    +	 *  @param  integer     $nooutputiferror  No output if error
     	 *	@return	int							  <0 if KO, >0 if OK
          */
     	function buildBarCode($code,$encoding,$readable='Y',$scale=1,$nooutputiferror=0)
    @@ -150,7 +158,7 @@ class modPhpbarcode extends ModeleBarCode
     	 *	@param	string   	$encoding		  Mode of encoding
     	 *	@param  string	 	$readable		  Code can be read
     	 *	@param	integer		$scale			  Scale
    -	 *  @param  integer     $nooutputiferror  No output if error 
    +	 *  @param  integer     $nooutputiferror  No output if error
     	 *	@return	int							  <0 if KO, >0 if OK
     	 */
     	function writeBarCode($code,$encoding,$readable='Y',$scale=1,$nooutputiferror=0)
    @@ -167,6 +175,4 @@ class modPhpbarcode extends ModeleBarCode
     
     		return $result;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php b/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php
    index 5b9422b15e7..c37f87f17d5 100644
    --- a/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php
    +++ b/htdocs/core/modules/barcode/doc/tcpdfbarcode.modules.php
    @@ -31,10 +31,19 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/barcode.lib.php';	   // This is to inc
      */
     class modTcpdfbarcode extends ModeleBarCode
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error='';
    -	var $is2d = false;
    -	
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	public $is2d = false;
    +
     	/**
     	 *	Return description of numbering model
     	 *
    @@ -55,8 +64,8 @@ class modTcpdfbarcode extends ModeleBarCode
     	function isEnabled()
     	{
     		return true;
    -	}	 
    -	
    +	}
    +
     	/**
     	 *	Test si les numeros deja en vigueur dans la base ne provoquent pas de
     	 *	de conflits qui empechera cette numerotation de fonctionner.
    @@ -66,10 +75,10 @@ class modTcpdfbarcode extends ModeleBarCode
     	function canBeActivated()
     	{
     		global $langs;
    -	
    +
     		return true;
     	}
    -	
    +
     	/**
     	 *	Return true if encoding is supported
     	 *
    @@ -83,7 +92,7 @@ class modTcpdfbarcode extends ModeleBarCode
     			return 0;
     		} else {
     			return 1;
    -		}		
    +		}
     	}
     
     	/**
    @@ -99,17 +108,17 @@ class modTcpdfbarcode extends ModeleBarCode
     	function buildBarCode($code,$encoding,$readable='Y',$scale=1,$nooutputiferror=0)
     	{
     		global $_GET;
    -		
    +
     		$tcpdfEncoding = $this->getTcpdfEncodingType($encoding);
     		if (empty($tcpdfEncoding)) return -1;
    -				
    +
     		$color = array(0,0,0);
     
     		$_GET["code"]=$code;
     		$_GET["type"]=$encoding;
     		$_GET["height"]=$height;
     		$_GET["readable"]=$readable;
    -		
    +
     		if ($code) {
     			// Load the tcpdf barcode class
     			if ($this->is2d) {
    @@ -122,15 +131,15 @@ class modTcpdfbarcode extends ModeleBarCode
     				$width = 1;
     				require_once TCPDF_PATH.'tcpdf_barcodes_1d.php';
     				$barcodeobj = new TCPDFBarcode($code, $tcpdfEncoding);
    -			}		
    -			
    +			}
    +
     			dol_syslog("buildBarCode::TCPDF.getBarcodePNG");
     			$barcodeobj->getBarcodePNG($width, $height, $color);
    -			
    +
     			return 1;
     		} else {
     			return -2;
    -		}		
    +		}
     	}
     
     	/**
    @@ -172,8 +181,8 @@ class modTcpdfbarcode extends ModeleBarCode
     				$width = 1;
     				require_once TCPDF_PATH.'tcpdf_barcodes_1d.php';
     				$barcodeobj = new TCPDFBarcode($code, $tcpdfEncoding);
    -			}		
    -			
    +			}
    +
     			dol_syslog("writeBarCode::TCPDF.getBarcodePngData");
     			if ($imageData = $barcodeobj->getBarcodePngData($width, $height, $color)) {
     				if (function_exists('imagecreate')) {
    @@ -186,16 +195,16 @@ class modTcpdfbarcode extends ModeleBarCode
     				}
     			} else {
     				return -4;
    -			}			
    +			}
     		} else {
     			return -2;
     		}
     	}
    -	
    +
     	/**
     	 *	get available output_modes for tcpdf class wth its translated description
     	 *
    -	 * @param	string $dolEncodingType dolibarr barcode encoding type	
    +	 * @param	string $dolEncodingType dolibarr barcode encoding type
     	 * @return	string tcpdf encoding type
     	 */
     	public function getTcpdfEncodingType($dolEncodingType)
    @@ -232,7 +241,7 @@ class modTcpdfbarcode extends ModeleBarCode
     						'PHARMA' => 'PHARMA',
     						'PHARMA2T' => 'PHARMA2T'
     		);
    -		
    +
     		$tcpdf2dEncodingTypes = array(
     						'DATAMATRIX' => 'DATAMATRIX',
     						'PDF417' => 'PDF417',
    @@ -240,9 +249,9 @@ class modTcpdfbarcode extends ModeleBarCode
     						'QRCODE,L' => 'QRCODE,L',
     						'QRCODE,M' => 'QRCODE,M',
     						'QRCODE,Q' => 'QRCODE,Q',
    -						'QRCODE,H' => 'QRCODE,H'						
    +						'QRCODE,H' => 'QRCODE,H'
     		);
    -		
    +
     		if (array_key_exists($dolEncodingType, $tcpdf1dEncodingTypes)) {
     			$this->is2d = false;
     			return $tcpdf1dEncodingTypes[$dolEncodingType];
    @@ -251,6 +260,6 @@ class modTcpdfbarcode extends ModeleBarCode
     			return $tcpdf2dEncodingTypes[$dolEncodingType];
     		} else {
     			return '';
    -		}		 
    +		}
     	}
     }
    diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php
    index 3e233eb1843..886ff87520a 100644
    --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php
    +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php
    @@ -33,17 +33,29 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/barcode/modules_barcode.class.php'
      */
     class mod_barcode_product_standard extends ModeleNumRefBarCode
     {
    -	var $name='Standard';				// Model Name
    -	var $code_modifiable;				// Editable code
    -	var $code_modifiable_invalide;		// Modified code if it is invalid
    -	var $code_modifiable_null;			// Modified code if it is null
    -	var $code_null;						// Optional code
    -	var $version='dolibarr';    		// 'development', 'experimental', 'dolibarr'
    -	var $code_auto;                     // Automatic Numbering
    +	public $name='Standard';				// Model Name
     
    -	var $searchcode; // Search string
    -	var $numbitcounter; // Number of digits the counter
    -	var $prefixIsRequired; // The prefix field of third party must be filled when using {pre}
    +	public $code_modifiable;				// Editable code
    +
    +	public $code_modifiable_invalide;		// Modified code if it is invalid
    +
    +	public $code_modifiable_null;			// Modified code if it is null
    +
    +	public $code_null;						// Optional code
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';    		// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto;                     // Automatic Numbering
    +
    +	public $searchcode; // Search string
    +
    +	public $numbitcounter; // Number of digits the counter
    +
    +	public $prefixIsRequired; // The prefix field of third party must be filled when using {pre}
     
     
     	/**
    @@ -223,16 +235,18 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *		Return if a code is used (by other element)
    +	 *	Return if a code is used (by other element)
     	 *
    -	 *		@param	DoliDB		$db			Handler acces base
    -	 *		@param	string		$code		Code to check
    -	 *		@param	Product		$product	Objet product
    -	 *		@return	int						0 if available, <0 if KO
    +	 *	@param	DoliDB		$db			Handler acces base
    +	 *	@param	string		$code		Code to check
    +	 *	@param	Product		$product	Objet product
    +	 *	@return	int						0 if available, <0 if KO
     	 */
     	function verif_dispo($db, $code, $product)
     	{
    +        // phpcs:enable
     		$sql = "SELECT barcode FROM ".MAIN_DB_PREFIX."product";
     		$sql.= " WHERE barcode = '".$code."'";
     		if ($product->id > 0) $sql.= " AND rowid <> ".$product->id;
    @@ -253,9 +267,9 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
     		{
     			return -2;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return if a barcode value match syntax
     	 *
    @@ -265,6 +279,7 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
     	 */
     	function verif_syntax($codefortest, $typefortest)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$result = 0;
    @@ -300,6 +315,4 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode
     
     		return $result;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/barcode/modules_barcode.class.php b/htdocs/core/modules/barcode/modules_barcode.class.php
    index 4720ffb1341..44d7eccbb07 100644
    --- a/htdocs/core/modules/barcode/modules_barcode.class.php
    +++ b/htdocs/core/modules/barcode/modules_barcode.class.php
    @@ -29,7 +29,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
      */
     abstract class ModeleBarCode
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -41,7 +44,6 @@ abstract class ModeleBarCode
     	{
     		return true;
     	}
    -
     }
     
     
    @@ -50,7 +52,10 @@ abstract class ModeleBarCode
      */
     abstract class ModeleNumRefBarCode
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
         /**     Return default description of numbering model
          *
    @@ -171,6 +176,5 @@ abstract class ModeleNumRefBarCode
     
             return $s;
         }
    -
     }
     
    diff --git a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php
    index 1e539a2019f..c4995ead47f 100644
    --- a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php
    +++ b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php
    @@ -34,7 +34,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/cheque/modules_chequereceipts.php'
      */
     class BordereauChequeBlochet extends ModeleChequeReceipts
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     	/**
     	 *	Constructor
    @@ -45,8 +49,8 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     	{
     		global $conf,$langs,$mysoc;
     
    -		$langs->load("main");
    -		$langs->load("bills");
    +		// Load traductions files requiredby by page
    +		$langs->loadLangs(array("main", "bills"));
     
     		$this->db = $db;
     		$this->name = "blochet";
    @@ -74,10 +78,11 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     		$this->tab_height = 200;	//$this->line_height * $this->line_per_page;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Fonction to generate document on disk
     	 *
    -	 *	@param	RemiseCheque	$object			Object RemiseCheque			
    +	 *	@param	RemiseCheque	$object			Object RemiseCheque
     	 *	@param	string			$_dir			Directory
     	 *	@param	string			$number			Number
     	 *	@param	Translate		$outputlangs	Lang output object
    @@ -85,6 +90,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     	 */
     	function write_file($object, $_dir, $number, $outputlangs)
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$hookmanager;
     
             if (! is_object($outputlangs)) $outputlangs=$langs;
    @@ -92,11 +98,8 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
             $sav_charset_output=$outputlangs->charset_output;
             if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    -        $outputlangs->load("compta");
    +        // Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "companies", "bills", "products", "compta"));
     
     		$dir = $_dir . "/".get_exdir($number,0,1,0,$object,'cheque').$number;
     
    @@ -194,12 +197,13 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     			@chmod($file, octdec($conf->global->MAIN_UMASK));
     
     		$this->result = array('fullpath'=>$file);
    -		
    +
             $outputlangs->charset_output=$sav_charset_output;
     	    return 1;   // Pas d'erreur
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Generate Header
     	 *
    @@ -211,11 +215,12 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     	 */
     	function Header(&$pdf, $page, $pages, $outputlangs)
     	{
    +        // phpcs:enable
     		global $langs;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    -		$outputlangs->load("compta");
    -		$outputlangs->load("banks");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("compta", "banks"));
     
     		$title = $outputlangs->transnoentities("CheckReceipt");
     		$pdf->SetFont('','B', $default_font_size);
    @@ -306,6 +311,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Output array
     	 *
    @@ -317,6 +323,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     	 */
     	function Body(&$pdf, $pagenb, $pages, $outputlangs)
     	{
    +        // phpcs:enable
     		// x=10 - Num
     		// x=30 - Banque
     		// x=100 - Emetteur
    @@ -387,8 +394,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts
     		{
     		    $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray);
     		}
    -		
    +
     		return pdf_pagefoot($pdf,$outputlangs,$newfreetext,$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
     }
    -
    diff --git a/htdocs/core/modules/cheque/mod_chequereceipt_mint.php b/htdocs/core/modules/cheque/mod_chequereceipt_mint.php
    index 680357ce9bb..ba617787cbe 100644
    --- a/htdocs/core/modules/cheque/mod_chequereceipt_mint.php
    +++ b/htdocs/core/modules/cheque/mod_chequereceipt_mint.php
    @@ -29,10 +29,20 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/cheque/modules_chequereceipts.php
      */
     class mod_chequereceipt_mint extends ModeleNumRefChequeReceipts
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='CHK';
    -	var $error='';
    -	var $name='Mint';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='CHK';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	public $name='Mint';
     
     
         /**
    @@ -135,6 +145,7 @@ class mod_chequereceipt_mint extends ModeleNumRefChequeReceipts
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -144,7 +155,7 @@ class mod_chequereceipt_mint extends ModeleNumRefChequeReceipts
     	 */
     	function chequereceipt_get_num($objsoc,$objforref)
     	{
    +        // phpcs:enable
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php b/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php
    index 69ee2ff2b73..6e211fb4ace 100644
    --- a/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php
    +++ b/htdocs/core/modules/cheque/mod_chequereceipt_thyme.php
    @@ -30,9 +30,18 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/cheque/modules_chequereceipts.php
      */
     class mod_chequereceipt_thyme extends ModeleNumRefChequeReceipts
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $name = 'Thyme';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	public $name = 'Thyme';
     
     
         /**
    @@ -42,7 +51,7 @@ class mod_chequereceipt_thyme extends ModeleNumRefChequeReceipts
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -124,6 +133,7 @@ class mod_chequereceipt_thyme extends ModeleNumRefChequeReceipts
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -133,8 +143,7 @@ class mod_chequereceipt_thyme extends ModeleNumRefChequeReceipts
          */
         function chequereceipt_get_num($objsoc,$objforref)
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/cheque/modules_chequereceipts.php b/htdocs/core/modules/cheque/modules_chequereceipts.php
    index bbf20761f5f..f2841a7ec8e 100644
    --- a/htdocs/core/modules/cheque/modules_chequereceipts.php
    +++ b/htdocs/core/modules/cheque/modules_chequereceipts.php
    @@ -36,7 +36,10 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';   // Requ
      */
     abstract class ModeleNumRefChequeReceipts
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Return if a module can be used or not
    @@ -115,12 +118,16 @@ abstract class ModeleNumRefChequeReceipts
     
     /**
      *	\class      ModeleChequeReceipts
    - *	\brief      Classe mere des modeles de 
    + *	\brief      Classe mere des modeles de
      */
     abstract class ModeleChequeReceipts extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
    @@ -130,6 +137,7 @@ abstract class ModeleChequeReceipts extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='chequereceipt';
    @@ -201,7 +209,6 @@ function chequereceipt_pdf_create($db, $id, $message, $modele, $outputlangs)
     			dol_print_error($db,"chequereceipt_pdf_create Error: ".$obj->error);
     			return -1;
     		}
    -
     	}
     	else
     	{
    @@ -209,4 +216,3 @@ function chequereceipt_pdf_create($db, $id, $message, $modele, $outputlangs)
     		return -1;
     	}
     }
    -
    diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    index 4c8b4ba2dc5..a849d2a2c7a 100644
    --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    @@ -3,21 +3,23 @@
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2014		Marcos García		<marcosgdf@gmail.com>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    -*
    -* 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 <http://www.gnu.org/licenses/>.
    -* or see http://www.gnu.org/
    -*/
    + * Copyright (C) 2018       Philippe Grand      <philippe.grand@atoo-net.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
     
     /**
      *	\file       htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    @@ -38,10 +40,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_order_odt extends ModelePDFCommandes
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -51,10 +66,10 @@ class doc_generic_order_odt extends ModelePDFCommandes
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -98,8 +113,8 @@ class doc_generic_order_odt extends ModelePDFCommandes
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -177,6 +192,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -190,6 +206,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -211,10 +228,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
     
     		if ($conf->commande->dir_output)
     		{
    @@ -338,6 +352,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -353,6 +368,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     				}
     				catch(OdfException $e)
     				{
    +                    dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -389,6 +405,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -421,9 +438,11 @@ class doc_generic_order_odt extends ModelePDFCommandes
     								}
     								catch(OdfException $e)
     								{
    +                                    dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +                                    dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -447,6 +466,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -460,15 +480,17 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
     					}catch (Exception $e){
    -						$this->error=$e->getMessage();
    +                        $this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
     					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    -						$this->error=$e->getMessage();
    +					} catch (Exception $e) {
    +                        $this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -494,6 +516,4 @@ class doc_generic_order_odt extends ModelePDFCommandes
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    index 99acc394475..6047caa55b3 100644
    --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    @@ -1,7 +1,7 @@
     <?php
    -/* Copyright (C) 2004-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2008		Raphael Bertrand	<raphael.bertrand@resultic.fr>
    +/* Copyright (C) 2004-2014  Laurent Destailleur <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2008       Raphael Bertrand	<raphael.bertrand@resultic.fr>
      * Copyright (C) 2010-2013	Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2012      	Christophe Battarel <christophe.battarel@altairis.fr>
      * Copyright (C) 2012       Cedric Salvador     <csalvador@gpcsolutions.fr>
    @@ -27,7 +27,7 @@
     /**
      *	\file       htdocs/core/modules/commande/doc/pdf_einstein.modules.php
      *	\ingroup    commande
    - *	\brief      Fichier de la classe permettant de generer les commandes au modele Einstein
    + *	\brief      File of Class to generate PDF orders with template Einstein
      */
     
     require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
    @@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     
     /**
    - *	Classe to generate PDF orders with template Einstein
    + *	Class to generate PDF orders with template Einstein
      */
     class pdf_einstein extends ModelePDFCommandes
     {
    @@ -69,9 +69,9 @@ class pdf_einstein extends ModelePDFCommandes
     
     	/**
          * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
          */
    -	public $phpmin = array(5, 2);
    +	public $phpmin = array(5, 4);
     
     	/**
          * Dolibarr version of the loaded document
    @@ -79,15 +79,46 @@ class pdf_einstein extends ModelePDFCommandes
          */
     	public $version = 'dolibarr';
     
    +	/**
    +     * @var int page_largeur
    +     */
         public $page_largeur;
    +
    +    /**
    +     * @var int page_hauteur
    +     */
         public $page_hauteur;
    +
    +    /**
    +     * @var array format
    +     */
         public $format;
    +
    +    /**
    +     * @var int marge_gauche
    +     */
     	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
     	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
     	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
     	public $marge_basse;
     
    -    public $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +    public $emetteur;
     
     
     	/**
    @@ -118,13 +149,13 @@ class pdf_einstein extends ModelePDFCommandes
     		$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
     		$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
     
    -		$this->option_logo = 1;                    // Affiche logo
    -		$this->option_tva = 1;                     // Gere option tva FACTURE_TVAOPTION
    -		$this->option_modereg = 1;                 // Affiche mode reglement
    -		$this->option_condreg = 1;                 // Affiche conditions reglement
    -		$this->option_codeproduitservice = 1;      // Affiche code produit-service
    -		$this->option_multilang = 1;               // Dispo en plusieurs langues
    -		$this->option_escompte = 0;                // Affiche si il y a eu escompte
    +		$this->option_logo = 1;                    // Display logo
    +		$this->option_tva = 1;                     // Manage the vat option FACTURE_TVAOPTION
    +		$this->option_modereg = 1;                 // Display payment mode
    +		$this->option_condreg = 1;                 // Display payment terms
    +		$this->option_codeproduitservice = 1;      // Display product-service code
    +		$this->option_multilang = 1;               // Available in several languages
    +		$this->option_escompte = 0;                // Displays if there has been a discount
     		$this->option_credit_note = 0;             // Support credit notes
     		$this->option_freetext = 1;				   // Support add of a personalised text
     		$this->option_draft_watermark = 1;		   // Support add of a watermark on drafts
    @@ -172,7 +203,8 @@ class pdf_einstein extends ModelePDFCommandes
     		$this->atleastonediscount=0;
     	}
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -185,13 +217,14 @@ class pdf_einstein extends ModelePDFCommandes
     	 */
     	function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
     	{
    +        // phpcs:enable
     		global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		// Translations
    +		// Load translation files required by the page
     		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
     
     		$nblignes = count($object->lines);
    @@ -613,6 +646,7 @@ class pdf_einstein extends ModelePDFCommandes
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show payments table
          *
    @@ -624,10 +658,11 @@ class pdf_einstein extends ModelePDFCommandes
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    -
    +        // phpcs:enable
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -639,6 +674,7 @@ class pdf_einstein extends ModelePDFCommandes
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -814,6 +850,7 @@ class pdf_einstein extends ModelePDFCommandes
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -826,6 +863,7 @@ class pdf_einstein extends ModelePDFCommandes
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     	    global $conf,$mysoc;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -929,7 +967,6 @@ class pdf_einstein extends ModelePDFCommandes
     
     								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
     								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    -
     							}
     						}
     					}
    @@ -1201,7 +1238,7 @@ class pdf_einstein extends ModelePDFCommandes
     	{
     		global $conf,$langs,$hookmanager;
     
    -		// Translations
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1223,27 +1260,30 @@ class pdf_einstein extends ModelePDFCommandes
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -			    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B', $default_font_size -2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B', $default_font_size -2);
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B', $default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    @@ -1411,5 +1451,4 @@ class pdf_einstein extends ModelePDFCommandes
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    new file mode 100644
    index 00000000000..0bf4b91365e
    --- /dev/null
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -0,0 +1,1672 @@
    +<?php
    +/* Copyright (C) 2004-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2008		Raphael Bertrand	<raphael.bertrand@resultic.fr>
    + * Copyright (C) 2010-2013	Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2012      	Christophe Battarel <christophe.battarel@altairis.fr>
    + * Copyright (C) 2012       Cedric Salvador     <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2015       Marcos García       <marcosgdf@gmail.com>
    + * Copyright (C) 2017       Ferran Marcet       <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *	\file       htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    + *	\ingroup    commande
    + *	\brief      Fichier de la classe permettant de generer les commandes au modele Eratosthène
    + */
    +
    +require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
    +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
    +
    +
    +/**
    + *	Classe to generate PDF orders with template Eratosthene
    + */
    +class pdf_eratosthene extends ModelePDFCommandes
    +{
    +    /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
    +
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
    +
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +    /**
    +     * @var int 	Save the name of generated file as the main doc when generating a doc with this template
    +     */
    +    public $update_main_doc_field;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +	/**
    +     * @var array Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +     */
    +	public $phpmin = array(5, 2);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'development';
    +
    +    public $page_largeur;
    +    public $page_hauteur;
    +    public $format;
    +	public $marge_gauche;
    +	public $marge_droite;
    +	public $marge_haute;
    +	public $marge_basse;
    +
    +    public $emetteur;	// Objet societe qui emet
    +
    +
    +	/**
    +	 *	Constructor
    +	 *
    +	 *  @param		DoliDB		$db      Database handler
    +	 */
    +	public function __construct($db)
    +	{
    +		global $conf,$langs,$mysoc;
    +
    +		// Translations
    +		$langs->loadLangs(array("main", "bills", "products"));
    +
    +		$this->db = $db;
    +		$this->name = "eratosthene";
    +		$this->description = $langs->trans('PDFEratostheneDescription');
    +		$this->update_main_doc_field = 1;		// Save the name of generated file as the main doc when generating a doc with this template
    +
    +		// Dimension page
    +		$this->type = 'pdf';
    +		$formatarray=pdf_getFormat();
    +		$this->page_largeur = $formatarray['width'];
    +		$this->page_hauteur = $formatarray['height'];
    +		$this->format = array($this->page_largeur,$this->page_hauteur);
    +		$this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
    +		$this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
    +		$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
    +		$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
    +
    +		$this->option_logo = 1;                    // Affiche logo
    +		$this->option_tva = 1;                     // Gere option tva FACTURE_TVAOPTION
    +		$this->option_modereg = 1;                 // Affiche mode reglement
    +		$this->option_condreg = 1;                 // Affiche conditions reglement
    +		$this->option_codeproduitservice = 1;      // Affiche code produit-service
    +		$this->option_multilang = 1;               // Dispo en plusieurs langues
    +		$this->option_escompte = 0;                // Affiche si il y a eu escompte
    +		$this->option_credit_note = 0;             // Support credit notes
    +		$this->option_freetext = 1;				   // Support add of a personalised text
    +		$this->option_draft_watermark = 1;		   // Support add of a watermark on drafts
    +
    +		$this->franchise=!$mysoc->tva_assuj;
    +
    +		// Get source company
    +		$this->emetteur=$mysoc;
    +		if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default, if was not defined
    +
    +		// Define position of columns
    +		$this->posxdesc=$this->marge_gauche+1;
    +
    +
    +		$this->tva=array();
    +		$this->localtax1=array();
    +		$this->localtax2=array();
    +		$this->atleastoneratenotnull=0;
    +		$this->atleastonediscount=0;
    +	}
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
    +    /**
    +     *  Function to build pdf onto disk
    +     *
    +     *  @param		Object		$object				Object to generate
    +     *  @param		Translate	$outputlangs		Lang output object
    +     *  @param		string		$srctemplatepath	Full path of source filename for generator using a template file
    +     *  @param		int			$hidedetails		Do not show line details
    +     *  @param		int			$hidedesc			Do not show desc
    +     *  @param		int			$hideref			Do not show ref
    +     *  @return     int             			    1=OK, 0=KO
    +	 */
    +	public function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
    +	{
    +	    // phpcs:enable
    +		global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblignes;
    +
    +		if (! is_object($outputlangs)) $outputlangs=$langs;
    +		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
    +		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    +
    +		// Translations
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
    +
    +		$nblignes = count($object->lines);
    +
    +		if ($conf->commande->dir_output)
    +		{
    +            $object->fetch_thirdparty();
    +
    +            $deja_regle = 0;
    +
    +            // Definition of $dir and $file
    +			if ($object->specimen)
    +			{
    +				$dir = $conf->commande->dir_output;
    +				$file = $dir . "/SPECIMEN.pdf";
    +			}
    +			else
    +			{
    +				$objectref = dol_sanitizeFileName($object->ref);
    +				$dir = $conf->commande->dir_output . "/" . $objectref;
    +				$file = $dir . "/" . $objectref . ".pdf";
    +			}
    +
    +			if (! file_exists($dir))
    +			{
    +				if (dol_mkdir($dir) < 0)
    +				{
    +					$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
    +					return 0;
    +				}
    +			}
    +
    +			if (file_exists($dir))
    +			{
    +				// Add pdfgeneration hook
    +				if (! is_object($hookmanager))
    +				{
    +					include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    +					$hookmanager=new HookManager($this->db);
    +				}
    +				$hookmanager->initHooks(array('pdfgeneration'));
    +				$parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
    +				global $action;
    +				$reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    +
    +				// Create pdf instance
    +				$pdf=pdf_getInstance($this->format);
    +				$default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
    +				$pdf->SetAutoPageBreak(1,0);
    +
    +				$heightforinfotot = 40;	// Height reserved to output the info and total part
    +		        $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5);	// Height reserved to output the free text on last page
    +		        $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22);	// Height reserved to output the footer (value include bottom margin)
    +
    +                if (class_exists('TCPDF'))
    +                {
    +                    $pdf->setPrintHeader(false);
    +                    $pdf->setPrintFooter(false);
    +                }
    +                $pdf->SetFont(pdf_getPDFFont($outputlangs));
    +                // Set path to the background PDF File
    +                if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
    +                {
    +                    $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
    +                    $tplidx = $pdf->importPage(1);
    +                }
    +
    +				$pdf->Open();
    +				$pagenb=0;
    +				$pdf->SetDrawColor(128,128,128);
    +
    +				$pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
    +				$pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle"));
    +				$pdf->SetCreator("Dolibarr ".DOL_VERSION);
    +				$pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
    +				$pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
    +				if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
    +
    +				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
    +
    +				/// Does we have at least one line with discount $this->atleastonediscount
    +				foreach ($object->lines as $line) {
    +				    if ($line->remise_percent){
    +				        $this->atleastonediscount = true;
    +				        break;
    +				    }
    +				}
    +
    +				if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS))
    +				{
    +					$this->posxpicture+=($this->postotalht - $this->posxdiscount);
    +					$this->posxtva+=($this->postotalht - $this->posxdiscount);
    +					$this->posxup+=($this->postotalht - $this->posxdiscount);
    +					$this->posxqty+=($this->postotalht - $this->posxdiscount);
    +					$this->posxdiscount+=($this->postotalht - $this->posxdiscount);
    +					//$this->postotalht;
    +				}
    +
    +				// New page
    +				$pdf->AddPage();
    +				if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +				$pagenb++;
    +				$top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
    +				$pdf->SetFont('','', $default_font_size - 1);
    +				$pdf->MultiCell(0, 3, '');		// Set interline to 3
    +				$pdf->SetTextColor(0,0,0);
    +
    +
    +				$tab_top = 90+$top_shift;
    +				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
    +
    +				// Incoterm
    +				if ($conf->incoterm->enabled)
    +				{
    +					$desc_incoterms = $object->getIncotermsForPDF();
    +					if ($desc_incoterms)
    +					{
    +						$tab_top -= 2;
    +
    +						$pdf->SetFont('','', $default_font_size - 1);
    +						$pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
    +						$nexY = $pdf->GetY();
    +						$height_incoterms=$nexY-$tab_top;
    +
    +						// Rect prend une longueur en 3eme param
    +						$pdf->SetDrawColor(192,192,192);
    +						$pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
    +
    +						$tab_top = $nexY+6;
    +					}
    +				}
    +
    +				// Affiche notes
    +				$notetoshow=empty($object->note_public)?'':$object->note_public;
    +				if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
    +				{
    +					// Get first sale rep
    +					if (is_object($object->thirdparty))
    +					{
    +						$salereparray=$object->thirdparty->getSalesRepresentatives($user);
    +						$salerepobj=new User($this->db);
    +						$salerepobj->fetch($salereparray[0]['id']);
    +						if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
    +					}
    +				}
    +
    +				$pagenb = $pdf->getPage();
    +				if ($notetoshow)
    +				{
    +				    $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
    +				    $pageposbeforenote = $pagenb;
    +
    +				    $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
    +				    complete_substitutions_array($substitutionarray, $outputlangs, $object);
    +				    $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    +
    +					$tab_top -= 2;
    +
    +				    $pdf->startTransaction();
    +
    +				    $pdf->SetFont('','', $default_font_size - 1);
    +				    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
    +				    // Description
    +				    $pageposafternote=$pdf->getPage();
    +				    $posyafter = $pdf->GetY();
    +
    +				    if($pageposafternote>$pageposbeforenote )
    +				    {
    +				        $pdf->rollbackTransaction(true);
    +
    +				        // prepar pages to receive notes
    +				        while ($pagenb < $pageposafternote) {
    +				            $pdf->AddPage();
    +				            $pagenb++;
    +				            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +				            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +				            // $this->_pagefoot($pdf,$object,$outputlangs,1);
    +				            $pdf->setTopMargin($tab_top_newpage);
    +				            // The only function to edit the bottom margin of current page to set it.
    +				            $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +				        }
    +
    +				        // back to start
    +				        $pdf->setPage($pageposbeforenote);
    +				        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +				        $pdf->SetFont('','', $default_font_size - 1);
    +				        $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
    +				        $pageposafternote=$pdf->getPage();
    +
    +				        $posyafter = $pdf->GetY();
    +
    +				        if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
    +				        {
    +				            $pdf->AddPage('','',true);
    +				            $pagenb++;
    +				            $pageposafternote++;
    +				            $pdf->setPage($pageposafternote);
    +				            $pdf->setTopMargin($tab_top_newpage);
    +				            // The only function to edit the bottom margin of current page to set it.
    +				            $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +				            //$posyafter = $tab_top_newpage;
    +				        }
    +
    +
    +				        // apply note frame to previus pages
    +				        $i = $pageposbeforenote;
    +				        while ($i < $pageposafternote) {
    +				            $pdf->setPage($i);
    +
    +
    +				            $pdf->SetDrawColor(128,128,128);
    +				            // Draw note frame
    +				            if($i>$pageposbeforenote){
    +				                $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
    +				                $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
    +				            }
    +				            else{
    +				                $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
    +				                $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
    +				            }
    +
    +				            // Add footer
    +				            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +				            $this->_pagefoot($pdf,$object,$outputlangs,1);
    +
    +				            $i++;
    +				        }
    +
    +				        // apply note frame to last page
    +				        $pdf->setPage($pageposafternote);
    +				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +				        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +				        $height_note=$posyafter-$tab_top_newpage;
    +				        $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    +				    }
    +				    else // No pagebreak
    +				    {
    +				        $pdf->commitTransaction();
    +				        $posyafter = $pdf->GetY();
    +				        $height_note=$posyafter-$tab_top;
    +				        $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    +
    +
    +				        if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
    +				        {
    +				            // not enough space, need to add page
    +				            $pdf->AddPage('','',true);
    +				            $pagenb++;
    +				            $pageposafternote++;
    +				            $pdf->setPage($pageposafternote);
    +				            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +				            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +
    +				            $posyafter = $tab_top_newpage;
    +				        }
    +				    }
    +
    +				    $tab_height = $tab_height - $height_note;
    +				    $tab_top = $posyafter +6;
    +				}
    +				else
    +				{
    +					$height_note=0;
    +				}
    +
    +				$iniY = $tab_top + 7;
    +				$curY = $tab_top + 7;
    +				$nexY = $tab_top + 7;
    +
    +				// Use new auto collum system
    +				$this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    +
    +				// Loop on each lines
    +				$pageposbeforeprintlines=$pdf->getPage();
    +				$pagenb = $pageposbeforeprintlines;
    +				for ($i = 0 ; $i < $nblignes ; $i++)
    +				{
    +					$curY = $nexY;
    +					$pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
    +					$pdf->SetTextColor(0,0,0);
    +
    +					$pdf->setTopMargin($tab_top_newpage);
    +					$pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
    +					$pageposbefore=$pdf->getPage();
    +
    +					// Description of product line
    +					$curX = $this->posxdesc-1;
    +
    +					$showpricebeforepagebreak=1;
    +
    +					if($this->getColumnStatus('desc'))
    +					{
    +    					$pdf->startTransaction();
    +    					pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    +    					$pageposafter=$pdf->getPage();
    +    					if ($pageposafter > $pageposbefore)	// There is a pagebreak
    +    					{
    +    						$pdf->rollbackTransaction(true);
    +    						$pageposafter=$pageposbefore;
    +    						//print $pageposafter.'-'.$pageposbefore;exit;
    +    						$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
    +    						pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    +    						$pageposafter=$pdf->getPage();
    +    						$posyafter=$pdf->GetY();
    +    						if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot)))	// There is no space left for total+free text
    +    						{
    +    							if ($i == ($nblignes-1))	// No more lines, and no space left to show total, so we create a new page
    +    							{
    +    								$pdf->AddPage('','',true);
    +    								if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +    								//if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +    								$pdf->setPage($pageposafter+1);
    +    							}
    +    						}
    +    						else
    +    						{
    +    							// We found a page break
    +    							$showpricebeforepagebreak=0;
    +    						}
    +    					}
    +    					else	// No pagebreak
    +    					{
    +    						$pdf->commitTransaction();
    +    					}
    +    					$posYAfterDescription=$pdf->GetY();
    +					}
    +
    +					$nexY = $pdf->GetY();
    +					$pageposafter=$pdf->getPage();
    +
    +					$pdf->setPage($pageposbefore);
    +					$pdf->setTopMargin($this->marge_haute);
    +					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +
    +					// We suppose that a too long description is moved completely on next page
    +					if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
    +						$pdf->setPage($pageposafter); $curY = $tab_top_newpage;
    +					}
    +
    +					$pdf->SetFont('','',  $default_font_size - 1);   // On repositionne la police par defaut
    +
    +					// VAT Rate
    +					if ($this->getColumnStatus('vat'))
    +					{
    +					    $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Unit price before discount
    +					if ($this->getColumnStatus('subprice'))
    +					{
    +					    $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Quantity
    +					// Enough for 6 chars
    +					if ($this->getColumnStatus('qty'))
    +					{
    +					    $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +
    +					// Unit
    +					if ($this->getColumnStatus('unit'))
    +					{
    +					    $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
    +					    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Discount on line
    +					if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
    +					{
    +					    $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Total HT line
    +					if ($this->getColumnStatus('totalexcltax'))
    +					{
    +					    $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +
    +					$parameters=array(
    +					    'object' => $object,
    +					    'i' => $i,
    +					    'pdf' =>& $pdf,
    +					    'curY' =>& $curY,
    +					    'nexY' =>& $nexY,
    +					    'outputlangs' => $outputlangs,
    +					    'hidedetails' => $hidedetails
    +					);
    +					$reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    +
    +
    +					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
    +					if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
    +					else $tvaligne=$object->lines[$i]->total_tva;
    +
    +					$localtax1ligne=$object->lines[$i]->total_localtax1;
    +					$localtax2ligne=$object->lines[$i]->total_localtax2;
    +					$localtax1_rate=$object->lines[$i]->localtax1_tx;
    +					$localtax2_rate=$object->lines[$i]->localtax2_tx;
    +					$localtax1_type=$object->lines[$i]->localtax1_type;
    +					$localtax2_type=$object->lines[$i]->localtax2_type;
    +
    +					if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
    +					if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
    +					if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
    +
    +					$vatrate=(string) $object->lines[$i]->tva_tx;
    +
    +					// Retrieve type from database for backward compatibility with old records
    +					if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
    +					&& (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
    +					{
    +						$localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc);
    +						$localtax1_type = $localtaxtmp_array[0];
    +						$localtax2_type = $localtaxtmp_array[2];
    +					}
    +
    +				    // retrieve global local tax
    +					if ($localtax1_type && $localtax1ligne != 0)
    +						$this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
    +					if ($localtax2_type && $localtax2ligne != 0)
    +						$this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
    +
    +					if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
    +					if (! isset($this->tva[$vatrate])) 				$this->tva[$vatrate]=0;
    +					$this->tva[$vatrate] += $tvaligne;
    +
    +					// Add line
    +					if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
    +					{
    +						$pdf->setPage($pageposafter);
    +						$pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
    +						//$pdf->SetDrawColor(190,190,200);
    +						$pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
    +						$pdf->SetLineStyle(array('dash'=>0));
    +					}
    +
    +					$nexY+=2;    // Passe espace entre les lignes
    +
    +					// Detect if some page were added automatically and output _tableau for past pages
    +					while ($pagenb < $pageposafter)
    +					{
    +						$pdf->setPage($pagenb);
    +						if ($pagenb == $pageposbeforeprintlines)
    +						{
    +							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
    +						}
    +						else
    +						{
    +							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
    +						}
    +						$this->_pagefoot($pdf,$object,$outputlangs,1);
    +						$pagenb++;
    +						$pdf->setPage($pagenb);
    +						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +					}
    +					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
    +					{
    +					    if ($pagenb == $pageposafter)
    +						{
    +							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
    +						}
    +						else
    +						{
    +							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
    +						}
    +						$this->_pagefoot($pdf,$object,$outputlangs,1);
    +						// New page
    +						$pdf->AddPage();
    +						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +						$pagenb++;
    +						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +					}
    +				}
    +
    +				// Show square
    +				if ($pagenb == $pageposbeforeprintlines)
    +					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
    +				else
    +					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
    +				$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
    +
    +				// Affiche zone infos
    +				$posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
    +
    +				// Affiche zone totaux
    +				$posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
    +
    +				// Affiche zone versements
    +				/*
    +				if ($deja_regle)
    +				{
    +					$posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
    +				}
    +				*/
    +
    +				// Pied de page
    +				$this->_pagefoot($pdf, $object, $outputlangs);
    +				if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages();
    +
    +				$pdf->Close();
    +
    +				$pdf->Output($file, 'F');
    +
    +				// Add pdfgeneration hook
    +				$hookmanager->initHooks(array('pdfgeneration'));
    +				$parameters=array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
    +				global $action;
    +				$reshook=$hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action);    // Note that $action and $object may have been modified by some hooks
    +
    +				if (! empty($conf->global->MAIN_UMASK))
    +					@chmod($file, octdec($conf->global->MAIN_UMASK));
    +
    +				$this->result = array('fullpath'=>$file);
    +
    +				return 1;   // Pas d'erreur
    +			}
    +			else
    +			{
    +				$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
    +				return 0;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$langs->transnoentities("ErrorConstantNotDefined","COMMANDE_OUTPUTDIR");
    +			return 0;
    +		}
    +	}
    +
    +	/**
    +	 *  Show payments table
    +   *
    +	 *  @param	TCPDF		$pdf     		Object PDF
    +	 *  @param  Object		$object			Object order
    +	 *	@param	int			$posy			Position y in PDF
    +	 *	@param	Translate	$outputlangs	Object langs for output
    +	 *	@return int							<0 if KO, >0 if OK
    +	 */
    +	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
    +	{
    +	}
    +
    +	/**
    +	 *   Show miscellaneous information (payment mode, payment term, ...)
    +	 *
    +	 *   @param		TCPDF		$pdf     		Object PDF
    +	 *   @param		Object		$object			Object to show
    +	 *   @param		int			$posy			Y
    +	 *   @param		Translate	$outputlangs	Langs object
    +	 *   @return	void
    +	 */
    +	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
    +	{
    +		global $conf;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +        // If France, show VAT mention if not applicable
    +		if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
    +
    +			$posy=$pdf->GetY()+4;
    +		}
    +
    +		$posxval=52;
    +
    +		// Show payments conditions
    +		if ($object->cond_reglement_code || $object->cond_reglement)
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("PaymentConditions").':';
    +			$pdf->MultiCell(43, 4, $titre, 0, 'L');
    +
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
    +			$lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
    +			$pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
    +
    +			$posy=$pdf->GetY()+3;
    +		}
    +
    +        // Check a payment mode is defined
    +        /* Not used with orders
    +		if (empty($object->mode_reglement_code)
    +        	&& ! $conf->global->FACTURE_CHQ_NUMBER
    +        	&& ! $conf->global->FACTURE_RIB_NUMBER)
    +		{
    +            $pdf->SetXY($this->marge_gauche, $posy);
    +            $pdf->SetTextColor(200,0,0);
    +            $pdf->SetFont('','B', $default_font_size - 2);
    +            $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
    +            $pdf->SetTextColor(0,0,0);
    +
    +            $posy=$pdf->GetY()+1;
    +        }
    +		*/
    +		/* TODO
    +		else if (! empty($object->availability_code))
    +		{
    +            $pdf->SetXY($this->marge_gauche, $posy);
    +            $pdf->SetTextColor(200,0,0);
    +            $pdf->SetFont('','B', $default_font_size - 2);
    +            $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0);
    +            $pdf->SetTextColor(0,0,0);
    +
    +            $posy=$pdf->GetY()+1;
    +		}*/
    +
    +	    // Show planed date of delivery
    +        if (! empty($object->date_livraison))
    +		{
    +            $outputlangs->load("sendings");
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
    +			$pdf->MultiCell(80, 4, $titre, 0, 'L');
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true);
    +			$pdf->MultiCell(80, 4, $dlp, 0, 'L');
    +
    +            $posy=$pdf->GetY()+1;
    +		}
    +        elseif ($object->availability_code || $object->availability)    // Show availability conditions
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
    +			$pdf->MultiCell(80, 4, $titre, 0, 'L');
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset(isset($object->availability)?$object->availability:'');
    +			$lib_availability=str_replace('\n',"\n",$lib_availability);
    +			$pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
    +
    +			$posy=$pdf->GetY()+1;
    +		}
    +
    +      	// Show payment mode
    +        if ($object->mode_reglement_code
    +        	 && $object->mode_reglement_code != 'CHQ'
    +           	 && $object->mode_reglement_code != 'VIR')
    +           	 {
    +	            $pdf->SetFont('','B', $default_font_size - 2);
    +	            $pdf->SetXY($this->marge_gauche, $posy);
    +	            $titre = $outputlangs->transnoentities("PaymentMode").':';
    +	            $pdf->MultiCell(80, 5, $titre, 0, 'L');
    +
    +				$pdf->SetFont('','', $default_font_size - 2);
    +	            $pdf->SetXY($posxval, $posy);
    +	            $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
    +	            $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
    +
    +	            $posy=$pdf->GetY()+2;
    +           	 }
    +
    +		// Show payment mode CHQ
    +        if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
    +        {
    +        	// Si mode reglement non force ou si force a CHQ
    +	        if (! empty($conf->global->FACTURE_CHQ_NUMBER))
    +	        {
    +	            if ($conf->global->FACTURE_CHQ_NUMBER > 0)
    +	            {
    +	                $account = new Account($this->db);
    +	                $account->fetch($conf->global->FACTURE_CHQ_NUMBER);
    +
    +	                $pdf->SetXY($this->marge_gauche, $posy);
    +	                $pdf->SetFont('','B', $default_font_size - 3);
    +	                $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
    +		            $posy=$pdf->GetY()+1;
    +
    +		            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
    +		            {
    +		                $pdf->SetXY($this->marge_gauche, $posy);
    +		                $pdf->SetFont('','', $default_font_size - 3);
    +		                $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
    +			            $posy=$pdf->GetY()+2;
    +		            }
    +	            }
    +	            if ($conf->global->FACTURE_CHQ_NUMBER == -1)
    +	            {
    +	                $pdf->SetXY($this->marge_gauche, $posy);
    +	                $pdf->SetFont('','B', $default_font_size - 3);
    +	                $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
    +		            $posy=$pdf->GetY()+1;
    +
    +		            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
    +		            {
    +			            $pdf->SetXY($this->marge_gauche, $posy);
    +		                $pdf->SetFont('','', $default_font_size - 3);
    +		                $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
    +			            $posy=$pdf->GetY()+2;
    +		            }
    +	            }
    +	        }
    +		}
    +
    +        // If payment mode not forced or forced to VIR, show payment with BAN
    +        if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
    +        {
    +			if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
    +			{
    +				$bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
    +				if (! empty($object->fk_bank)) $bankid=$object->fk_bank;   // For backward compatibility when object->fk_account is forced with object->fk_bank
    +				$account = new Account($this->db);
    +				$account->fetch($bankid);
    +
    +				$curx=$this->marge_gauche;
    +				$cury=$posy;
    +
    +				$posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
    +
    +				$posy+=2;
    +			}
    +        }
    +
    +		return $posy;
    +	}
    +
    +
    +	/**
    +	 *	Show total to pay
    +	 *
    +	 *	@param	TCPDF		$pdf           Object PDF
    +	 *	@param  Facture		$object         Object invoice
    +	 *	@param  int			$deja_regle     Montant deja regle
    +	 *	@param	int			$posy			Position depart
    +	 *	@param	Translate	$outputlangs	Objet langs
    +	 *	@return int							Position pour suite
    +	 */
    +	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
    +	{
    +	    global $conf,$mysoc;
    +
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$tab2_top = $posy;
    +		$tab2_hl = 4;
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// Tableau total
    +        $col1x = 120; $col2x = 170;
    +		if ($this->page_largeur < 210) // To work with US executive format
    +		{
    +			$col2x-=20;
    +		}
    +		$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
    +
    +		$useborder=0;
    +		$index = 0;
    +
    +		// Total HT
    +		$pdf->SetFillColor(255,255,255);
    +		$pdf->SetXY($col1x, $tab2_top + 0);
    +		$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
    +
    +		$total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
    +		$pdf->SetXY($col2x, $tab2_top + 0);
    +		$pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1);
    +
    +		// Show VAT by rates and total
    +		$pdf->SetFillColor(248,248,248);
    +
    +		$total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
    +
    +		$this->atleastoneratenotnull=0;
    +		if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
    +		{
    +			$tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
    +			if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
    +			{
    +				// Nothing to do
    +			}
    +			else
    +			{
    +				//Local tax 1 before VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
    +				//{
    +					foreach( $this->localtax1 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey!=0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +	      		//}
    +				//Local tax 2 before VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
    +				//{
    +					foreach( $this->localtax2 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey!=0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +				//}
    +				// VAT
    +				foreach($this->tva as $tvakey => $tvaval)
    +				{
    +					if ($tvakey != 0)    // On affiche pas taux 0
    +					{
    +						$this->atleastoneratenotnull++;
    +
    +						$index++;
    +						$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +						$tvacompl='';
    +						if (preg_match('/\*/',$tvakey))
    +						{
    +							$tvakey=str_replace('*','',$tvakey);
    +							$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +						}
    +						$totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
    +						$totalvat.=vatrate($tvakey,1).$tvacompl;
    +						$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +						$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +						$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +					}
    +				}
    +
    +				//Local tax 1 after VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
    +				//{
    +					foreach( $this->localtax1 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey != 0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
    +
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +	      		//}
    +				//Local tax 2 after VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
    +				//{
    +					foreach( $this->localtax2 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey != 0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
    +
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +				//}
    +
    +				// Total TTC
    +				$index++;
    +				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +				$pdf->SetTextColor(0,0,60);
    +				$pdf->SetFillColor(224,224,224);
    +				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
    +
    +				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
    +			}
    +		}
    +
    +		$pdf->SetTextColor(0,0,0);
    +
    +        $creditnoteamount=0;
    +        $depositsamount=0;
    +		//$creditnoteamount=$object->getSumCreditNotesUsed();
    +		//$depositsamount=$object->getSumDepositsUsed();
    +		//print "x".$creditnoteamount."-".$depositsamount;exit;
    +		$resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
    +		if (! empty($object->paye)) $resteapayer=0;
    +
    +		if ($deja_regle > 0)
    +		{
    +			// Already paid + Deposits
    +			$index++;
    +
    +			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
    +			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
    +
    +			$index++;
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->SetFillColor(224,224,224);
    +			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
    +
    +			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
    +
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->SetTextColor(0,0,0);
    +		}
    +
    +		$index++;
    +		return ($tab2_top + ($tab2_hl * $index));
    +	}
    +
    +	/**
    +	 *   Show table for lines
    +	 *
    +	 *   @param		TCPDF		$pdf     		Object PDF
    +	 *   @param		string		$tab_top		Top position of table
    +	 *   @param		string		$tab_height		Height of table (rectangle)
    +	 *   @param		int			$nexY			Y (not used)
    +	 *   @param		Translate	$outputlangs	Langs object
    +	 *   @param		int			$hidetop		1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
    +	 *   @param		int			$hidebottom		Hide bottom bar of array
    +	 *   @param		string		$currency		Currency code
    +	 *   @return	void
    +	 */
    +	private function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
    +	{
    +		global $conf;
    +
    +		// Force to disable hidetop and hidebottom
    +		$hidebottom=0;
    +		if ($hidetop) $hidetop=-1;
    +
    +		$currency = !empty($currency) ? $currency : $conf->currency;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		// Amount in (at tab_top - 1)
    +		$pdf->SetTextColor(0,0,0);
    +		$pdf->SetFont('','', $default_font_size - 2);
    +
    +		if (empty($hidetop))
    +		{
    +			$titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
    +			$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
    +			$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
    +
    +			//$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
    +			if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
    +		}
    +
    +		$pdf->SetDrawColor(128,128,128);
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// Output Rect
    +		$this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
    +
    +
    +		foreach ($this->cols as $colKey => $colDef)
    +		{
    +		    if(!$this->getColumnStatus($colKey)) continue;
    +
    +		    // get title label
    +		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    +
    +		    // Add column separator
    +		    if(!empty($colDef['border-left'])){
    +		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
    +		    }
    +
    +		    if (empty($hidetop))
    +		    {
    +		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    +
    +		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
    +		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
    +		    }
    +		}
    +
    +		if (empty($hidetop)){
    +			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
    +		}
    +	}
    +
    +	/**
    +	 *  Show top header of page.
    +	 *
    +	 *  @param	TCPDF		$pdf     		Object PDF
    +	 *  @param  Object		$object     	Object to show
    +	 *  @param  int	    	$showaddress    0=no, 1=yes
    +	 *  @param  Translate	$outputlangs	Object lang for output
    +	 *  @param	string		$titlekey		Translation key to show as title of document
    +	 *  @return	void
    +	 */
    +	private function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="PdfOrderTitle")
    +	{
    +		global $conf,$langs,$hookmanager;
    +
    +		// Translations
    +		$outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies"));
    +
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
    +
    +		// Show Draft Watermark
    +		if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) )
    +		{
    +            pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_DRAFT_WATERMARK);
    +		}
    +
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->SetFont('','B', $default_font_size + 3);
    +
    +		$posy=$this->marge_haute;
    +		$posx=$this->page_largeur-$this->marge_droite-100;
    +
    +		$pdf->SetXY($this->marge_gauche,$posy);
    +
    +		// Logo
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
    +		{
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
    +			{
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B', $default_font_size -2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
    +			}
    +			else
    +			{
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    +			}
    +		}
    +
    +		$pdf->SetFont('','B', $default_font_size + 3);
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$title=$outputlangs->transnoentities($titlekey);
    +		$pdf->MultiCell(100, 3, $title, '', 'R');
    +
    +		$pdf->SetFont('','B',$default_font_size);
    +
    +		$posy+=5;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R');
    +
    +		$posy+=1;
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		if ($object->ref_client)
    +		{
    +			$posy+=5;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
    +		}
    +
    +		$posy+=4;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("OrderDate")." : " . dol_print_date($object->date,"%d %b %Y",false,$outputlangs,true), '', 'R');
    +
    +		// Get contact
    +		if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
    +		{
    +		    $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
    +		    if (count($arrayidcontact) > 0)
    +		    {
    +                $usertmp=new User($this->db);
    +		        $usertmp->fetch($arrayidcontact[0]);
    +                $posy+=4;
    +                $pdf->SetXY($posx,$posy);
    +		        $pdf->SetTextColor(0,0,60);
    +		        $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
    +		    }
    +		}
    +
    +		$posy+=2;
    +
    +		$top_shift = 0;
    +		// Show list of linked objects
    +		$current_y = $pdf->getY();
    +		$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
    +		if ($current_y < $pdf->getY())
    +		{
    +			$top_shift = $pdf->getY() - $current_y;
    +		}
    +
    +		if ($showaddress)
    +		{
    +			// Sender properties
    +			$carac_emetteur='';
    +		 	// Add internal contact of proposal if defined
    +			$arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
    +		 	if (count($arrayidcontact) > 0)
    +		 	{
    +		 		$object->fetch_user($arrayidcontact[0]);
    +		 		$labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name"));
    +		 		$carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
    +		 	}
    +
    +		 	$carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
    +
    +			// Show sender
    +			$posy=42+$top_shift;
    +			$posx=$this->marge_gauche;
    +			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
    +			$hautcadre=40;
    +
    +			// Show sender frame
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posx,$posy-5);
    +			$pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetFillColor(230,230,230);
    +			$pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
    +			$pdf->SetTextColor(0,0,60);
    +
    +			// Show sender name
    +			$pdf->SetXY($posx+2,$posy+3);
    +			$pdf->SetFont('','B', $default_font_size);
    +			$pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
    +			$posy=$pdf->getY();
    +
    +			// Show sender information
    +			$pdf->SetXY($posx+2,$posy);
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
    +
    +
    +
    +			// If CUSTOMER contact defined on order, we use it
    +			$usecontact=false;
    +			$arrayidcontact=$object->getIdContact('external','CUSTOMER');
    +			if (count($arrayidcontact) > 0)
    +			{
    +				$usecontact=true;
    +				$result=$object->fetch_contact($arrayidcontact[0]);
    +			}
    +
    +			//Recipient name
    +			// On peut utiliser le nom de la societe du contact
    +			if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
    +				$thirdparty = $object->contact;
    +			} else {
    +				$thirdparty = $object->thirdparty;
    +			}
    +
    +			$carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
    +
    +			$carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target', $object);
    +
    +			// Show recipient
    +			$widthrecbox=100;
    +			if ($this->page_largeur < 210) $widthrecbox=84;	// To work with US executive format
    +			$posy=42+$top_shift;
    +			$posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
    +			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
    +
    +			// Show recipient frame
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posx+2,$posy-5);
    +			$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L');
    +			$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
    +
    +			// Show recipient name
    +			$pdf->SetXY($posx+2,$posy+3);
    +			$pdf->SetFont('','B', $default_font_size);
    +			$pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L');
    +
    +			$posy = $pdf->getY();
    +
    +			// Show recipient information
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->SetXY($posx+2,$posy);
    +			$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
    +		}
    +
    +		$pdf->SetTextColor(0,0,0);
    +		return $top_shift;
    +	}
    +
    +	/**
    +	 *   	Show footer of page. Need this->emetteur object
    +     *
    +	 *   	@param	TCPDF		$pdf     			PDF
    +	 * 		@param	Object		$object				Object to show
    +	 *      @param	Translate	$outputlangs		Object lang for output
    +	 *      @param	int			$hidefreetext		1=Hide free text
    +	 *      @return	int								Return height of bottom margin including footer text
    +	 */
    +	private function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
    +	{
    +		global $conf;
    +		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
    +		return pdf_pagefoot($pdf,$outputlangs,'ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
    +	}
    +
    +
    +
    +	/**
    +	 *   	Define Array Column Field
    +	 *
    +	 *   	@param	object			$object    		common object
    +	 *   	@param	Translate		$outputlangs    langs
    +	 *      @param	int				$hidedetails	Do not show line details
    +	 *      @param	int				$hidedesc		Do not show desc
    +	 *      @param	int				$hideref		Do not show ref
    +	 *      @return	null
    +	 */
    +    public function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
    +	    global $conf, $hookmanager;
    +
    +	    // Default field style for content
    +	    $this->defaultContentsFieldsStyle = array(
    +	        'align' => 'R', // R,C,L
    +	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	    );
    +
    +	    // Default field style for content
    +	    $this->defaultTitlesFieldsStyle = array(
    +	        'align' => 'C', // R,C,L
    +	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	    );
    +
    +	    /*
    +	     * For exemple
    +	     $this->cols['theColKey'] = array(
    +	     'rank' => $rank, // int : use for ordering columns
    +	     'width' => 20, // the column width in mm
    +	     'title' => array(
    +	     'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
    +	     'label' => ' ', // the final label : used fore final generated text
    +	     'align' => 'L', // text alignement :  R,C,L
    +	     'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	     ),
    +	     'content' => array(
    +	     'align' => 'L', // text alignement :  R,C,L
    +	     'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	     ),
    +	     );
    +	     */
    +
    +	    $rank=0; // do not use negative rank
    +	    $this->cols['desc'] = array(
    +	        'rank' => $rank,
    +	        'width' => false, // only for desc
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'Designation', // use lang key is usefull in somme case with module
    +	            'align' => 'L',
    +	            // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
    +	            // 'label' => ' ', // the final label
    +	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	        'content' => array(
    +	            'align' => 'L',
    +	        ),
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['photo'] = array(
    +	        'rank' => $rank,
    +	        'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Photo',
    +	            'label' => ' '
    +	        ),
    +	        'content' => array(
    +	            'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	        'border-left' => false, // remove left line separator
    +	    );
    +
    +	    if (! empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE))
    +	    {
    +	        $this->cols['photo']['status'] = true;
    +	    }
    +
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['vat'] = array(
    +	        'rank' => $rank,
    +	        'status' => false,
    +	        'width' => 16, // in mm
    +	        'title' => array(
    +	            'textkey' => 'VAT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
    +	    {
    +	        $this->cols['vat']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['subprice'] = array(
    +	        'rank' => $rank,
    +	        'width' => 19, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'PriceUHT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['qty'] = array(
    +	        'rank' => $rank,
    +	        'width' => 16, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'Qty'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['progress'] = array(
    +	        'rank' => $rank,
    +	        'width' => 19, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Progress'
    +	        ),
    +	        'border-left' => false, // add left line separator
    +	    );
    +
    +	    if($this->situationinvoice)
    +	    {
    +	        $this->cols['progress']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['unit'] = array(
    +	        'rank' => $rank,
    +	        'width' => 11, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Unit'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +	    if($conf->global->PRODUCT_USE_UNITS){
    +	        $this->cols['unit']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['discount'] = array(
    +	        'rank' => $rank,
    +	        'width' => 13, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'ReductionShort'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +	    if ($this->atleastonediscount){
    +	        $this->cols['discount']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['totalexcltax'] = array(
    +	        'rank' => $rank,
    +	        'width' => 26, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'TotalHT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +
    +	    $parameters=array(
    +	        'object' => $object,
    +	        'outputlangs' => $outputlangs,
    +	        'hidedetails' => $hidedetails,
    +	        'hidedesc' => $hidedesc,
    +	        'hideref' => $hideref
    +	    );
    +
    +	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
    +	    if ($reshook < 0)
    +	    {
    +	        setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
    +	    }
    +	    elseif (empty($reshook))
    +	    {
    +	        $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
    +	    }
    +	    else
    +	    {
    +	        $this->cols = $hookmanager->resArray;
    +	    }
    +	}
    +}
    diff --git a/htdocs/core/modules/commande/doc/pdf_proforma.modules.php b/htdocs/core/modules/commande/doc/pdf_proforma.modules.php
    index 918b338aa12..8d99fc00378 100644
    --- a/htdocs/core/modules/commande/doc/pdf_proforma.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_proforma.modules.php
    @@ -73,6 +73,4 @@ class pdf_proforma extends pdf_einstein
     
     		parent::_pagehead($pdf, $object, $showaddress, $outputlangs, $titlekey);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/commande/mod_commande_marbre.php b/htdocs/core/modules/commande/mod_commande_marbre.php
    index 9941811006b..8345d694cff 100644
    --- a/htdocs/core/modules/commande/mod_commande_marbre.php
    +++ b/htdocs/core/modules/commande/mod_commande_marbre.php
    @@ -29,10 +29,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/commande/modules_commande.php';
      */
     class mod_commande_marbre extends ModeleNumRefCommandes
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='CO';
    -	var $error='';
    -	var $nom='Marbre';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='CO';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Marbre';
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name='Marbre';
     
     
         /**
    @@ -128,13 +148,14 @@ class mod_commande_marbre extends ModeleNumRefCommandes
     		$yymm = strftime("%y%m",$date);
     
         	if ($max >= (pow(10, 4) - 1)) $num=$max+1;	// If counter > 9999, we do not format on 4 chars, we take number as it is
    -    	else $num = sprintf("%04s",$max+1);
    +    	else $num = sprintf("%04s", $max+1);
     
     		dol_syslog("mod_commande_marbre::getNextValue return ".$this->prefix.$yymm."-".$num);
     		return $this->prefix.$yymm."-".$num;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -144,7 +165,7 @@ class mod_commande_marbre extends ModeleNumRefCommandes
     	 */
     	function commande_get_num($objsoc,$objforref)
     	{
    +        // phpcs:enable
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/commande/mod_commande_saphir.php b/htdocs/core/modules/commande/mod_commande_saphir.php
    index 2c8ae2ef3e9..588d6fffc6d 100644
    --- a/htdocs/core/modules/commande/mod_commande_saphir.php
    +++ b/htdocs/core/modules/commande/mod_commande_saphir.php
    @@ -33,9 +33,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/commande/modules_commande.php';
      */
     class mod_commande_saphir extends ModeleNumRefCommandes
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Saphir';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string nom
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Saphir';
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name='Saphir';
     
     
         /**
    @@ -45,7 +64,7 @@ class mod_commande_saphir extends ModeleNumRefCommandes
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -132,17 +151,17 @@ class mod_commande_saphir extends ModeleNumRefCommandes
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
     	 *  @param	Societe		$objsoc     Object third party
    -	 * 	@param	string		$objforref	Object for number to search
    +	 *  @param	string		$objforref	Object for number to search
     	 *  @return string      			Next free value
          */
         function commande_get_num($objsoc,$objforref)
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/commande/modules_commande.php b/htdocs/core/modules/commande/modules_commande.php
    index aa6da728f56..7a1ffea8792 100644
    --- a/htdocs/core/modules/commande/modules_commande.php
    +++ b/htdocs/core/modules/commande/modules_commande.php
    @@ -39,26 +39,27 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
      */
     abstract class ModelePDFCommandes extends CommonDocGenerator
     {
    -	var $error='';
     
    -	/**
    -	 *  Return list of active generation modules
    -	 *
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Return list of active generation modules
    +     *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
     	 */
    -	static function liste_modeles($db,$maxfilenamelength=0)
    +	static function liste_modeles($db, $maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
    -		$type='order';
    -		$liste=array();
    +		$type = 'order';
    +		$list = array();
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -		$liste=getListOfModels($db,$type,$maxfilenamelength);
    +		$list = getListOfModels($db, $type, $maxfilenamelength);
     
    -		return $liste;
    +		return $list;
     	}
     }
     
    @@ -71,7 +72,10 @@ abstract class ModelePDFCommandes extends CommonDocGenerator
     
     abstract class ModeleNumRefCommandes
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Return if a module can be used or not
    @@ -146,4 +150,4 @@ abstract class ModeleNumRefCommandes
     		if ($this->version) return $this->version;
     		return $langs->trans("NotAvailable");
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php
    index cd96e880d27..5a19d821653 100644
    --- a/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php
    +++ b/htdocs/core/modules/contract/doc/doc_generic_contract_odt.modules.php
    @@ -2,7 +2,8 @@
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2018		Ferran Marcet		<fmarcet@2byte.es>
    -*
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
     * 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
    @@ -37,10 +38,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_contract_odt extends ModelePDFContract
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -50,10 +64,10 @@ class doc_generic_contract_odt extends ModelePDFContract
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -97,8 +111,8 @@ class doc_generic_contract_odt extends ModelePDFContract
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array('companies', 'errors'));
     
     		$form = new Form($this->db);
     
    @@ -167,6 +181,7 @@ class doc_generic_contract_odt extends ModelePDFContract
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -180,6 +195,7 @@ class doc_generic_contract_odt extends ModelePDFContract
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -201,10 +217,8 @@ class doc_generic_contract_odt extends ModelePDFContract
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
     
     		if ($conf->contrat->dir_output)
     		{
    @@ -341,6 +355,7 @@ class doc_generic_contract_odt extends ModelePDFContract
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -354,8 +369,9 @@ class doc_generic_contract_odt extends ModelePDFContract
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				foreach($tmparray as $key=>$value)
    @@ -371,8 +387,9 @@ class doc_generic_contract_odt extends ModelePDFContract
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -406,9 +423,11 @@ class doc_generic_contract_odt extends ModelePDFContract
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -432,6 +451,7 @@ class doc_generic_contract_odt extends ModelePDFContract
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -443,7 +463,7 @@ class doc_generic_contract_odt extends ModelePDFContract
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
     						return -1;
     					}
    @@ -451,7 +471,7 @@ class doc_generic_contract_odt extends ModelePDFContract
     				else {
     					try {
     					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
     						return -1;
     					}
    @@ -477,6 +497,4 @@ class doc_generic_contract_odt extends ModelePDFContract
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php
    index 9fa86d24a19..fe0a79c6c8e 100644
    --- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php
    +++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php
    @@ -39,21 +39,72 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
      */
     class pdf_strato extends ModelePDFContract
     {
    -	var $db;
    -	var $name;
    -	var $description;
    -	var $type;
    +	/**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -	var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -	var $page_largeur;
    -	var $page_hauteur;
    -	var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +	/**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
     
     	/**
     	 * Issuer
    @@ -108,7 +159,8 @@ class pdf_strato extends ModelePDFContract
     		$this->posxdesc=$this->marge_gauche+1;
     	}
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		CommonObject	$object				Id of object to generate
    @@ -121,13 +173,14 @@ class pdf_strato extends ModelePDFContract
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$hookmanager,$mysoc;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "dict", "companies", "contracts"));
     
     		if ($conf->contrat->dir_output)
    @@ -486,10 +539,10 @@ class pdf_strato extends ModelePDFContract
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
     		global $conf,$langs;
    -		
    +
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "dict", "contract", "companies"));
     
     		pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
    @@ -668,6 +721,4 @@ class pdf_strato extends ModelePDFContract
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'CONTRACT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/contract/mod_contract_magre.php b/htdocs/core/modules/contract/mod_contract_magre.php
    index 54da8fc55c4..4769ec17f99 100644
    --- a/htdocs/core/modules/contract/mod_contract_magre.php
    +++ b/htdocs/core/modules/contract/mod_contract_magre.php
    @@ -29,10 +29,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/contract/modules_contract.php';
      */
     class mod_contract_magre extends ModelNumRefContracts
     {
    -	var $version='dolibarr';
    -	var $error = '';
    -	var $nom = 'Magre';
    -	var $code_auto=1;
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string nom
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Magre';
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name='Magre';
    +
    +	public $code_auto=1;
     
     	/**
     	 *	Return default description of numbering model
    @@ -117,8 +137,9 @@ class mod_contract_magre extends ModelNumRefContracts
     		return  $numFinal;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *	Return next value
    +	 *  Return next value
     	 *
     	 *	@param	Societe		$objsoc     third party object
     	 *	@param	Object		$objforref	contract object
    @@ -126,8 +147,7 @@ class mod_contract_magre extends ModelNumRefContracts
     	 */
         function contract_get_num($objsoc,$objforref)
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/contract/mod_contract_olive.php b/htdocs/core/modules/contract/mod_contract_olive.php
    index 6d22aebeb3d..993f4bf9bfb 100644
    --- a/htdocs/core/modules/contract/mod_contract_olive.php
    +++ b/htdocs/core/modules/contract/mod_contract_olive.php
    @@ -32,15 +32,33 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/contract/modules_contract.php';
      */
     class mod_contract_olive extends ModelNumRefContracts
     {
    +    /**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Olive';
     
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Olive';
     
    -	var $nom='Olive';					// Nom du modele
    -	var $code_modifiable = 1;				// Code modifiable
    -	var $code_modifiable_invalide = 1;		// Code modifiable si il est invalide
    -	var $code_modifiable_null = 1;			// Code modifiables si il est null
    -	var $code_null = 1;						// Code facultatif
    -	var $version='dolibarr';    		// 'development', 'experimental', 'dolibarr'
    -	var $code_auto = 0; 	                // Numerotation automatique
    +	public $code_modifiable = 1;				// Code modifiable
    +
    +	public $code_modifiable_invalide = 1;		// Code modifiable si il est invalide
    +
    +	public $code_modifiable_null = 1;			// Code modifiables si il est null
    +
    +	public $code_null = 1;						// Code facultatif
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';    		// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto = 0; 	                // Numerotation automatique
     
     
     	/**
    diff --git a/htdocs/core/modules/contract/mod_contract_serpis.php b/htdocs/core/modules/contract/mod_contract_serpis.php
    index 5dcb8a72baa..e91775f669c 100644
    --- a/htdocs/core/modules/contract/mod_contract_serpis.php
    +++ b/htdocs/core/modules/contract/mod_contract_serpis.php
    @@ -28,11 +28,32 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/contract/modules_contract.php';
      */
     class mod_contract_serpis extends ModelNumRefContracts
     {
    -	var $version='dolibarr';
    -	var $prefix='CT';
    -	var $error='';
    -	var $nom='Serpis';
    -	var $code_auto=1;
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $prefix='CT';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Serpis';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Serpis';
    +
    +	public $code_auto=1;
     
     
     	/**
    @@ -132,16 +153,17 @@ class mod_contract_serpis extends ModelNumRefContracts
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return next value
     	 *
     	 *	@param	Societe		$objsoc     third party object
    -	 *	@param	Object		$objforref	contract object
    +	 *	@param	Object		$objforref  contract object
     	 *	@return string      			Value if OK, 0 if KO
     	 */
     	function contract_get_num($objsoc,$objforref)
     	{
    +        // phpcs:enable
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/contract/modules_contract.php b/htdocs/core/modules/contract/modules_contract.php
    index 47a882b7b56..cd1ce4137cc 100644
    --- a/htdocs/core/modules/contract/modules_contract.php
    +++ b/htdocs/core/modules/contract/modules_contract.php
    @@ -37,9 +37,13 @@
      */
     abstract class ModelePDFContract extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of active generation modules
     	 *
    @@ -49,6 +53,7 @@ abstract class ModelePDFContract extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='contract';
    @@ -67,7 +72,10 @@ abstract class ModelePDFContract extends CommonDocGenerator
      */
     class ModelNumRefContracts
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Return if a module can be used or not
    diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php
    index c9d2b4984ad..8f6c10119c4 100644
    --- a/htdocs/core/modules/dons/html_cerfafr.modules.php
    +++ b/htdocs/core/modules/dons/html_cerfafr.modules.php
    @@ -38,7 +38,7 @@ class html_cerfafr extends ModeleDon
     	/**
     	 *  Constructor
     	 *
    -	 *  @param      DoliDb		$db      Database handler
    +	 *  @param      DoliDb      $db      Database handler
     	 */
     	function __construct($db)
     	{
    @@ -64,6 +64,7 @@ class html_cerfafr extends ModeleDon
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Write the object to document file to disk
     	 *
    @@ -74,6 +75,7 @@ class html_cerfafr extends ModeleDon
     	 */
     	function write_file($don,$outputlangs,$currency='')
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$mysoc;
     
     		$now=dol_now();
    @@ -81,12 +83,8 @@ class html_cerfafr extends ModeleDon
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    -		$outputlangs->load("donations");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "donations"));
     
     		$currency = !empty($currency) ? $currency : $conf->currency;
     
    @@ -167,7 +165,7 @@ class html_cerfafr extends ModeleDon
     				$form = str_replace('__DATE__',dol_print_date($don->date,'day',false,$outputlangs),$form);
     				//$form = str_replace('__IP__',$user->ip,$form); // TODO $user->ip not exist
     				$form = str_replace('__AMOUNT__', price($don->amount), $form);
    -				$form = str_replace('__AMOUNTLETTERS__',chiffre_en_lettre($don->amount),$form);
    +				$form = str_replace('__AMOUNTLETTERS__', $this->amountToLetters($don->amount),$form);
     				$form = str_replace('__CURRENCY__',$outputlangs->transnoentitiesnoconv("Currency".$currency),$form);
     				$form = str_replace('__CURRENCYCODE__',$conf->currency,$form);
     				$form = str_replace('__MAIN_INFO_SOCIETE_NOM__',$mysoc->name,$form);
    @@ -276,153 +274,163 @@ class html_cerfafr extends ModeleDon
     			return 0;
     		}
     	}
    -}
     
    -function chiffre_en_lettre($montant, $devise1='', $devise2='')
    -{
    -	if(empty($devise1)) $dev1='euros';
    -	else $dev1=$devise1;
    -	if(empty($devise2)) $dev2='centimes';
    -	else $dev2=$devise2;
    -	$valeur_entiere=intval($montant);
    -	$valeur_decimal=intval(round($montant-intval($montant), 2)*100);
    -	$dix_c=intval($valeur_decimal%100/10);
    -	$cent_c=intval($valeur_decimal%1000/100);
    -	$unite[1]=$valeur_entiere%10;
    -	$dix[1]=intval($valeur_entiere%100/10);
    -	$cent[1]=intval($valeur_entiere%1000/100);
    -	$unite[2]=intval($valeur_entiere%10000/1000);
    -	$dix[2]=intval($valeur_entiere%100000/10000);
    -	$cent[2]=intval($valeur_entiere%1000000/100000);
    -	$unite[3]=intval($valeur_entiere%10000000/1000000);
    -	$dix[3]=intval($valeur_entiere%100000000/10000000);
    -	$cent[3]=intval($valeur_entiere%1000000000/100000000);
    -	$chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf');
    -		$secon_c='';
    -		$trio_c='';
    -	for($i=1; $i<=3; $i++){
    -		$prim[$i]='';
    -		$secon[$i]='';
    -		$trio[$i]='';
    -		if($dix[$i]==0){
    +	/**
    +	 * numbers to letters
    +	 *
    +	 * @param   mixed   $montant    amount
    +	 * @param   mixed   $devise1    devise 1 ex: euro
    +	 * @param   mixed   $devise2    devise 2 ex: centimes
    +	 * @return string               amount in letters
    +	 */
    +	private function amountToLetters($montant, $devise1='', $devise2='')
    +	{
    +		$unite = array();
    +		$dix = array();
    +		$cent = array();
    +		if(empty($devise1)) $dev1='euros';
    +		else $dev1=$devise1;
    +		if(empty($devise2)) $dev2='centimes';
    +		else $dev2=$devise2;
    +		$valeur_entiere=intval($montant);
    +		$valeur_decimal=intval(round($montant-intval($montant), 2)*100);
    +		$dix_c=intval($valeur_decimal%100/10);
    +		$cent_c=intval($valeur_decimal%1000/100);
    +		$unite[1]=$valeur_entiere%10;
    +		$dix[1]=intval($valeur_entiere%100/10);
    +		$cent[1]=intval($valeur_entiere%1000/100);
    +		$unite[2]=intval($valeur_entiere%10000/1000);
    +		$dix[2]=intval($valeur_entiere%100000/10000);
    +		$cent[2]=intval($valeur_entiere%1000000/100000);
    +		$unite[3]=intval($valeur_entiere%10000000/1000000);
    +		$dix[3]=intval($valeur_entiere%100000000/10000000);
    +		$cent[3]=intval($valeur_entiere%1000000000/100000000);
    +		$chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf');
    +			$secon_c='';
    +			$trio_c='';
    +		for($i=1; $i<=3; $i++){
    +			$prim[$i]='';
     			$secon[$i]='';
    -			$prim[$i]=$chif[$unite[$i]];
    +			$trio[$i]='';
    +			if($dix[$i]==0){
    +				$secon[$i]='';
    +				$prim[$i]=$chif[$unite[$i]];
    +			}
    +			else if($dix[$i]==1){
    +				$secon[$i]='';
    +				$prim[$i]=$chif[($unite[$i]+10)];
    +			}
    +			else if($dix[$i]==2){
    +				if($unite[$i]==1){
    +				$secon[$i]='vingt et';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +				else {
    +				$secon[$i]='vingt';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +			}
    +			else if($dix[$i]==3){
    +				if($unite[$i]==1){
    +				$secon[$i]='trente et';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +				else {
    +				$secon[$i]='trente';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +			}
    +			else if($dix[$i]==4){
    +				if($unite[$i]==1){
    +				$secon[$i]='quarante et';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +				else {
    +				$secon[$i]='quarante';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +			}
    +			else if($dix[$i]==5){
    +				if($unite[$i]==1){
    +				$secon[$i]='cinquante et';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +				else {
    +				$secon[$i]='cinquante';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +			}
    +			else if($dix[$i]==6){
    +				if($unite[$i]==1){
    +				$secon[$i]='soixante et';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +				else {
    +				$secon[$i]='soixante';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +			}
    +			else if($dix[$i]==7){
    +				if($unite[$i]==1){
    +				$secon[$i]='soixante et';
    +				$prim[$i]=$chif[$unite[$i]+10];
    +				}
    +				else {
    +				$secon[$i]='soixante';
    +				$prim[$i]=$chif[$unite[$i]+10];
    +				}
    +			}
    +			else if($dix[$i]==8){
    +				if($unite[$i]==1){
    +				$secon[$i]='quatre-vingts et';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +				else {
    +				$secon[$i]='quatre-vingt';
    +				$prim[$i]=$chif[$unite[$i]];
    +				}
    +			}
    +			else if($dix[$i]==9){
    +				if($unite[$i]==1){
    +				$secon[$i]='quatre-vingts et';
    +				$prim[$i]=$chif[$unite[$i]+10];
    +				}
    +				else {
    +				$secon[$i]='quatre-vingts';
    +				$prim[$i]=$chif[$unite[$i]+10];
    +				}
    +			}
    +			if($cent[$i]==1) $trio[$i]='cent';
    +			else if($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents';
     		}
    -		else if($dix[$i]==1){
    -			$secon[$i]='';
    -			$prim[$i]=$chif[($unite[$i]+10)];
    -		}
    -		else if($dix[$i]==2){
    -			if($unite[$i]==1){
    -			$secon[$i]='vingt et';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -			else {
    -			$secon[$i]='vingt';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -		}
    -		else if($dix[$i]==3){
    -			if($unite[$i]==1){
    -			$secon[$i]='trente et';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -			else {
    -			$secon[$i]='trente';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -		}
    -		else if($dix[$i]==4){
    -			if($unite[$i]==1){
    -			$secon[$i]='quarante et';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -			else {
    -			$secon[$i]='quarante';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -		}
    -		else if($dix[$i]==5){
    -			if($unite[$i]==1){
    -			$secon[$i]='cinquante et';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -			else {
    -			$secon[$i]='cinquante';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -		}
    -		else if($dix[$i]==6){
    -			if($unite[$i]==1){
    -			$secon[$i]='soixante et';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -			else {
    -			$secon[$i]='soixante';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -		}
    -		else if($dix[$i]==7){
    -			if($unite[$i]==1){
    -			$secon[$i]='soixante et';
    -			$prim[$i]=$chif[$unite[$i]+10];
    -			}
    -			else {
    -			$secon[$i]='soixante';
    -			$prim[$i]=$chif[$unite[$i]+10];
    -			}
    -		}
    -		else if($dix[$i]==8){
    -			if($unite[$i]==1){
    -			$secon[$i]='quatre-vingts et';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -			else {
    -			$secon[$i]='quatre-vingt';
    -			$prim[$i]=$chif[$unite[$i]];
    -			}
    -		}
    -		else if($dix[$i]==9){
    -			if($unite[$i]==1){
    -			$secon[$i]='quatre-vingts et';
    -			$prim[$i]=$chif[$unite[$i]+10];
    -			}
    -			else {
    -			$secon[$i]='quatre-vingts';
    -			$prim[$i]=$chif[$unite[$i]+10];
    -			}
    -		}
    -		if($cent[$i]==1) $trio[$i]='cent';
    -		else if($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents';
    +
    +
    +		$chif2=array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix');
    +		$secon_c=$chif2[$dix_c];
    +		if($cent_c==1) $trio_c='cent';
    +		else if($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents';
    +
    +		if(($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1))
    +			$somme = $trio[3]. '  ' .$secon[3]. ' ' . $prim[3]. ' million ';
    +		else if(($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!=''))
    +			$somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions ';
    +		else
    +			$somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3];
    +
    +		if(($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1))
    +			$somme = $somme.' mille ';
    +		else if(($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!=''))
    +			$somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles ';
    +		else
    +			$somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2];
    +
    +		$somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1];
    +
    +		$somme = $somme. ' '. $dev1 .' ' ;
    +
    +		if(($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c==''))
    +			return $somme. ' et z&eacute;ro '. $dev2;
    +		else
    +			return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2;
     	}
    -
    -
    -$chif2=array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix');
    -	$secon_c=$chif2[$dix_c];
    -	if($cent_c==1) $trio_c='cent';
    -	else if($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents';
    -
    -	if(($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1))
    -		$somme = $trio[3]. '  ' .$secon[3]. ' ' . $prim[3]. ' million ';
    -	else if(($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!=''))
    -		$somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions ';
    -	else
    -		$somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3];
    -
    -	if(($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1))
    -		$somme = $somme.' mille ';
    -	else if(($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!=''))
    -		$somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles ';
    -	else
    -		$somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2];
    -
    -	$somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1];
    -
    -	$somme = $somme. ' '. $dev1 .' ' ;
    -
    -	if(($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c==''))
    -		return $somme. ' et z&eacute;ro '. $dev2;
    -	else
    -		return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2;
    -
     }
    diff --git a/htdocs/core/modules/dons/modules_don.php b/htdocs/core/modules/dons/modules_don.php
    index 4949cce94e1..d8fbe92c2c7 100644
    --- a/htdocs/core/modules/dons/modules_don.php
    +++ b/htdocs/core/modules/dons/modules_don.php
    @@ -34,17 +34,22 @@ require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
      */
     abstract class ModeleDon extends CommonDocGenerator
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return list of active generation modules
          *
    -     *  @param	DoliDB	$db     			Database handler
    -     *  @param  integer	$maxfilenamelength  Max length of value to show
    +     *  @param	DoliDB  $db     			Database handler
    +     *  @param  integer $maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
          */
         static function liste_modeles($db,$maxfilenamelength=0)
         {
    +        // phpcs:enable
             global $conf;
     
             $type='donation';
    @@ -63,7 +68,10 @@ abstract class ModeleDon extends CommonDocGenerator
      */
     abstract class ModeleNumRefDons
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
         /**
          * 	Return if a module can be used or not
    @@ -138,4 +146,3 @@ abstract class ModeleNumRefDons
             return $langs->trans("NotAvailable");
         }
     }
    -
    diff --git a/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php b/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php
    index 9c45c135ac3..6a1543af4cf 100644
    --- a/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php
    +++ b/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php
    @@ -2,9 +2,10 @@
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2014		Marcos García		<marcosgdf@gmail.com>
    -  * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    -
    -*
    + * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Philippe Grand      <philippe.grand@atoo-net.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
     * 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
    @@ -39,10 +40,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_shipment_odt extends ModelePdfExpedition
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -52,10 +66,10 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -99,8 +113,8 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -177,6 +191,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -190,6 +205,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -211,10 +227,8 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
     
     		if ($conf->expedition->dir_output."/sending")
     		{
    @@ -333,6 +347,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -348,6 +363,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     				}
     				catch(OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Make substitutions into odt of user info
    @@ -367,8 +383,9 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Make substitutions into odt of mysoc
    @@ -388,8 +405,9 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Make substitutions into odt of thirdparty
    @@ -407,8 +425,9 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of object + external modules
    @@ -432,6 +451,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -464,9 +484,11 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -474,7 +496,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     						$odfHandler->mergeSegment($listlines);
     					}
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
     					$this->error=$e->getMessage();
     					dol_syslog($this->error, LOG_WARNING);
    @@ -488,8 +510,9 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     					try {
     						$odfHandler->setVars($key, $value, true, 'UTF-8');
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -501,16 +524,18 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
     					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -535,6 +560,4 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php
    index 9a496cb5589..3d786bf111d 100644
    --- a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php
    +++ b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php
    @@ -33,11 +33,82 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     
     /**
    - *	Classe permettant de generer les borderaux envoi au modele Merou
    + *	Class to build sending documents with model Merou
      */
     class pdf_merou extends ModelePdfExpedition
     {
    -	var $emetteur;	// Objet societe qui emet
    +    /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
    +
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
    +
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +	/**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -65,12 +136,13 @@ class pdf_merou extends ModelePdfExpedition
     
     		$this->option_logo = 1;
     
    -		// Recupere emmetteur
    +		// Get source company
     		$this->emetteur=$mysoc;
     		if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default if not defined
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build pdf onto disk
     	 *
    @@ -84,6 +156,7 @@ class pdf_merou extends ModelePdfExpedition
     	 */
     	function write_file(&$object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$mysoc,$hookmanager;
     
     		$object->fetch_thirdparty();
    @@ -91,10 +164,10 @@ class pdf_merou extends ModelePdfExpedition
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies", "propal", "deliveries", "sendings", "productbatch"));
    -		
    +
     		if ($conf->expedition->dir_output)
     		{
     			$object->fetch_thirdparty();
    @@ -260,7 +333,7 @@ class pdf_merou extends ModelePdfExpedition
     					$pdf->SetDrawColor(120,120,120);
     					$pdf->Rect(10+3, $curY, 3, 3);
     					$pdf->Rect(20+3, $curY, 3, 3);
    -					
    +
     					//Insertion de la reference du produit
     					$pdf->SetXY(30, $curY);
     					$pdf->SetFont('','B', $default_font_size - 3);
    @@ -353,7 +426,7 @@ class pdf_merou extends ModelePdfExpedition
                         @chmod($file, octdec($conf->global->MAIN_UMASK));
     
     				$this->result = array('fullpath'=>$file);
    -                
    +
     				return 1;
     			}
     			else
    @@ -385,7 +458,7 @@ class pdf_merou extends ModelePdfExpedition
     	{
     		global $langs;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
     
    diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php
    index 683a5e13124..daa8d67e5d1 100644
    --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php
    +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php
    @@ -32,11 +32,82 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     
     /**
    - *	Classe permettant de generer les borderaux envoi au modele Rouget
    + *	Class to build sending documents with model Rouget
      */
     class pdf_rouget extends ModelePdfExpedition
     {
    -	var $emetteur;	// Objet societe qui emet
    +    /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
    +
    +    /**
    +     * @var string model name
    +     */
    +    public $name;
    +
    +    /**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +	/**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -102,6 +173,7 @@ class pdf_rouget extends ModelePdfExpedition
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build pdf onto disk
     	 *
    @@ -115,6 +187,7 @@ class pdf_rouget extends ModelePdfExpedition
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$hookmanager;
     
     		$object->fetch_thirdparty();
    @@ -122,8 +195,8 @@ class pdf_rouget extends ModelePdfExpedition
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies", "propal", "deliveries", "sendings", "productbatch"));
     
     		$nblignes = count($object->lines);
    @@ -580,6 +653,7 @@ class pdf_rouget extends ModelePdfExpedition
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -592,6 +666,7 @@ class pdf_rouget extends ModelePdfExpedition
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     
             $sign=1;
    @@ -655,7 +730,6 @@ class pdf_rouget extends ModelePdfExpedition
     
     	    	$pdf->SetXY($this->posxtotalht, $tab2_top + $tab2_hl * $index);
     	    	$pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxtotalht, $tab2_hl, price($object->total_ht, 0, $outputlangs), 0, 'C', 1);
    -
     		}
     
     		// Total Weight
    @@ -759,9 +833,7 @@ class pdf_rouget extends ModelePdfExpedition
     				$pdf->SetXY($this->posxtotalht-1, $tab_top+1);
     				$pdf->MultiCell(($this->page_largeur - $this->marge_droite - $this->posxtotalht), 2, $outputlangs->transnoentities("TotalHT"),'','C');
     			}
    -
     		}
    -
     	}
     
     	/**
    @@ -1027,6 +1099,4 @@ class pdf_rouget extends ModelePdfExpedition
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'SHIPPING_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/expedition/mod_expedition_ribera.php b/htdocs/core/modules/expedition/mod_expedition_ribera.php
    index c002da1eee2..35a5eb2325b 100644
    --- a/htdocs/core/modules/expedition/mod_expedition_ribera.php
    +++ b/htdocs/core/modules/expedition/mod_expedition_ribera.php
    @@ -29,9 +29,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/expedition/modules_expedition.php
      */
     class mod_expedition_ribera extends ModelNumRefExpedition
     {
    -	var $version='dolibarr';
    -	var $error = '';
    -	var $nom = 'Ribera';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Ribera';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Ribera';
     
     	/**
     	 *	Return default description of numbering model
    @@ -40,7 +59,7 @@ class mod_expedition_ribera extends ModelNumRefExpedition
     	 */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -121,6 +140,7 @@ class mod_expedition_ribera extends ModelNumRefExpedition
     		return  $numFinal;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -130,8 +150,7 @@ class mod_expedition_ribera extends ModelNumRefExpedition
     	 */
         function expedition_get_num($objsoc,$objforref)
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/expedition/mod_expedition_safor.php b/htdocs/core/modules/expedition/mod_expedition_safor.php
    index 826ba6665c4..2ebf9335755 100644
    --- a/htdocs/core/modules/expedition/mod_expedition_safor.php
    +++ b/htdocs/core/modules/expedition/mod_expedition_safor.php
    @@ -28,10 +28,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/expedition/modules_expedition.php
      */
     class mod_expedition_safor extends ModelNumRefExpedition
     {
    -	var $version='dolibarr';
    -	var $prefix='SH';
    -	var $error='';
    -	var $nom='Safor';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $prefix='SH';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Safor';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Safor';
     
     
     	/**
    @@ -130,6 +150,7 @@ class mod_expedition_safor extends ModelNumRefExpedition
     		return $this->prefix.$yymm."-".$num;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -139,7 +160,7 @@ class mod_expedition_safor extends ModelNumRefExpedition
     	 */
     	function expedition_get_num($objsoc,$objforref)
     	{
    +        // phpcs:enable
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/expedition/modules_expedition.php b/htdocs/core/modules/expedition/modules_expedition.php
    index f46fa33c5f1..51f41978732 100644
    --- a/htdocs/core/modules/expedition/modules_expedition.php
    +++ b/htdocs/core/modules/expedition/modules_expedition.php
    @@ -36,9 +36,13 @@
      */
     abstract class ModelePdfExpedition extends CommonDocGenerator
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
    @@ -48,6 +52,7 @@ abstract class ModelePdfExpedition extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='shipping';
    @@ -66,7 +71,10 @@ abstract class ModelePdfExpedition extends CommonDocGenerator
      */
     abstract class ModelNumRefExpedition
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/** Return if a model can be used or not
     	 *
    diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
    index 3244bb25340..ec03a2cef8e 100644
    --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
    +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php
    @@ -52,24 +52,64 @@ class pdf_standard extends ModeleExpenseReport
          * @var string model description (short text)
          */
         public $description;
    -    
    +
     	/**
          * @var string document type
          */
         public $type;
     
    -    var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -    var $version = 'dolibarr';
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
     
    -    var $page_largeur;
    -    var $page_hauteur;
    -    var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
    -    var $emetteur;	// Objet societe qui emet
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -80,7 +120,7 @@ class pdf_standard extends ModeleExpenseReport
     	function __construct($db)
     	{
     		global $conf, $langs, $mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "trips", "projects"));
     
    @@ -150,7 +190,8 @@ class pdf_standard extends ModeleExpenseReport
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -163,13 +204,14 @@ class pdf_standard extends ModeleExpenseReport
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "trips", "projects", "dict"));
     
     		$nblignes = count($object->lines);
    @@ -236,7 +278,7 @@ class pdf_standard extends ModeleExpenseReport
     				$pagenb=0;
     				$pdf->SetDrawColor(128,128,128);
     
    -				$pdf->SetTitle($outputlangs->convToOutputCharset($object->ref_number));
    +				$pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
     				$pdf->SetSubject($outputlangs->transnoentities("Trips"));
     				$pdf->SetCreator("Dolibarr ".DOL_VERSION);
     				$pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
    @@ -437,7 +479,6 @@ class pdf_standard extends ModeleExpenseReport
     						$pagenb++;
     						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     					}
    -
     				}
     
     				// Show square
    @@ -526,9 +567,9 @@ class pdf_standard extends ModeleExpenseReport
     	 */
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
    -		global $conf,$langs,$hookmanager;
    -		
    -		// Translations
    +		global $conf, $langs, $hookmanager;
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "trips", "companies"));
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -736,7 +777,6 @@ class pdf_standard extends ModeleExpenseReport
     				}
     			}
     		}
    -
        	}
     
     	/**
    @@ -877,6 +917,4 @@ class pdf_standard extends ModeleExpenseReport
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'EXPENSEREPORT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/expensereport/mod_expensereport_jade.php b/htdocs/core/modules/expensereport/mod_expensereport_jade.php
    index c6153d422eb..385a7558c4c 100644
    --- a/htdocs/core/modules/expensereport/mod_expensereport_jade.php
    +++ b/htdocs/core/modules/expensereport/mod_expensereport_jade.php
    @@ -28,10 +28,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/expensereport/modules_expenserepo
      */
     class mod_expensereport_jade extends ModeleNumRefExpenseReport
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='ER';
    -	var $error='';
    -	var $nom='Jade';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='ER';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Jade';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Jade';
     
     
         /**
    diff --git a/htdocs/core/modules/expensereport/mod_expensereport_sand.php b/htdocs/core/modules/expensereport/mod_expensereport_sand.php
    index 4222bf163d5..95cc3d39c95 100644
    --- a/htdocs/core/modules/expensereport/mod_expensereport_sand.php
    +++ b/htdocs/core/modules/expensereport/mod_expensereport_sand.php
    @@ -30,9 +30,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/expensereport/modules_expenserepo
      */
     class mod_expensereport_sand extends ModeleNumRefExpenseReport
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Sand';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Sand';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Sand';
     
     
         /**
    @@ -42,7 +61,7 @@ class mod_expensereport_sand extends ModeleNumRefExpenseReport
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    diff --git a/htdocs/core/modules/expensereport/modules_expensereport.php b/htdocs/core/modules/expensereport/modules_expensereport.php
    index e97766b38f6..9ff7f671f9f 100644
    --- a/htdocs/core/modules/expensereport/modules_expensereport.php
    +++ b/htdocs/core/modules/expensereport/modules_expensereport.php
    @@ -23,18 +23,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModeleExpenseReport extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
    -	 *
    +     *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
    -	 */
    +     */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='expensereport';
    @@ -45,9 +50,9 @@ abstract class ModeleExpenseReport extends CommonDocGenerator
     
     		return $liste;
     	}
    -
     }
     
    +// phpcs:ignore PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      * expensereport_pdf_create
      *
    @@ -63,6 +68,7 @@ abstract class ModeleExpenseReport extends CommonDocGenerator
      */
     function expensereport_pdf_create(DoliDB $db, ExpenseReport $object, $message, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
     {
    +    // phpcs:enable
     	return $object->generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
     }
     
    @@ -73,7 +79,10 @@ function expensereport_pdf_create(DoliDB $db, ExpenseReport $object, $message, $
     
     abstract class ModeleNumRefExpenseReport
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Return if a module can be used or not
    @@ -134,7 +143,7 @@ abstract class ModeleNumRefExpenseReport
     	/**
     	 *	Renvoie version du module numerotation
     	 *
    -	 *	@return     string      Valeur
    +	 *  @return     string      Valeur
     	 */
     	function getVersion()
     	{
    diff --git a/htdocs/core/modules/export/export_csv.modules.php b/htdocs/core/modules/export/export_csv.modules.php
    index 8d35ff63225..1efe6161647 100644
    --- a/htdocs/core/modules/export/export_csv.modules.php
    +++ b/htdocs/core/modules/export/export_csv.modules.php
    @@ -30,17 +30,31 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/export/modules_export.php';
      */
     class ExportCsv extends ModeleExports
     {
    -	var $id;
    -	var $label;
    -	var $extension;
    -	var $version;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $label_lib;
    -	var $version_lib;
    +	/**
    +     * @var string export files label
    +     */
    +    public $label;
     
    -	var $separator;
    +	public $extension;
     
    -	var $handle;    // Handle fichier
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $label_lib;
    +
    +	public $version_lib;
    +
    +	public $separator;
    +
    +	public $handle;    // Handle fichier
     
     
     	/**
    @@ -50,7 +64,7 @@ class ExportCsv extends ModeleExports
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     		$this->db = $db;
     
     		$this->separator=',';
    @@ -68,7 +82,6 @@ class ExportCsv extends ModeleExports
     		// If driver use an external library, put its name here
     		$this->label_lib='Dolibarr';
     		$this->version_lib=DOL_VERSION;
    -
     	}
     
     	/**
    @@ -142,6 +155,7 @@ class ExportCsv extends ModeleExports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Open output file
     	 *
    @@ -151,6 +165,7 @@ class ExportCsv extends ModeleExports
     	 */
     	function open_file($file,$outputlangs)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		dol_syslog("ExportCsv::open_file file=".$file);
    @@ -169,6 +184,7 @@ class ExportCsv extends ModeleExports
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output header into file
     	 *
    @@ -177,10 +193,12 @@ class ExportCsv extends ModeleExports
     	 */
     	function write_header($outputlangs)
     	{
    +        // phpcs:enable
     		return 0;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output title line into file
     	 *
    @@ -192,6 +210,7 @@ class ExportCsv extends ModeleExports
     	 */
     	function write_title($array_export_fields_label,$array_selected_sorted,$outputlangs,$array_types)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (! empty($conf->global->EXPORT_CSV_FORCE_CHARSET))
    @@ -215,7 +234,8 @@ class ExportCsv extends ModeleExports
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *	Output record line into file
          *
          *  @param     	array		$array_selected_sorted      Array with list of field to export
    @@ -226,6 +246,7 @@ class ExportCsv extends ModeleExports
     	 */
     	function write_record($array_selected_sorted,$objp,$outputlangs,$array_types)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (! empty($conf->global->EXPORT_CSV_FORCE_CHARSET))
    @@ -258,7 +279,7 @@ class ExportCsv extends ModeleExports
     				$array = $array['options'];
     				$newvalue = $array[$newvalue];
     			}
    -			
    +
     			fwrite($this->handle,$newvalue.$this->separator);
     			$this->col++;
     		}
    @@ -267,6 +288,7 @@ class ExportCsv extends ModeleExports
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output footer into file
     	 *
    @@ -275,9 +297,11 @@ class ExportCsv extends ModeleExports
     	 */
     	function write_footer($outputlangs)
     	{
    +        // phpcs:enable
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Close file handle
     	 *
    @@ -285,6 +309,7 @@ class ExportCsv extends ModeleExports
     	 */
     	function close_file()
     	{
    +        // phpcs:enable
     		fclose($this->handle);
     		return 0;
     	}
    @@ -303,14 +328,14 @@ class ExportCsv extends ModeleExports
     	{
     		global $conf;
     		$addquote=0;
    -		
    +
     
     		// Rule Dolibarr: No HTML
        		//print $charset.' '.$newvalue."\n";
        		//$newvalue=dol_string_nohtmltag($newvalue,0,$charset);
        		$newvalue=dol_htmlcleanlastbr($newvalue);
        		//print $charset.' '.$newvalue."\n";
    -		
    +
     		// Rule 1 CSV: No CR, LF in cells (except if USE_STRICT_CSV_RULES is on, we can keep record as it is but we must add quotes)
     		$oldvalue=$newvalue;
     		$newvalue=str_replace("\r",'',$newvalue);
    @@ -321,7 +346,7 @@ class ExportCsv extends ModeleExports
     			$newvalue=$oldvalue;
     			$addquote=1;
     		}
    -		
    +
     		// Rule 2 CSV: If value contains ", we must escape with ", and add "
     		if (preg_match('/"/',$newvalue))
     		{
    @@ -337,6 +362,4 @@ class ExportCsv extends ModeleExports
     
     		return ($addquote?'"':'').$newvalue.($addquote?'"':'');
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/export/export_excel.modules.php b/htdocs/core/modules/export/export_excel.modules.php
    index 00d06e8511a..1982fffb07e 100644
    --- a/htdocs/core/modules/export/export_excel.modules.php
    +++ b/htdocs/core/modules/export/export_excel.modules.php
    @@ -32,19 +32,37 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
      */
     class ExportExcel extends ModeleExports
     {
    -	var $id;
    -	var $label;
    -	var $extension;
    -	var $version;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $label_lib;
    -	var $version_lib;
    +    /**
    +     * @var string Export Excel label
    +     */
    +    public $label;
     
    -	var $workbook;      // Handle fichier
    -	var $worksheet;     // Handle onglet
    -	var $row;
    -	var $col;
    -    var $file;          // To save filename
    +	public $extension;
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $label_lib;
    +
    +	public $version_lib;
    +
    +	public $workbook;      // Handle file
    +
    +	public $worksheet;     // Handle sheet
    +
    +	public $row;
    +
    +	public $col;
    +
    +    public $file;          // To save filename
     
     
     	/**
    @@ -65,7 +83,7 @@ class ExportExcel extends ModeleExports
     		$this->version='1.30';             // Driver version
     
     		$this->disabled = (in_array(constant('PHPEXCEL_PATH'),array('disabled','disabled/'))?1:0);	// A condition to disable module (used for native debian packages)
    -		
    +
     		if (empty($this->disabled))
     		{
         		// If driver use an external library, put its name here
    @@ -160,6 +178,7 @@ class ExportExcel extends ModeleExports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Open output file
     	 *
    @@ -169,6 +188,7 @@ class ExportExcel extends ModeleExports
     	 */
     	function open_file($file,$outputlangs)
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs;
     
     		if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL))
    @@ -229,20 +249,23 @@ class ExportExcel extends ModeleExports
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *	Write header
    +	 *  Write header
     	 *
    -     *	@param      Translate	$outputlangs        Object lang to translate values
    +     *  @param      Translate	$outputlangs        Object lang to translate values
     	 * 	@return		int								<0 if KO, >0 if OK
     	 */
     	function write_header($outputlangs)
     	{
    +        // phpcs:enable
     		//$outputlangs->charset_output='ISO-8859-1';	// Because Excel 5 format is ISO
     
     		return 0;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *  Output title line into file
          *
    @@ -254,6 +277,7 @@ class ExportExcel extends ModeleExports
     	 */
     	function write_title($array_export_fields_label,$array_selected_sorted,$outputlangs,$array_types)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		// Create a format for the column headings
    @@ -298,6 +322,7 @@ class ExportExcel extends ModeleExports
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *  Output record line into file
          *
    @@ -309,6 +334,7 @@ class ExportExcel extends ModeleExports
     	 */
     	function write_record($array_selected_sorted,$objp,$outputlangs,$array_types)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		// Create a format for the column headings
    @@ -329,14 +355,14 @@ class ExportExcel extends ModeleExports
     
     			$newvalue=$this->excel_clean($newvalue);
     			$typefield=isset($array_types[$code])?$array_types[$code]:'';
    -			
    +
     			if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7))
     			{
     				$array = unserialize($typefield);
     				$array = $array['options'];
     				$newvalue = $array[$newvalue];
     			}
    -			
    +
     			// Traduction newvalue
     			if (preg_match('/^\((.*)\)$/i',$newvalue,$reg))
     			{
    @@ -416,6 +442,7 @@ class ExportExcel extends ModeleExports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Write footer
          *
    @@ -424,17 +451,20 @@ class ExportExcel extends ModeleExports
          */
     	function write_footer($outputlangs)
     	{
    +        // phpcs:enable
     		return 0;
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *	Close Excel file
          *
     	 * 	@return		int							<0 if KO, >0 if OK
          */
     	function close_file()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL))
    @@ -453,7 +483,8 @@ class ExportExcel extends ModeleExports
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          * Clean a cell to respect rules of Excel file cells
          *
          * @param 	string	$newvalue	String to clean
    @@ -461,6 +492,7 @@ class ExportExcel extends ModeleExports
          */
         function excel_clean($newvalue)
         {
    +        // phpcs:enable
     		// Rule Dolibarr: No HTML
         	$newvalue=dol_string_nohtmltag($newvalue);
     
    @@ -490,4 +522,3 @@ class ExportExcel extends ModeleExports
         	return $letter;
         }
     }
    -
    diff --git a/htdocs/core/modules/export/export_excel2007.modules.php b/htdocs/core/modules/export/export_excel2007.modules.php
    index df9fd9d5705..6c80ac5977e 100644
    --- a/htdocs/core/modules/export/export_excel2007.modules.php
    +++ b/htdocs/core/modules/export/export_excel2007.modules.php
    @@ -33,19 +33,37 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
      */
     class ExportExcel2007 extends ExportExcel
     {
    -	var $id;
    -	var $label;
    -	var $extension;
    -	var $version;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $label_lib;
    -	var $version_lib;
    +	/**
    +     * @var string label
    +     */
    +    public $label;
     
    -	var $workbook;      // Handle fichier
    -	var $worksheet;     // Handle onglet
    -	var $row;
    -	var $col;
    -    var $file;          // To save filename
    +	public $extension;
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $label_lib;
    +
    +	public $version_lib;
    +
    +	public $workbook;      // Handle fichier
    +
    +	public $worksheet;     // Handle onglet
    +
    +	public $row;
    +
    +	public $col;
    +
    +    public $file;          // To save filename
     
     	/**
     	 *	Constructor
    @@ -65,7 +83,7 @@ class ExportExcel2007 extends ExportExcel
     		$this->version='1.30';             // Driver version
     
     		$this->disabled = (in_array(constant('PHPEXCEL_PATH'),array('disabled','disabled/'))?1:0);	// A condition to disable module (used for native debian packages)
    -		
    +
     		if (empty($this->disabled))
     		{
         		// If driver use an external library, put its name here
    @@ -85,18 +103,20 @@ class ExportExcel2007 extends ExportExcel
                     $this->version_lib='1.8.0';		// No way to get info from library
         		}
     		}
    -		
    +
     		$this->row=0;
     	}
     
     
    -	/**
    -     *	Close Excel file
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Close Excel file
          *
    -	 * 	@return		int							<0 if KO, >0 if OK
    +	 *  @return		int							<0 if KO, >0 if OK
          */
     	function close_file()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (! empty($conf->global->MAIN_USE_PHP_WRITEEXCEL))
    @@ -113,6 +133,4 @@ class ExportExcel2007 extends ExportExcel
         	}
     		return 1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/export/export_tsv.modules.php b/htdocs/core/modules/export/export_tsv.modules.php
    index 2945c5095b8..8afa9ded884 100644
    --- a/htdocs/core/modules/export/export_tsv.modules.php
    +++ b/htdocs/core/modules/export/export_tsv.modules.php
    @@ -31,17 +31,31 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/export/modules_export.php';
      */
     class ExportTsv extends ModeleExports
     {
    -    var $id;
    -    var $label;
    -    var $extension;
    -    var $version;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -    var $label_lib;
    -    var $version_lib;
    +    /**
    +     * @var string label
    +     */
    +    public $label;
     
    -    var $separator="\t";
    +    public $extension;
     
    -    var $handle;    // Handle fichier
    +    /**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +    public $label_lib;
    +
    +    public $version_lib;
    +
    +    public $separator="\t";
    +
    +    public $handle;    // Handle fichier
     
     
         /**
    @@ -137,20 +151,22 @@ class ExportTsv extends ModeleExports
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	*	Open output file
     	*
     	 *	@param		string		$file			Path of filename to generate
     	*	@param		Translate	$outputlangs	Output language object
     	*	@return		int							<0 if KO, >=0 if OK
    -	*/
    -	function open_file($file,$outputlangs)
    +    */
    +    function open_file($file,$outputlangs)
         {
    +        // phpcs:enable
             global $langs;
     
             dol_syslog("ExportTsv::open_file file=".$file);
     
    -		$ret=1;
    +        $ret=1;
     
             $outputlangs->load("exports");
     		$this->handle = fopen($file, "wt");
    @@ -164,6 +180,7 @@ class ExportTsv extends ModeleExports
     		return $ret;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output header into file
     	 *
    @@ -172,11 +189,13 @@ class ExportTsv extends ModeleExports
     	 */
         function write_header($outputlangs)
         {
    +        // phpcs:enable
             return 0;
         }
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Output title line into file
          *
          *  @param      array		$array_export_fields_label   	Array with list of label of fields
    @@ -187,6 +206,7 @@ class ExportTsv extends ModeleExports
     	 */
         function write_title($array_export_fields_label,$array_selected_sorted,$outputlangs,$array_types)
         {
    +        // phpcs:enable
             foreach($array_selected_sorted as $code => $value)
             {
                 $newvalue=$outputlangs->transnoentities($array_export_fields_label[$code]);		// newvalue is now $outputlangs->charset_output encoded
    @@ -199,6 +219,7 @@ class ExportTsv extends ModeleExports
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output record line into file
     	 *
    @@ -210,6 +231,7 @@ class ExportTsv extends ModeleExports
     	 */
         function write_record($array_selected_sorted,$objp,$outputlangs,$array_types)
         {
    +        // phpcs:enable
         	global $conf;
     
     		$this->col=0;
    @@ -226,14 +248,14 @@ class ExportTsv extends ModeleExports
     			if (preg_match('/^\((.*)\)$/i',$newvalue,$reg)) $newvalue=$outputlangs->transnoentities($reg[1]);
     
     			$newvalue=$this->tsv_clean($newvalue,$outputlangs->charset_output);
    -			
    +
     			if (preg_match('/^Select:/i', $typefield, $reg) && $typefield = substr($typefield, 7))
     			{
     				$array = unserialize($typefield);
     				$array = $array['options'];
     				$newvalue = $array[$newvalue];
     			}
    -			
    +
     			fwrite($this->handle,$newvalue.$this->separator);
                 $this->col++;
     		}
    @@ -241,6 +263,7 @@ class ExportTsv extends ModeleExports
             return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output footer into file
     	 *
    @@ -249,9 +272,11 @@ class ExportTsv extends ModeleExports
     	 */
         function write_footer($outputlangs)
         {
    +        // phpcs:enable
     		return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Close file handle
     	 *
    @@ -259,19 +284,22 @@ class ExportTsv extends ModeleExports
     	 */
         function close_file()
         {
    +        // phpcs:enable
             fclose($this->handle);
             return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Clean a cell to respect rules of TSV file cells
          *
          * @param 	string	$newvalue	String to clean
    -	 * @param	string	$charset	Input AND Output character set
    +     * @param	string	$charset	Input AND Output character set
          * @return 	string				Value cleaned
          */
         function tsv_clean($newvalue, $charset)
         {
    +        // phpcs:enable
     		// Rule Dolibarr: No HTML
     		$newvalue=dol_string_nohtmltag($newvalue, 1, $charset);
     
    @@ -285,8 +313,6 @@ class ExportTsv extends ModeleExports
     			$newvalue=str_replace("\t"," ",$newvalue);
     		}
     
    -    	return $newvalue;
    +        return $newvalue;
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/export/modules_export.php b/htdocs/core/modules/export/modules_export.php
    index 5d7e0ecac84..6436b501705 100644
    --- a/htdocs/core/modules/export/modules_export.php
    +++ b/htdocs/core/modules/export/modules_export.php
    @@ -30,15 +30,21 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     class ModeleExports extends CommonDocGenerator    // This class can't be abstract as there is instance propreties loaded by liste_modeles
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -	var $driverlabel=array();
    -	var $driverversion=array();
    +	public $driverlabel=array();
     
    -	var $liblabel=array();
    -	var $libversion=array();
    +	public $driverversion=array();
    +
    +	public $liblabel=array();
    +
    +	public $libversion=array();
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load into memory list of available export format
     	 *
    @@ -48,6 +54,7 @@ class ModeleExports extends CommonDocGenerator    // This class can't be abstrac
     	 */
     	function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		dol_syslog(get_class($this)."::liste_modeles");
     
     		$dir=DOL_DOCUMENT_ROOT."/core/modules/export/";
    @@ -159,7 +166,4 @@ class ModeleExports extends CommonDocGenerator    // This class can't be abstrac
     	{
     		return $this->libversion[$key];
     	}
    -
     }
    -
    -
    diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
    index 21c25913543..bfe22b93ae3 100644
    --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
    +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php
    @@ -1,9 +1,10 @@
     <?php
     /* Copyright (C) 2010-2012	Laurent Destailleur	<ely@users.sourceforge.net>
    -* Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
    -* Copyright (C) 2014		Marcos García		<marcosgdf@gmail.com>
    -* Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    -*
    + * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2014		Marcos García		<marcosgdf@gmail.com>
    + * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
     * 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
    @@ -38,10 +39,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_invoice_odt extends ModelePDFFactures
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -51,10 +65,10 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT/ODS templates";
    @@ -96,10 +110,10 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     	 */
     	function info($langs)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -176,6 +190,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -189,6 +204,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -210,10 +226,8 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
     
     		if ($conf->facture->dir_output)
     		{
    @@ -342,9 +356,10 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     						)
     					);
     				}
    -				catch(Exception $e)
    +				catch (Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -358,8 +373,9 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -397,8 +413,9 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -431,9 +448,11 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -457,6 +476,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -470,14 +490,16 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     						$odfHandler->exportAsAttachedPDF($file);
     					}catch (Exception $e){
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
    -					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +						$odfHandler->saveToDisk($file);
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -502,6 +524,4 @@ class doc_generic_invoice_odt extends ModelePDFFactures
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
    index 7cbe960d374..797b48865c6 100644
    --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
    @@ -70,9 +70,9 @@ class pdf_crabe extends ModelePDFFactures
     
     	/**
          * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
          */
    -	public $phpmin = array(5, 2);
    +	public $phpmin = array(5, 4);
     
     	/**
          * Dolibarr version of the loaded document
    @@ -80,15 +80,46 @@ class pdf_crabe extends ModelePDFFactures
          */
     	public $version = 'dolibarr';
     
    +	/**
    +     * @var int page_largeur
    +     */
         public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
         public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
         public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
     	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
     	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
     	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
     	public $marge_basse;
     
    -	public $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     	/**
     	 * @var bool Situation invoice type
    @@ -108,7 +139,7 @@ class pdf_crabe extends ModelePDFFactures
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
    @@ -187,6 +218,7 @@ class pdf_crabe extends ModelePDFFactures
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *  Function to build pdf onto disk
          *
    @@ -200,13 +232,14 @@ class pdf_crabe extends ModelePDFFactures
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		// Translations
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
     
     		$nblignes = count($object->lines);
    @@ -743,6 +776,7 @@ class pdf_crabe extends ModelePDFFactures
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show payments table
     	 *
    @@ -754,6 +788,7 @@ class pdf_crabe extends ModelePDFFactures
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
             $sign=1;
    @@ -880,10 +915,10 @@ class pdf_crabe extends ModelePDFFactures
     			$this->error=$this->db->lasterror();
     			return -1;
     		}
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -895,6 +930,7 @@ class pdf_crabe extends ModelePDFFactures
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1041,6 +1077,7 @@ class pdf_crabe extends ModelePDFFactures
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -1053,6 +1090,7 @@ class pdf_crabe extends ModelePDFFactures
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     
             $sign=1;
    @@ -1164,7 +1202,6 @@ class pdf_crabe extends ModelePDFFactures
     
     								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
     								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    -
     							}
     						}
     					}
    @@ -1187,7 +1224,6 @@ class pdf_crabe extends ModelePDFFactures
     							$this->tva[$tvakey]=$tvaval * $coef_fix_tva;
     						}
     					}
    -
     				}
     
     				foreach($this->tva as $tvakey => $tvaval)
    @@ -1478,9 +1514,7 @@ class pdf_crabe extends ModelePDFFactures
     				{
     					$pdf->MultiCell($this->postotalht-$this->posxprogress,2, $outputlangs->transnoentities("Progress"),'','C');
     				}
    -
     			}
    -
     		}
     
     		if($conf->global->PRODUCT_USE_UNITS) {
    @@ -1536,7 +1570,7 @@ class pdf_crabe extends ModelePDFFactures
     	{
     		global $conf, $langs;
     
    -		// Translations
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1560,27 +1594,30 @@ class pdf_crabe extends ModelePDFFactures
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -				$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +					$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B',$default_font_size - 2);
    -				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B', $default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    @@ -1810,5 +1847,4 @@ class pdf_crabe extends ModelePDFFactures
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    new file mode 100644
    index 00000000000..439f81ab02e
    --- /dev/null
    +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    @@ -0,0 +1,2022 @@
    +<?php
    +/* Copyright (C) 2004-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2008		Raphael Bertrand		<raphael.bertrand@resultic.fr>
    + * Copyright (C) 2010-2014	Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2012		Christophe Battarel	<christophe.battarel@altairis.fr>
    + * Copyright (C) 2012		Cédric Salvador		<csalvador@gpcsolutions.fr>
    + * Copyright (C) 2012-2014	Raphaël Doursenaud	<rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2015		Marcos García		<marcosgdf@gmail.com>
    + * Copyright (C) 2017		Ferran Marcet		<fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *	\file       htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    + *	\ingroup    facture
    + *	\brief      File of class to generate customers invoices from sponge model
    + */
    +
    +require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
    +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
    +
    +
    +/**
    + *	Class to manage PDF invoice template sponge
    + */
    +class pdf_sponge extends ModelePDFFactures
    +{
    +     /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
    +
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
    +
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +    /**
    +     * @var int 	Save the name of generated file as the main doc when generating a doc with this template
    +     */
    +    public $update_main_doc_field;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +	/**
    +     * @var array Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +     */
    +	public $phpmin = array(5, 2);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'development';
    +
    +    public $page_largeur;
    +    public $page_hauteur;
    +    public $format;
    +	public $marge_gauche;
    +	public $marge_droite;
    +	public $marge_haute;
    +	public $marge_basse;
    +
    +	public $emetteur;	// Objet societe qui emet
    +
    +	/**
    +	 * @var bool Situation invoice type
    +	 */
    +	public $situationinvoice;
    +
    +	/**
    +	 * @var float X position for the situation progress column
    +	 */
    +	public $posxprogress;
    +
    +
    +	/**
    +	 *	Constructor
    +	 *
    +	 *  @param		DoliDB		$db      Database handler
    +	 */
    +	function __construct($db)
    +	{
    +		global $conf,$langs,$mysoc;
    +
    +		// Translations
    +		$langs->loadLangs(array("main", "bills"));
    +
    +		$this->db = $db;
    +		$this->name = "sponge";
    +		$this->description = $langs->trans('PDFSpongeDescription');
    +		$this->update_main_doc_field = 1;		// Save the name of generated file as the main doc when generating a doc with this template
    +
    +		// Dimensiont page
    +		$this->type = 'pdf';
    +		$formatarray=pdf_getFormat();
    +		$this->page_largeur = $formatarray['width'];
    +		$this->page_hauteur = $formatarray['height'];
    +		$this->format = array($this->page_largeur,$this->page_hauteur);
    +		$this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
    +		$this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
    +		$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
    +		$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
    +
    +		$this->option_logo = 1;                    // Affiche logo
    +		$this->option_tva = 1;                     // Gere option tva FACTURE_TVAOPTION
    +		$this->option_modereg = 1;                 // Affiche mode reglement
    +		$this->option_condreg = 1;                 // Affiche conditions reglement
    +		$this->option_codeproduitservice = 1;      // Affiche code produit-service
    +		$this->option_multilang = 1;               // Dispo en plusieurs langues
    +		$this->option_escompte = 1;                // Affiche si il y a eu escompte
    +		$this->option_credit_note = 1;             // Support credit notes
    +		$this->option_freetext = 1;				   // Support add of a personalised text
    +		$this->option_draft_watermark = 1;		   // Support add of a watermark on drafts
    +
    +		$this->franchise=!$mysoc->tva_assuj;
    +
    +		// Get source company
    +		$this->emetteur=$mysoc;
    +		if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default, if was not defined
    +
    +		// Define position of columns
    +		$this->posxdesc=$this->marge_gauche+1; // used for notes ans other stuff
    +
    +		//  Use new system for position of columns, view  $this->defineColumnField()
    +
    +		$this->tva=array();
    +		$this->localtax1=array();
    +		$this->localtax2=array();
    +		$this->atleastoneratenotnull=0;
    +		$this->atleastonediscount=0;
    +		$this->situationinvoice=false;
    +	}
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
    +    /**
    +     *  Function to build pdf onto disk
    +     *
    +     *  @param		Object		$object				Object to generate
    +     *  @param		Translate	$outputlangs		Lang output object
    +     *  @param		string		$srctemplatepath	Full path of source filename for generator using a template file
    +     *  @param		int			$hidedetails		Do not show line details
    +     *  @param		int			$hidedesc			Do not show desc
    +     *  @param		int			$hideref			Do not show ref
    +     *  @return     int         	    			1=OK, 0=KO
    +	 */
    +	public function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
    +	{
    +	    // phpcs:enable
    +	    global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
    +
    +	    if (! is_object($outputlangs)) $outputlangs=$langs;
    +	    // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
    +	    if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    +
    +	    // Translations
    +	    $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
    +
    +	    $nblignes = count($object->lines);
    +
    +	    // Loop on each lines to detect if there is at least one image to show
    +	    $realpatharray=array();
    +	    $this->atleastonephoto = false;
    +	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
    +	    {
    +	        $objphoto = new Product($this->db);
    +
    +	        for ($i = 0 ; $i < $nblignes ; $i++)
    +	        {
    +	            if (empty($object->lines[$i]->fk_product)) continue;
    +
    +	            $objphoto->fetch($object->lines[$i]->fk_product);
    +	            //var_dump($objphoto->ref);exit;
    +	            if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
    +	            {
    +	                $pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";
    +	                $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';
    +	            }
    +	            else
    +	            {
    +	                $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';				// default
    +	                $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";	// alternative
    +	            }
    +
    +	            $arephoto = false;
    +	            foreach ($pdir as $midir)
    +	            {
    +	                if (! $arephoto)
    +	                {
    +	                    $dir = $conf->product->dir_output.'/'.$midir;
    +
    +	                    foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
    +	                    {
    +	                        if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES))		// If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
    +	                        {
    +	                            if ($obj['photo_vignette'])
    +	                            {
    +	                                $filename= $obj['photo_vignette'];
    +	                            }
    +	                            else
    +	                            {
    +	                                $filename=$obj['photo'];
    +	                            }
    +	                        }
    +	                        else
    +	                        {
    +	                            $filename=$obj['photo'];
    +	                        }
    +
    +	                        $realpath = $dir.$filename;
    +	                        $arephoto = true;
    +	                        $this->atleastonephoto = true;
    +	                    }
    +	                }
    +	            }
    +
    +	            if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
    +	        }
    +	    }
    +
    +	    //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
    +
    +	    if ($conf->facture->dir_output)
    +	    {
    +	        $object->fetch_thirdparty();
    +
    +	        $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    +	        $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    +	        $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    +
    +	        // Definition of $dir and $file
    +	        if ($object->specimen)
    +	        {
    +	            $dir = $conf->facture->dir_output;
    +	            $file = $dir . "/SPECIMEN.pdf";
    +	        }
    +	        else
    +	        {
    +	            $objectref = dol_sanitizeFileName($object->ref);
    +	            $dir = $conf->facture->dir_output . "/" . $objectref;
    +	            $file = $dir . "/" . $objectref . ".pdf";
    +	        }
    +	        if (! file_exists($dir))
    +	        {
    +	            if (dol_mkdir($dir) < 0)
    +	            {
    +	                $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
    +	                return 0;
    +	            }
    +	        }
    +
    +	        if (file_exists($dir))
    +	        {
    +	            // Add pdfgeneration hook
    +	            if (! is_object($hookmanager))
    +	            {
    +	                include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    +	                $hookmanager=new HookManager($this->db);
    +	            }
    +	            $hookmanager->initHooks(array('pdfgeneration'));
    +	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
    +	            global $action;
    +	            $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    +
    +	            // Set nblignes with the new facture lines content after hook
    +	            $nblignes = count($object->lines);
    +	            $nbpayments = count($object->getListOfPayments());
    +
    +	            // Create pdf instance
    +	            $pdf=pdf_getInstance($this->format);
    +	            $default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
    +	            $pdf->SetAutoPageBreak(1,0);
    +
    +	            $heightforinfotot = 50+(4*$nbpayments);	// Height reserved to output the info and total part and payment part
    +	            $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5);	// Height reserved to output the free text on last page
    +	            $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22);	// Height reserved to output the footer (value include bottom margin)
    +
    +	            if (class_exists('TCPDF'))
    +	            {
    +	                $pdf->setPrintHeader(false);
    +	                $pdf->setPrintFooter(false);
    +	            }
    +	            $pdf->SetFont(pdf_getPDFFont($outputlangs));
    +
    +	            // Set path to the background PDF File
    +                if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
    +	            {
    +	                $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
    +	                $tplidx = $pdf->importPage(1);
    +	            }
    +
    +	            $pdf->Open();
    +	            $pagenb=0;
    +	            $pdf->SetDrawColor(128,128,128);
    +
    +	            $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
    +	            $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
    +	            $pdf->SetCreator("Dolibarr ".DOL_VERSION);
    +	            $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
    +	            $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
    +	            if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
    +
    +	            $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
    +
    +	            // Does we have at least one line with discount $this->atleastonediscount
    +	            foreach ($object->lines as $line) {
    +	               if ($line->remise_percent){
    +	                    $this->atleastonediscount = true;
    +	                    break;
    +	               }
    +	            }
    +
    +
    +	            // Situation invoice handling
    +	            if ($object->situation_cycle_ref)
    +	            {
    +	                $this->situationinvoice = true;
    +	            }
    +
    +	            // New page
    +	            $pdf->AddPage();
    +	            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +	            $pagenb++;
    +
    +	            $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
    +	            $pdf->SetFont('','', $default_font_size - 1);
    +	            $pdf->MultiCell(0, 3, '');		// Set interline to 3
    +	            $pdf->SetTextColor(0,0,0);
    +
    +	            $tab_top = 90+$top_shift;
    +	            $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
    +	            $tab_height = 130-$top_shift;
    +	            $tab_height_newpage = 150;
    +	            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
    +
    +	            // Incoterm
    +	            $height_incoterms = 0;
    +	            if ($conf->incoterm->enabled)
    +	            {
    +	                $desc_incoterms = $object->getIncotermsForPDF();
    +	                if ($desc_incoterms)
    +	                {
    +						$tab_top -= 2;
    +
    +	                    $pdf->SetFont('','', $default_font_size - 1);
    +	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                    $height_incoterms=$nexY-$tab_top;
    +
    +	                    // Rect prend une longueur en 3eme param
    +	                    $pdf->SetDrawColor(192,192,192);
    +	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
    +
    +	                    $tab_top = $nexY+6;
    +	                    $height_incoterms += 4;
    +	                }
    +	            }
    +
    +	            // Affiche notes
    +	            $notetoshow=empty($object->note_public)?'':$object->note_public;
    +	            if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
    +	            {
    +	                // Get first sale rep
    +	                if (is_object($object->thirdparty))
    +	                {
    +	                    $salereparray=$object->thirdparty->getSalesRepresentatives($user);
    +	                    $salerepobj=new User($this->db);
    +	                    $salerepobj->fetch($salereparray[0]['id']);
    +	                    if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
    +	                }
    +	            }
    +
    +	            $pagenb = $pdf->getPage();
    +	            if ($notetoshow)
    +	            {
    +					$tab_top -= 2;
    +
    +	                $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
    +	                $pageposbeforenote = $pagenb;
    +
    +	                $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
    +	                complete_substitutions_array($substitutionarray, $outputlangs, $object);
    +	                $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    +
    +
    +	                $pdf->startTransaction();
    +
    +	                $pdf->SetFont('','', $default_font_size - 1);
    +	                $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
    +	                // Description
    +	                $pageposafternote=$pdf->getPage();
    +	                $posyafter = $pdf->GetY();
    +
    +	                if($pageposafternote>$pageposbeforenote )
    +	                {
    +	                    $pdf->rollbackTransaction(true);
    +
    +	                    // prepar pages to receive notes
    +	                    while ($pagenb < $pageposafternote) {
    +	                        $pdf->AddPage();
    +	                        $pagenb++;
    +	                        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +	                        // $this->_pagefoot($pdf,$object,$outputlangs,1);
    +	                        $pdf->setTopMargin($tab_top_newpage);
    +	                        // The only function to edit the bottom margin of current page to set it.
    +	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +	                    }
    +
    +	                    // back to start
    +	                    $pdf->setPage($pageposbeforenote);
    +	                    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +	                    $pdf->SetFont('','', $default_font_size - 1);
    +	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
    +	                    $pageposafternote=$pdf->getPage();
    +
    +	                    $posyafter = $pdf->GetY();
    +
    +	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
    +	                    {
    +	                        $pdf->AddPage('','',true);
    +	                        $pagenb++;
    +	                        $pageposafternote++;
    +	                        $pdf->setPage($pageposafternote);
    +	                        $pdf->setTopMargin($tab_top_newpage);
    +	                        // The only function to edit the bottom margin of current page to set it.
    +	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +	                        //$posyafter = $tab_top_newpage;
    +	                    }
    +
    +
    +	                    // apply note frame to previus pages
    +	                    $i = $pageposbeforenote;
    +	                    while ($i < $pageposafternote) {
    +	                        $pdf->setPage($i);
    +
    +
    +	                        $pdf->SetDrawColor(128,128,128);
    +	                        // Draw note frame
    +	                        if($i>$pageposbeforenote){
    +	                            $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
    +	                            $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
    +	                        }
    +	                        else{
    +	                            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
    +	                            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
    +	                        }
    +
    +	                        // Add footer
    +	                        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +	                        $this->_pagefoot($pdf,$object,$outputlangs,1);
    +
    +	                        $i++;
    +	                    }
    +
    +	                    // apply note frame to last page
    +	                    $pdf->setPage($pageposafternote);
    +	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +	                    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +	                    $height_note=$posyafter-$tab_top_newpage;
    +	                    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    +	                }
    +	                else // No pagebreak
    +	                {
    +	                    $pdf->commitTransaction();
    +	                    $posyafter = $pdf->GetY();
    +	                    $height_note=$posyafter-$tab_top;
    +	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    +
    +
    +	                    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
    +	                    {
    +	                        // not enough space, need to add page
    +	                        $pdf->AddPage('','',true);
    +	                        $pagenb++;
    +	                        $pageposafternote++;
    +	                        $pdf->setPage($pageposafternote);
    +	                        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +
    +	                        $posyafter = $tab_top_newpage;
    +	                    }
    +	                }
    +
    +	                $tab_height = $tab_height - $height_note;
    +	                $tab_top = $posyafter +6;
    +	            }
    +	            else
    +	            {
    +	                $height_note=0;
    +	            }
    +
    +	            $iniY = $tab_top + 7;
    +	            $curY = $tab_top + 7;
    +	            $nexY = $tab_top + 7;
    +
    +	            // Use new auto collum system
    +	            $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    +
    +	            // Loop on each lines
    +	            $pageposbeforeprintlines=$pdf->getPage();
    +	            $pagenb = $pageposbeforeprintlines;
    +	            for ($i = 0; $i < $nblignes; $i++)
    +	            {
    +
    +	                $curY = $nexY;
    +	                $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
    +	                $pdf->SetTextColor(0,0,0);
    +
    +	                // Define size of image if we need it
    +	                $imglinesize=array();
    +	                if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
    +
    +	                $pdf->setTopMargin($tab_top_newpage);
    +	                $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
    +	                $pageposbefore=$pdf->getPage();
    +
    +	                $showpricebeforepagebreak=1;
    +	                $posYAfterImage=0;
    +	                $posYAfterDescription=0;
    +
    +	                if($this->getColumnStatus('photo'))
    +	                {
    +    	                // We start with Photo of product line
    +    	                if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforinfotot)))	// If photo too high, we moved completely on new page
    +    	                {
    +    	                    $pdf->AddPage('','',true);
    +    	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +    	                    $pdf->setPage($pageposbefore+1);
    +
    +    	                    $curY = $tab_top_newpage;
    +    	                    $showpricebeforepagebreak=0;
    +    	                }
    +
    +    	                if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
    +    	                {
    +    	                    $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
    +    	                    // $pdf->Image does not increase value return by getY, so we save it manually
    +    	                    $posYAfterImage=$curY+$imglinesize['height'];
    +    	                }
    +	                }
    +
    +	                // Description of product line
    +	                if ($this->getColumnStatus('desc'))
    +	                {
    +    	                $pdf->startTransaction();
    +    	                pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    +    	                $pageposafter=$pdf->getPage();
    +    	                if ($pageposafter > $pageposbefore)	// There is a pagebreak
    +    	                {
    +    	                    $pdf->rollbackTransaction(true);
    +    	                    $pageposafter=$pageposbefore;
    +    	                    //print $pageposafter.'-'.$pageposbefore;exit;
    +    	                    $pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
    +    	                    pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    +    	                    $pageposafter=$pdf->getPage();
    +    	                    $posyafter=$pdf->GetY();
    +    	                    //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
    +    	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot)))	// There is no space left for total+free text
    +    	                    {
    +    	                        if ($i == ($nblignes-1))	// No more lines, and no space left to show total, so we create a new page
    +    	                        {
    +    	                            $pdf->AddPage('','',true);
    +    	                            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +    	                            $pdf->setPage($pageposafter+1);
    +    	                        }
    +    	                    }
    +    	                    else
    +    	                    {
    +    	                        // We found a page break
    +    	                        $showpricebeforepagebreak=0;
    +    	                    }
    +    	                }
    +    	                else	// No pagebreak
    +    	                {
    +    	                    $pdf->commitTransaction();
    +    	                }
    +    	                $posYAfterDescription=$pdf->GetY();
    +	                }
    +
    +	                $nexY = $pdf->GetY();
    +	                $pageposafter=$pdf->getPage();
    +	                $pdf->setPage($pageposbefore);
    +	                $pdf->setTopMargin($this->marge_haute);
    +	                $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +
    +	                // We suppose that a too long description or photo were moved completely on next page
    +	                if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
    +	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
    +	                }
    +
    +	                $pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
    +
    +	                // VAT Rate
    +	                if ($this->getColumnStatus('vat'))
    +	                {
    +	                    $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
    +	                    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +	                // Unit price before discount
    +	                if ($this->getColumnStatus('subprice'))
    +	                {
    +	                    $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
    +	                    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +	                // Quantity
    +	                // Enough for 6 chars
    +	                if ($this->getColumnStatus('qty'))
    +	                {
    +	                    $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
    +	                    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +	                // Situation progress
    +	                if ($this->getColumnStatus('progress'))
    +	                {
    +	                    $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails);
    +	                    $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +	                // Unit
    +	                if ($this->getColumnStatus('unit'))
    +	                {
    +	                    $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
    +	                    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +	                // Discount on line
    +	                if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
    +	                {
    +	                    $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
    +	                    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +	                // Total HT line
    +	                if ($this->getColumnStatus('totalexcltax'))
    +	                {
    +	                    $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
    +	                    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
    +	                    $nexY = max($pdf->GetY(),$nexY);
    +	                }
    +
    +
    +	                $parameters=array(
    +	                    'object' => $object,
    +	                    'i' => $i,
    +	                    'pdf' =>& $pdf,
    +	                    'curY' =>& $curY,
    +	                    'nexY' =>& $nexY,
    +	                    'outputlangs' => $outputlangs,
    +	                    'hidedetails' => $hidedetails
    +	                );
    +	                $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    +
    +
    +
    +	                $sign=1;
    +	                if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
    +	                // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
    +	                $prev_progress = $object->lines[$i]->get_prev_progress($object->id);
    +	                if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation
    +	                {
    +	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
    +	                    else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent;
    +	                } else {
    +	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne= $sign * $object->lines[$i]->multicurrency_total_tva;
    +	                    else $tvaligne= $sign * $object->lines[$i]->total_tva;
    +	                }
    +
    +	                $localtax1ligne=$object->lines[$i]->total_localtax1;
    +	                $localtax2ligne=$object->lines[$i]->total_localtax2;
    +	                $localtax1_rate=$object->lines[$i]->localtax1_tx;
    +	                $localtax2_rate=$object->lines[$i]->localtax2_tx;
    +	                $localtax1_type=$object->lines[$i]->localtax1_type;
    +	                $localtax2_type=$object->lines[$i]->localtax2_type;
    +
    +	                if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
    +	                if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
    +	                if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
    +
    +	                $vatrate=(string) $object->lines[$i]->tva_tx;
    +
    +	                // Retrieve type from database for backward compatibility with old records
    +	                if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
    +	                    && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
    +	                {
    +	                    $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0, $object->thirdparty, $mysoc);
    +	                    $localtax1_type = $localtaxtmp_array[0];
    +	                    $localtax2_type = $localtaxtmp_array[2];
    +	                }
    +
    +	                // retrieve global local tax
    +	                if ($localtax1_type && $localtax1ligne != 0)
    +	                    $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
    +	                    if ($localtax2_type && $localtax2ligne != 0)
    +	                        $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
    +
    +	                        if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
    +	                        if (! isset($this->tva[$vatrate])) 				$this->tva[$vatrate]=0;
    +	                        $this->tva[$vatrate] += $tvaligne;
    +
    +	                        $nexY = max($nexY,$posYAfterImage);
    +
    +	                        // Add line
    +	                        if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
    +	                        {
    +	                            $pdf->setPage($pageposafter);
    +	                            $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
    +	                            //$pdf->SetDrawColor(190,190,200);
    +	                            $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
    +	                            $pdf->SetLineStyle(array('dash'=>0));
    +	                        }
    +
    +	                        $nexY+=2;    // Passe espace entre les lignes
    +
    +	                        // Detect if some page were added automatically and output _tableau for past pages
    +	                        while ($pagenb < $pageposafter)
    +	                        {
    +	                            $pdf->setPage($pagenb);
    +	                            if ($pagenb == $pageposbeforeprintlines)
    +	                            {
    +	                                $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
    +	                            }
    +	                            else
    +	                            {
    +	                                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
    +	                            }
    +	                            $this->_pagefoot($pdf,$object,$outputlangs,1);
    +	                            $pagenb++;
    +	                            $pdf->setPage($pagenb);
    +	                            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +	                        }
    +
    +	                        if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
    +	                        {
    +	                            if ($pagenb == $pageposafter)
    +	                            {
    +	                                $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
    +	                            }
    +	                            else
    +	                            {
    +	                                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
    +	                            }
    +	                            $this->_pagefoot($pdf,$object,$outputlangs,1);
    +	                            // New page
    +	                            $pdf->AddPage();
    +	                            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +	                            $pagenb++;
    +	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +	                        }
    +	            }
    +
    +	            // Show square
    +	            if ($pagenb == $pageposbeforeprintlines)
    +	            {
    +	                $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
    +	                $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
    +	            }
    +	            else
    +	            {
    +	                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
    +	                $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
    +	            }
    +
    +	            // Affiche zone infos
    +	            $posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
    +
    +	            // Affiche zone totaux
    +	            $posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
    +
    +	            // Affiche zone versements
    +	            if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
    +	            {
    +	                $posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
    +	            }
    +
    +	            // Pied de page
    +	            $this->_pagefoot($pdf,$object,$outputlangs);
    +	            if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
    +
    +	            $pdf->Close();
    +
    +	            $pdf->Output($file,'F');
    +
    +	            // Add pdfgeneration hook
    +	            $hookmanager->initHooks(array('pdfgeneration'));
    +	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
    +	            global $action;
    +	            $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +
    +	            if (! empty($conf->global->MAIN_UMASK))
    +	                @chmod($file, octdec($conf->global->MAIN_UMASK));
    +
    +	                $this->result = array('fullpath'=>$file);
    +
    +	                return 1;   // No error
    +	        }
    +	        else
    +	        {
    +	            $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
    +	            return 0;
    +	        }
    +	    }
    +	    else
    +	    {
    +	        $this->error=$langs->transnoentities("ErrorConstantNotDefined","FAC_OUTPUTDIR");
    +	        return 0;
    +	    }
    +	}
    +
    +
    +	/**
    +	 *  Show payments table
    +	 *
    +     *  @param	PDF			$pdf           Object PDF
    +     *  @param  Object		$object         Object invoice
    +     *  @param  int			$posy           Position y in PDF
    +     *  @param  Translate	$outputlangs    Object langs for output
    +     *  @return int             			<0 if KO, >0 if OK
    +	 */
    +	function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
    +	{
    +		global $conf;
    +
    +        $sign=1;
    +        if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
    +
    +        $tab3_posx = 120;
    +		$tab3_top = $posy + 8;
    +		$tab3_width = 80;
    +		$tab3_height = 4;
    +		if ($this->page_largeur < 210) // To work with US executive format
    +		{
    +			$tab3_posx -= 20;
    +		}
    +
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$title=$outputlangs->transnoentities("PaymentsAlreadyDone");
    +		if ($object->type == 2) $title=$outputlangs->transnoentities("PaymentsBackAlreadyDone");
    +
    +		$pdf->SetFont('','', $default_font_size - 3);
    +		$pdf->SetXY($tab3_posx, $tab3_top - 4);
    +		$pdf->MultiCell(60, 3, $title, 0, 'L', 0);
    +
    +		$pdf->line($tab3_posx, $tab3_top, $tab3_posx+$tab3_width, $tab3_top);
    +
    +		$pdf->SetFont('','', $default_font_size - 4);
    +		$pdf->SetXY($tab3_posx, $tab3_top);
    +		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0);
    +		$pdf->SetXY($tab3_posx+21, $tab3_top);
    +		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0);
    +		$pdf->SetXY($tab3_posx+40, $tab3_top);
    +		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0);
    +		$pdf->SetXY($tab3_posx+58, $tab3_top);
    +		$pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0);
    +
    +		$pdf->line($tab3_posx, $tab3_top-1+$tab3_height, $tab3_posx+$tab3_width, $tab3_top-1+$tab3_height);
    +
    +		$y=0;
    +
    +		$pdf->SetFont('','', $default_font_size - 4);
    +
    +
    +		// Loop on each deposits and credit notes included
    +		$sql = "SELECT re.rowid, re.amount_ht, re.multicurrency_amount_ht, re.amount_tva, re.multicurrency_amount_tva,  re.amount_ttc, re.multicurrency_amount_ttc,";
    +		$sql.= " re.description, re.fk_facture_source,";
    +		$sql.= " f.type, f.datef";
    +		$sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re, ".MAIN_DB_PREFIX ."facture as f";
    +		$sql.= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".$object->id;
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			$num = $this->db->num_rows($resql);
    +			$i=0;
    +			$invoice=new Facture($this->db);
    +			while ($i < $num)
    +			{
    +				$y+=3;
    +				$obj = $this->db->fetch_object($resql);
    +
    +				if ($obj->type == 2) $text=$outputlangs->trans("CreditNote");
    +				elseif ($obj->type == 3) $text=$outputlangs->trans("Deposit");
    +				else $text=$outputlangs->trans("UnknownType");
    +
    +				$invoice->fetch($obj->fk_facture_source);
    +
    +				$pdf->SetXY($tab3_posx, $tab3_top+$y);
    +				$pdf->MultiCell(20, 3, dol_print_date($obj->datef,'day',false,$outputlangs,true), 0, 'L', 0);
    +				$pdf->SetXY($tab3_posx+21, $tab3_top+$y);
    +				$pdf->MultiCell(20, 3, price(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0);
    +				$pdf->SetXY($tab3_posx+40, $tab3_top+$y);
    +				$pdf->MultiCell(20, 3, $text, 0, 'L', 0);
    +				$pdf->SetXY($tab3_posx+58, $tab3_top+$y);
    +				$pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0);
    +
    +				$pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
    +
    +				$i++;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$this->db->lasterror();
    +			return -1;
    +		}
    +
    +		// Loop on each payment
    +		// TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql
    +		$sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,";
    +		$sql.= " cp.code";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p";
    +		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id";
    +		$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id;
    +		//$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1";
    +		$sql.= " ORDER BY p.datep";
    +
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			$num = $this->db->num_rows($resql);
    +			$i=0;
    +			while ($i < $num) {
    +				$y+=3;
    +				$row = $this->db->fetch_object($resql);
    +
    +				$pdf->SetXY($tab3_posx, $tab3_top+$y);
    +				$pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date),'day',false,$outputlangs,true), 0, 'L', 0);
    +				$pdf->SetXY($tab3_posx+21, $tab3_top+$y);
    +				$pdf->MultiCell(20, 3, price($sign * (($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0);
    +				$pdf->SetXY($tab3_posx+40, $tab3_top+$y);
    +				$oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort" . $row->code);
    +
    +				$pdf->MultiCell(20, 3, $oper, 0, 'L', 0);
    +				$pdf->SetXY($tab3_posx+58, $tab3_top+$y);
    +				$pdf->MultiCell(30, 3, $row->num, 0, 'L', 0);
    +
    +				$pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3);
    +
    +				$i++;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$this->db->lasterror();
    +			return -1;
    +		}
    +	}
    +
    +
    +	/**
    +	 *   Show miscellaneous information (payment mode, payment term, ...)
    +	 *
    +	 *   @param		PDF			$pdf     		Object PDF
    +	 *   @param		Object		$object			Object to show
    +	 *   @param		int			$posy			Y
    +	 *   @param		Translate	$outputlangs	Langs object
    +	 *   @return	void
    +	 */
    +	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
    +	{
    +		global $conf;
    +
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// If France, show VAT mention if not applicable
    +		if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
    +
    +			$posy=$pdf->GetY()+4;
    +		}
    +
    +		$posxval=52;
    +
    +		// Show payments conditions
    +		if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement))
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("PaymentConditions").':';
    +			$pdf->MultiCell(43, 4, $titre, 0, 'L');
    +
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
    +			$lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
    +			$pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
    +
    +			$posy=$pdf->GetY()+3;
    +		}
    +
    +		if ($object->type != 2)
    +		{
    +			// Check a payment mode is defined
    +			if (empty($object->mode_reglement_code)
    +			&& empty($conf->global->FACTURE_CHQ_NUMBER)
    +			&& empty($conf->global->FACTURE_RIB_NUMBER))
    +			{
    +				$this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured");
    +			}
    +			// Avoid having any valid PDF with setup that is not complete
    +			elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))
    +				|| ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)))
    +			{
    +				$outputlangs->load("errors");
    +
    +				$pdf->SetXY($this->marge_gauche, $posy);
    +				$pdf->SetTextColor(200,0,0);
    +				$pdf->SetFont('','B', $default_font_size - 2);
    +				$this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup",$object->mode_reglement_code);
    +				$pdf->MultiCell(80, 3, $this->error,0,'L',0);
    +				$pdf->SetTextColor(0,0,0);
    +
    +				$posy=$pdf->GetY()+1;
    +			}
    +
    +			// Show payment mode
    +			if ($object->mode_reglement_code
    +			&& $object->mode_reglement_code != 'CHQ'
    +			&& $object->mode_reglement_code != 'VIR')
    +			{
    +				$pdf->SetFont('','B', $default_font_size - 2);
    +				$pdf->SetXY($this->marge_gauche, $posy);
    +				$titre = $outputlangs->transnoentities("PaymentMode").':';
    +				$pdf->MultiCell(80, 5, $titre, 0, 'L');
    +
    +				$pdf->SetFont('','', $default_font_size - 2);
    +				$pdf->SetXY($posxval, $posy);
    +				$lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
    +				$pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
    +
    +				$posy=$pdf->GetY()+2;
    +			}
    +
    +			// Show payment mode CHQ
    +			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
    +			{
    +				// Si mode reglement non force ou si force a CHQ
    +				if (! empty($conf->global->FACTURE_CHQ_NUMBER))
    +				{
    +					$diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
    +
    +					if ($conf->global->FACTURE_CHQ_NUMBER > 0)
    +					{
    +						$account = new Account($this->db);
    +						$account->fetch($conf->global->FACTURE_CHQ_NUMBER);
    +
    +						$pdf->SetXY($this->marge_gauche, $posy);
    +						$pdf->SetFont('','B', $default_font_size - $diffsizetitle);
    +						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
    +						$posy=$pdf->GetY()+1;
    +
    +			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
    +			            {
    +							$pdf->SetXY($this->marge_gauche, $posy);
    +							$pdf->SetFont('','', $default_font_size - $diffsizetitle);
    +							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
    +							$posy=$pdf->GetY()+2;
    +			            }
    +					}
    +					if ($conf->global->FACTURE_CHQ_NUMBER == -1)
    +					{
    +						$pdf->SetXY($this->marge_gauche, $posy);
    +						$pdf->SetFont('','B', $default_font_size - $diffsizetitle);
    +						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
    +						$posy=$pdf->GetY()+1;
    +
    +			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
    +			            {
    +							$pdf->SetXY($this->marge_gauche, $posy);
    +							$pdf->SetFont('','', $default_font_size - $diffsizetitle);
    +							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
    +							$posy=$pdf->GetY()+2;
    +			            }
    +					}
    +				}
    +			}
    +
    +			// If payment mode not forced or forced to VIR, show payment with BAN
    +			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
    +			{
    +				if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
    +				{
    +					$bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
    +					if (! empty($object->fk_bank)) $bankid=$object->fk_bank;   // For backward compatibility when object->fk_account is forced with object->fk_bank
    +					$account = new Account($this->db);
    +					$account->fetch($bankid);
    +
    +					$curx=$this->marge_gauche;
    +					$cury=$posy;
    +
    +					$posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
    +
    +					$posy+=2;
    +				}
    +			}
    +		}
    +
    +		return $posy;
    +	}
    +
    +
    +	/**
    +	 *	Show total to pay
    +	 *
    +	 *	@param	PDF			$pdf           Object PDF
    +	 *	@param  Facture		$object         Object invoice
    +	 *	@param  int			$deja_regle     Montant deja regle
    +	 *	@param	int			$posy			Position depart
    +	 *	@param	Translate	$outputlangs	Objet langs
    +	 *	@return int							Position pour suite
    +	 */
    +	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
    +	{
    +		global $conf,$mysoc;
    +
    +        $sign=1;
    +        if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
    +
    +        $default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$tab2_top = $posy;
    +		$tab2_hl = 4;
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// Tableau total
    +		$col1x = 120; $col2x = 170;
    +		if ($this->page_largeur < 210) // To work with US executive format
    +		{
    +			$col2x-=20;
    +		}
    +		$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
    +
    +		$useborder=0;
    +		$index = 0;
    +
    +		// Total HT
    +		$pdf->SetFillColor(255,255,255);
    +		$pdf->SetXY($col1x, $tab2_top + 0);
    +		$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
    +
    +		$total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
    +		$pdf->SetXY($col2x, $tab2_top + 0);
    +		$pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (! empty($object->remise)?$object->remise:0)), 0, $outputlangs), 0, 'R', 1);
    +
    +		// Show VAT by rates and total
    +		$pdf->SetFillColor(248,248,248);
    +
    +		$total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
    +
    +		$this->atleastoneratenotnull=0;
    +		if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
    +		{
    +			$tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
    +			if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
    +			{
    +				// Nothing to do
    +			}
    +			else
    +			{
    +			    // FIXME amount of vat not supported with multicurrency
    +
    +				//Local tax 1 before VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
    +				//{
    +					foreach( $this->localtax1 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey!=0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +	      		//}
    +				//Local tax 2 before VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
    +				//{
    +					foreach( $this->localtax2 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey!=0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +
    +                //}
    +
    +				// VAT
    +				// Situations totals migth be wrong on huge amounts
    +				if ($object->situation_cycle_ref && $object->situation_counter > 1) {
    +
    +					$sum_pdf_tva = 0;
    +					foreach($this->tva as $tvakey => $tvaval){
    +						$sum_pdf_tva+=$tvaval; // sum VAT amounts to compare to object
    +					}
    +
    +					if($sum_pdf_tva!=$object->total_tva) { // apply coef to recover the VAT object amount (the good one)
    +						$coef_fix_tva = $object->total_tva / $sum_pdf_tva;
    +
    +						foreach($this->tva as $tvakey => $tvaval) {
    +							$this->tva[$tvakey]=$tvaval * $coef_fix_tva;
    +						}
    +					}
    +				}
    +
    +				foreach($this->tva as $tvakey => $tvaval)
    +				{
    +					if ($tvakey != 0)    // On affiche pas taux 0
    +					{
    +						$this->atleastoneratenotnull++;
    +
    +						$index++;
    +						$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +						$tvacompl='';
    +						if (preg_match('/\*/',$tvakey))
    +						{
    +							$tvakey=str_replace('*','',$tvakey);
    +							$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +						}
    +						$totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
    +						$totalvat.=vatrate($tvakey,1).$tvacompl;
    +						$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +						$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +						$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +					}
    +				}
    +
    +				//Local tax 1 after VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
    +				//{
    +					foreach( $this->localtax1 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey != 0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +	      		//}
    +				//Local tax 2 after VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
    +				//{
    +					foreach( $this->localtax2 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +						    // retrieve global local tax
    +							if ($tvakey != 0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
    +
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					//}
    +				}
    +
    +				// Revenue stamp
    +				if (price2num($object->revenuestamp) != 0)
    +				{
    +					$index++;
    +					$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +					$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp"), $useborder, 'L', 1);
    +
    +					$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +					$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1);
    +				}
    +
    +				// Total TTC
    +				$index++;
    +				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +				$pdf->SetTextColor(0,0,60);
    +				$pdf->SetFillColor(224,224,224);
    +				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
    +
    +				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1);
    +			}
    +		}
    +
    +		$pdf->SetTextColor(0,0,0);
    +
    +		$creditnoteamount=$object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    +		$depositsamount=$object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    +		//print "x".$creditnoteamount."-".$depositsamount;exit;
    +		$resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT');
    +		if ($object->paye) $resteapayer=0;
    +
    +		if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS))
    +		{
    +			// Already paid + Deposits
    +			$index++;
    +			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("Paid"), 0, 'L', 0);
    +			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0);
    +
    +			// Credit note
    +			if ($creditnoteamount)
    +			{
    +				$index++;
    +				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("CreditNotes"), 0, 'L', 0);
    +				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0);
    +			}
    +
    +			// Escompte
    +			if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT)
    +			{
    +				$index++;
    +				$pdf->SetFillColor(255,255,255);
    +
    +				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
    +				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1);
    +
    +				$resteapayer=0;
    +			}
    +
    +			$index++;
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->SetFillColor(224,224,224);
    +			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
    +			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
    +
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->SetTextColor(0,0,0);
    +		}
    +
    +		$index++;
    +		return ($tab2_top + ($tab2_hl * $index));
    +	}
    +
    +	/**
    +	 *   Show table for lines
    +	 *
    +	 *   @param		PDF			$pdf     		Object PDF
    +	 *   @param		string		$tab_top		Top position of table
    +	 *   @param		string		$tab_height		Height of table (rectangle)
    +	 *   @param		int			$nexY			Y (not used)
    +	 *   @param		Translate	$outputlangs	Langs object
    +	 *   @param		int			$hidetop		1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
    +	 *   @param		int			$hidebottom		Hide bottom bar of array
    +	 *   @param		string		$currency		Currency code
    +	 *   @return	void
    +	 */
    +	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
    +	{
    +		global $conf;
    +
    +		// Force to disable hidetop and hidebottom
    +		$hidebottom=0;
    +		if ($hidetop) $hidetop=-1;
    +
    +		$currency = !empty($currency) ? $currency : $conf->currency;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		// Amount in (at tab_top - 1)
    +		$pdf->SetTextColor(0,0,0);
    +		$pdf->SetFont('','', $default_font_size - 2);
    +
    +		if (empty($hidetop))
    +		{
    +			$titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
    +			$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
    +			$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
    +
    +			//$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
    +			if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
    +		}
    +
    +		$pdf->SetDrawColor(128,128,128);
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// Output Rect
    +		$this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
    +
    +
    +		foreach ($this->cols as $colKey => $colDef)
    +		{
    +		    if(!$this->getColumnStatus($colKey)) continue;
    +
    +		    // get title label
    +		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    +
    +		    // Add column separator
    +		    if(!empty($colDef['border-left'])){
    +		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
    +		    }
    +
    +		    if (empty($hidetop))
    +		    {
    +		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    +
    +		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
    +		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
    +		    }
    +		}
    +
    +		if (empty($hidetop)){
    +			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
    +		}
    +	}
    +
    +	/**
    +	 *  Show top header of page.
    +	 *
    +	 *  @param	PDF			$pdf     		Object PDF
    +	 *  @param  Object		$object     	Object to show
    +	 *  @param  int	    	$showaddress    0=no, 1=yes
    +	 *  @param  Translate	$outputlangs	Object lang for output
    +	 *  @return	void
    +	 */
    +	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
    +	{
    +		global $conf, $langs;
    +
    +		// Translations
    +		$outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
    +
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
    +
    +		// Show Draft Watermark
    +		if($object->statut==Facture::STATUS_DRAFT && (! empty($conf->global->FACTURE_DRAFT_WATERMARK)) )
    +        {
    +		      pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->FACTURE_DRAFT_WATERMARK);
    +        }
    +
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->SetFont('','B', $default_font_size + 3);
    +
    +		$w = 110;
    +
    +		$posy=$this->marge_haute;
    +        $posx=$this->page_largeur-$this->marge_droite-$w;
    +
    +		$pdf->SetXY($this->marge_gauche,$posy);
    +
    +		// Logo
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
    +		{
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
    +			{
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +					$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
    +			}
    +			else
    +			{
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    +			}
    +		}
    +
    +		$pdf->SetFont('','B', $default_font_size + 3);
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$title=$outputlangs->transnoentities("PdfInvoiceTitle");
    +		if ($object->type == 1) $title=$outputlangs->transnoentities("InvoiceReplacement");
    +		if ($object->type == 2) $title=$outputlangs->transnoentities("InvoiceAvoir");
    +		if ($object->type == 3) $title=$outputlangs->transnoentities("InvoiceDeposit");
    +		if ($object->type == 4) $title=$outputlangs->transnoentities("InvoiceProForma");
    +		if ($this->situationinvoice) $title=$outputlangs->transnoentities("InvoiceSituation");
    +		$pdf->MultiCell($w, 3, $title, '', 'R');
    +
    +		$pdf->SetFont('','B',$default_font_size);
    +
    +		$posy+=5;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$textref=$outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref);
    +		if ($object->statut == Facture::STATUS_DRAFT)
    +		{
    +			$pdf->SetTextColor(128,0,0);
    +			$textref.=' - '.$outputlangs->transnoentities("NotValidated");
    +		}
    +		$pdf->MultiCell($w, 4, $textref, '', 'R');
    +
    +		$posy+=1;
    +		$pdf->SetFont('','', $default_font_size - 2);
    +
    +		if ($object->ref_client)
    +		{
    +			$posy+=4;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
    +		}
    +
    +		$objectidnext=$object->getIdReplacingInvoice('validated');
    +		if ($object->type == 0 && $objectidnext)
    +		{
    +			$objectreplacing=new Facture($this->db);
    +			$objectreplacing->fetch($objectidnext);
    +
    +			$posy+=3;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R');
    +		}
    +		if ($object->type == 1)
    +		{
    +			$objectreplaced=new Facture($this->db);
    +			$objectreplaced->fetch($object->fk_facture_source);
    +
    +			$posy+=4;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
    +		}
    +		if ($object->type == 2 && !empty($object->fk_facture_source))
    +		{
    +			$objectreplaced=new Facture($this->db);
    +			$objectreplaced->fetch($object->fk_facture_source);
    +
    +			$posy+=3;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R');
    +		}
    +
    +		$posy+=4;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateInvoice")." : " . dol_print_date($object->date,"day",false,$outputlangs), '', 'R');
    +
    +		if (! empty($conf->global->INVOICE_POINTOFTAX_DATE))
    +		{
    +			$posy+=4;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : " . dol_print_date($object->date_pointoftax,"day",false,$outputlangs), '', 'R');
    +		}
    +
    +		if ($object->type != 2)
    +		{
    +			$posy+=3;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateDue")." : " . dol_print_date($object->date_lim_reglement,"day",false,$outputlangs,true), '', 'R');
    +		}
    +
    +		if ($object->thirdparty->code_client)
    +		{
    +			$posy+=3;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
    +		}
    +
    +		// Get contact
    +		if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
    +		{
    +		    $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
    +		    if (count($arrayidcontact) > 0)
    +		    {
    +		        $usertmp=new User($this->db);
    +		        $usertmp->fetch($arrayidcontact[0]);
    +                $posy+=4;
    +                $pdf->SetXY($posx,$posy);
    +		        $pdf->SetTextColor(0,0,60);
    +		        $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
    +		    }
    +		}
    +
    +		$posy+=1;
    +
    +		$top_shift = 0;
    +		// Show list of linked objects
    +		$current_y = $pdf->getY();
    +		$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size);
    +		if ($current_y < $pdf->getY())
    +		{
    +			$top_shift = $pdf->getY() - $current_y;
    +		}
    +
    +		if ($showaddress)
    +		{
    +			// Sender properties
    +			$carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
    +
    +			// Show sender
    +			$posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
    +			$posy+=$top_shift;
    +			$posx=$this->marge_gauche;
    +			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
    +
    +			$hautcadre=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40;
    +			$widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82;
    +
    +
    +			// Show sender frame
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posx,$posy-5);
    +			$pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetFillColor(230,230,230);
    +			$pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1);
    +			$pdf->SetTextColor(0,0,60);
    +
    +			// Show sender name
    +			$pdf->SetXY($posx+2,$posy+3);
    +			$pdf->SetFont('','B', $default_font_size);
    +			$pdf->MultiCell($widthrecbox-2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
    +			$posy=$pdf->getY();
    +
    +			// Show sender information
    +			$pdf->SetXY($posx+2,$posy);
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->MultiCell($widthrecbox-2, 4, $carac_emetteur, 0, 'L');
    +
    +			// If BILLING contact defined on invoice, we use it
    +			$usecontact=false;
    +			$arrayidcontact=$object->getIdContact('external','BILLING');
    +			if (count($arrayidcontact) > 0)
    +			{
    +				$usecontact=true;
    +				$result=$object->fetch_contact($arrayidcontact[0]);
    +			}
    +
    +			//Recipient name
    +			// On peut utiliser le nom de la societe du contact
    +			if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
    +				$thirdparty = $object->contact;
    +			} else {
    +				$thirdparty = $object->thirdparty;
    +			}
    +
    +			$carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
    +
    +			$carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object);
    +
    +			// Show recipient
    +			$widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100;
    +			if ($this->page_largeur < 210) $widthrecbox=84;	// To work with US executive format
    +			$posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42;
    +			$posy+=$top_shift;
    +			$posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
    +			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
    +
    +			// Show recipient frame
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posx+2,$posy-5);
    +			$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L');
    +			$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
    +
    +			// Show recipient name
    +			$pdf->SetXY($posx+2,$posy+3);
    +			$pdf->SetFont('','B', $default_font_size);
    +			$pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L');
    +
    +			$posy = $pdf->getY();
    +
    +			// Show recipient information
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->SetXY($posx+2,$posy);
    +			$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
    +		}
    +
    +		$pdf->SetTextColor(0,0,0);
    +		return $top_shift;
    +	}
    +
    +	/**
    +	 *   	Show footer of page. Need this->emetteur object
    +     *
    +	 *   	@param	PDF			$pdf     			PDF
    +	 * 		@param	Object		$object				Object to show
    +	 *      @param	Translate	$outputlangs		Object lang for output
    +	 *      @param	int			$hidefreetext		1=Hide free text
    +	 *      @return	int								Return height of bottom margin including footer text
    +	 */
    +	function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
    +	{
    +		global $conf;
    +		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
    +		return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
    +	}
    +
    +	/**
    +	 *   	Define Array Column Field
    +	 *
    +	 *   	@param	object			$object    		common object
    +	 *   	@param	outputlangs		$outputlangs    langs
    +     *      @param	int			   $hidedetails		Do not show line details
    +     *      @param	int			   $hidedesc		Do not show desc
    +     *      @param	int			   $hideref			Do not show ref
    +	 *      @return	null
    +	 */
    +    function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
    +	    global $conf, $hookmanager;
    +
    +	    // Default field style for content
    +	    $this->defaultContentsFieldsStyle = array(
    +	        'align' => 'R', // R,C,L
    +	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	    );
    +
    +	    // Default field style for content
    +	    $this->defaultTitlesFieldsStyle = array(
    +	        'align' => 'C', // R,C,L
    +	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	    );
    +
    +	    /*
    +	     * For exemple
    +	    $this->cols['theColKey'] = array(
    +	        'rank' => $rank, // int : use for ordering columns
    +	        'width' => 20, // the column width in mm
    +	        'title' => array(
    +	            'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
    +	            'label' => ' ', // the final label : used fore final generated text
    +	            'align' => 'L', // text alignement :  R,C,L
    +	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	        'content' => array(
    +	            'align' => 'L', // text alignement :  R,C,L
    +	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	    );
    +	    */
    +
    +	    $rank=0; // do not use negative rank
    +	    $this->cols['desc'] = array(
    +	        'rank' => $rank,
    +	        'width' => false, // only for desc
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'Designation', // use lang key is usefull in somme case with module
    +	            'align' => 'L',
    +	            // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
    +	            // 'label' => ' ', // the final label
    +	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	        'content' => array(
    +	            'align' => 'L',
    +	        ),
    +	    );
    +
    +	    // PHOTO
    +        $rank = $rank + 10;
    +        $this->cols['photo'] = array(
    +            'rank' => $rank,
    +            'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
    +            'status' => false,
    +            'title' => array(
    +                'textkey' => 'Photo',
    +                'label' => ' '
    +            ),
    +            'content' => array(
    +                'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +            ),
    +            'border-left' => false, // remove left line separator
    +        );
    +
    +	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
    +	    {
    +	        $this->cols['photo']['status'] = true;
    +	    }
    +
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['vat'] = array(
    +	        'rank' => $rank,
    +	        'status' => false,
    +	        'width' => 16, // in mm
    +	        'title' => array(
    +	            'textkey' => 'VAT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
    +	    {
    +	        $this->cols['vat']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['subprice'] = array(
    +	        'rank' => $rank,
    +	        'width' => 19, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'PriceUHT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['qty'] = array(
    +	        'rank' => $rank,
    +	        'width' => 16, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'Qty'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['progress'] = array(
    +	        'rank' => $rank,
    +	        'width' => 19, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Progress'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    if($this->situationinvoice)
    +	    {
    +	        $this->cols['progress']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['unit'] = array(
    +	        'rank' => $rank,
    +	        'width' => 11, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Unit'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +	    if($conf->global->PRODUCT_USE_UNITS){
    +	        $this->cols['unit']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['discount'] = array(
    +	        'rank' => $rank,
    +	        'width' => 13, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'ReductionShort'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +	    if ($this->atleastonediscount){
    +	        $this->cols['discount']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['totalexcltax'] = array(
    +	        'rank' => $rank,
    +	        'width' => 26, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'TotalHT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +
    +	    $parameters=array(
    +	        'object' => $object,
    +	        'outputlangs' => $outputlangs,
    +	        'hidedetails' => $hidedetails,
    +	        'hidedesc' => $hidedesc,
    +	        'hideref' => $hideref
    +	    );
    +
    +	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
    +	    if ($reshook < 0)
    +	    {
    +	        setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
    +	    }
    +	    elseif (empty($reshook))
    +	    {
    +	        $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
    +	    }
    +	    else
    +	    {
    +	        $this->cols = $hookmanager->resArray;
    +	    }
    +	}
    +}
    diff --git a/htdocs/core/modules/facture/mod_facture_mars.php b/htdocs/core/modules/facture/mod_facture_mars.php
    index 831dce5d3e4..a1ed1e32d24 100644
    --- a/htdocs/core/modules/facture/mod_facture_mars.php
    +++ b/htdocs/core/modules/facture/mod_facture_mars.php
    @@ -30,12 +30,24 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/facture/modules_facture.php';
      */
     class mod_facture_mars extends ModeleNumRefFactures
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefixinvoice='FA';
    -	var $prefixreplacement='FR';
    -	var $prefixdeposit='AC';
    -	var $prefixcreditnote='AV';
    -	var $error='';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefixinvoice='FA';
    +
    +	public $prefixreplacement='FR';
    +
    +	public $prefixdeposit='AC';
    +
    +	public $prefixcreditnote='AV';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -216,6 +228,5 @@ class mod_facture_mars extends ModeleNumRefFactures
     	{
     		return $this->getNextValue($objsoc,$objforref,$mode);
     	}
    -
     }
     
    diff --git a/htdocs/core/modules/facture/mod_facture_mercure.php b/htdocs/core/modules/facture/mod_facture_mercure.php
    index e826b18f0e0..dabd3fbd576 100644
    --- a/htdocs/core/modules/facture/mod_facture_mercure.php
    +++ b/htdocs/core/modules/facture/mod_facture_mercure.php
    @@ -33,8 +33,16 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/facture/modules_facture.php';
      */
     class mod_facture_mercure extends ModeleNumRefFactures
     {
    -    var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -    var $error = '';
    +    /**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +    /**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
     
     
         /**
    @@ -44,7 +52,7 @@ class mod_facture_mercure extends ModeleNumRefFactures
          */
         function info()
         {
    -        global $conf,$langs;
    +        global $conf, $langs;
     
             $langs->load("bills");
     
    @@ -78,7 +86,7 @@ class mod_facture_mercure extends ModeleNumRefFactures
             $texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceReplacement").'):</td>';
             $texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskreplacement" value="'.$conf->global->FACTURE_MERCURE_MASK_REPLACEMENT.'">',$tooltip,1,1).'</td>';
             $texte.= '</tr>';
    -        
    +
             // Parametrage du prefix des avoirs
             $texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'):</td>';
             $texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskcredit" value="'.$conf->global->FACTURE_MERCURE_MASK_CREDIT.'">',$tooltip,1,1).'</td>';
    @@ -135,7 +143,7 @@ class mod_facture_mercure extends ModeleNumRefFactures
     
             // Get Mask value
             $mask = '';
    -        if (is_object($facture) && $facture->type == 1) 
    +        if (is_object($facture) && $facture->type == 1)
             {
             	$mask=$conf->global->FACTURE_MERCURE_MASK_REPLACEMENT;
             	if (! $mask)
    @@ -175,5 +183,4 @@ class mod_facture_mercure extends ModeleNumRefFactures
         {
             return $this->getNextValue($objsoc,$objforref,$mode);
         }
    -
     }
    diff --git a/htdocs/core/modules/facture/mod_facture_terre.php b/htdocs/core/modules/facture/mod_facture_terre.php
    index 174d8314784..a55418a8cb5 100644
    --- a/htdocs/core/modules/facture/mod_facture_terre.php
    +++ b/htdocs/core/modules/facture/mod_facture_terre.php
    @@ -29,11 +29,22 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/facture/modules_facture.php';
      */
     class mod_facture_terre extends ModeleNumRefFactures
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefixinvoice='FA';
    -	var $prefixcreditnote='AV';
    -	var $prefixdeposit='AC';
    -	var $error='';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefixinvoice='FA';
    +
    +	public $prefixcreditnote='AV';
    +
    +	public $prefixdeposit='AC';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -232,6 +243,5 @@ class mod_facture_terre extends ModeleNumRefFactures
     	{
     		return $this->getNextValue($objsoc,$objforref,$mode);
     	}
    -
     }
     
    diff --git a/htdocs/core/modules/facture/modules_facture.php b/htdocs/core/modules/facture/modules_facture.php
    index b5d9a2397cc..12d41903edb 100644
    --- a/htdocs/core/modules/facture/modules_facture.php
    +++ b/htdocs/core/modules/facture/modules_facture.php
    @@ -37,8 +37,12 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';   // Requ
      */
     abstract class ModelePDFFactures extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
    @@ -48,6 +52,7 @@ abstract class ModelePDFFactures extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='invoice';
    @@ -61,11 +66,14 @@ abstract class ModelePDFFactures extends CommonDocGenerator
     }
     
     /**
    - *	Classe mere des modeles de numerotation des references de facture
    + *  Classe mere des modeles de numerotation des references de facture
      */
     abstract class ModeleNumRefFactures
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 * Return if a module can be used or not
    diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
    index aa7ed05070b..b67da288ae7 100644
    --- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
    +++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php
    @@ -38,21 +38,78 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
      */
     class pdf_soleil extends ModelePDFFicheinter
     {
    -	var $db;
    -	var $name;
    -	var $description;
    -	var $type;
    +	 /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -	var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -	var $page_largeur;
    -	var $page_hauteur;
    -	var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     	/**
     	 *	Constructor
    @@ -94,6 +151,7 @@ class pdf_soleil extends ModelePDFFicheinter
     		$this->posxdesc=$this->marge_gauche+1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Function to build pdf onto disk
     	 *
    @@ -107,13 +165,14 @@ class pdf_soleil extends ModelePDFFicheinter
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "interventions", "dict", "companies"));
     
     		if ($conf->ficheinter->dir_output)
    @@ -496,10 +555,8 @@ class pdf_soleil extends ModelePDFFicheinter
     		global $conf,$langs;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("interventions");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "interventions"));
     
     		pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
     
    @@ -675,6 +732,4 @@ class pdf_soleil extends ModelePDFFicheinter
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'FICHINTER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/fichinter/mod_arctic.php b/htdocs/core/modules/fichinter/mod_arctic.php
    index 278e20ae7de..82013e94413 100644
    --- a/htdocs/core/modules/fichinter/mod_arctic.php
    +++ b/htdocs/core/modules/fichinter/mod_arctic.php
    @@ -32,9 +32,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/fichinter/modules_fichinter.php';
      */
     class mod_arctic extends ModeleNumRefFicheinter
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'arctic';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='arctic';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='arctic';
     
     
     	/**
    @@ -44,7 +63,7 @@ class mod_arctic extends ModeleNumRefFicheinter
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -137,6 +156,5 @@ class mod_arctic extends ModeleNumRefFicheinter
         {
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
     
    diff --git a/htdocs/core/modules/fichinter/mod_pacific.php b/htdocs/core/modules/fichinter/mod_pacific.php
    index 7e60a6aed4b..dcf6baf5ef6 100644
    --- a/htdocs/core/modules/fichinter/mod_pacific.php
    +++ b/htdocs/core/modules/fichinter/mod_pacific.php
    @@ -30,10 +30,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/fichinter/modules_fichinter.php';
      */
     class mod_pacific extends ModeleNumRefFicheinter
     {
    -    var $version='dolibarr';        // 'development', 'experimental', 'dolibarr'
    -	var $prefix='FI';
    -	var $error='';
    -	var $nom = 'pacific';
    +    /**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';        // 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='FI';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='pacific';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='pacific';
     
     
     	/**
    @@ -142,6 +162,4 @@ class mod_pacific extends ModeleNumRefFicheinter
     	{
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/fichinter/modules_fichinter.php b/htdocs/core/modules/fichinter/modules_fichinter.php
    index 8bcb2990bdb..2d3c4bebfe6 100644
    --- a/htdocs/core/modules/fichinter/modules_fichinter.php
    +++ b/htdocs/core/modules/fichinter/modules_fichinter.php
    @@ -34,9 +34,13 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFFicheinter extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of active generation modules
     	 *
    @@ -46,6 +50,7 @@ abstract class ModelePDFFicheinter extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='ficheinter';
    @@ -64,7 +69,10 @@ abstract class ModelePDFFicheinter extends CommonDocGenerator
      */
     abstract class ModeleNumRefFicheinter
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 * 	Return if a module can be used or not
    @@ -141,6 +149,7 @@ abstract class ModeleNumRefFicheinter
     }
     
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *  Create an intervention document on disk using template defined into FICHEINTER_ADDON_PDF
      *
    @@ -155,6 +164,7 @@ abstract class ModeleNumRefFicheinter
      */
     function fichinter_create($db, $object, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
     {
    +    // phpcs:enable
     	global $conf,$langs,$user;
     	$langs->load("ficheinter");
     
    @@ -238,4 +248,3 @@ function fichinter_create($db, $object, $modele, $outputlangs, $hidedetails=0, $
     		return 0;
     	}
     }
    -
    diff --git a/htdocs/core/modules/holiday/index.html b/htdocs/core/modules/holiday/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/core/modules/holiday/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/core/modules/holiday/mod_holiday_immaculate.php b/htdocs/core/modules/holiday/mod_holiday_immaculate.php
    new file mode 100644
    index 00000000000..338b553166e
    --- /dev/null
    +++ b/htdocs/core/modules/holiday/mod_holiday_immaculate.php
    @@ -0,0 +1,154 @@
    +<?php
    +/* Copyright (C) 2011      Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2018      Charlene Benke		<charlie@patas-monkey.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *  \file       htdocs/core/modules/holiday/mod_holiday_immaculate.php
    + *  \ingroup    contract
    + *  \brief      File of class to manage contract numbering rules Magre
    + */
    +
    +require_once DOL_DOCUMENT_ROOT .'/core/modules/holiday/modules_holiday.php';
    +
    +/**
    + *	Class to manage contract numbering rules Magre
    + */
    +class mod_holiday_immaculate extends ModelNumRefHolidays
    +{
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see $name
    +	 */
    +	public $nom='Immaculate';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Immaculate';
    +
    +	public $code_auto=1;
    +
    +	/**
    +	 *	Return default description of numbering model
    +	 *
    +	 *	@return     string      text description
    +	 */
    +	function info()
    +    {
    +    	global $conf, $langs;
    +
    +		$langs->load("bills");
    +
    +		$form = new Form($this->db);
    +
    +		$texte = $langs->trans('GenericNumRefModelDesc')."<br>\n";
    +		$texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    +		$texte.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +		$texte.= '<input type="hidden" name="action" value="updateMask">';
    +		$texte.= '<input type="hidden" name="maskconstcontract" value="HOLIDAY_IMMACULATE_MASK">';
    +		$texte.= '<table class="nobordernopadding" width="100%">';
    +
    +		$tooltip=$langs->trans("GenericMaskCodes",$langs->transnoentities("Holiday"),$langs->transnoentities("Holiday"));
    +		$tooltip.=$langs->trans("GenericMaskCodes2");
    +		$tooltip.=$langs->trans("GenericMaskCodes3");
    +		$tooltip.=$langs->trans("GenericMaskCodes4a",$langs->transnoentities("Holiday"),$langs->transnoentities("Holiday"));
    +		$tooltip.=$langs->trans("GenericMaskCodes5");
    +
    +		$texte.= '<tr><td>'.$langs->trans("Mask").':</td>';
    +		$texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskholiday" value="'.$conf->global->HOLIDAY_IMMACULATE_MASK.'">',$tooltip,1,1).'</td>';
    +		$texte.= '<td align="left" rowspan="2">&nbsp; <input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button"></td>';
    +		$texte.= '</tr>';
    +		$texte.= '</table>';
    +		$texte.= '</form>';
    +
    +		return $texte;
    +    }
    +
    +	/**
    +	 *	Return numbering example
    +	 *
    +	 *	@return     string      Example
    +	 */
    +    function getExample()
    +    {
    +     	global $conf,$langs,$user;
    +
    +    	$old_login=$user->login;
    +    	$user->login='UUUUUUU';
    +     	$numExample = $this->getNextValue($user, '');
    +		$user->login=$old_login;
    +
    +		if (! $numExample)
    +		{
    +			$numExample = $langs->trans('NotConfigured');
    +		}
    +		return $numExample;
    +    }
    +
    +	/**
    +	 *	Return next value
    +	 *
    +	 *	@param	Societe		$user     	user object
    +	 *	@param	Object		$holiday	holiday object
    +	 *	@return string      			Value if OK, 0 if KO
    +	 */
    +    function getNextValue($user, $holiday)
    +    {
    +		global $db,$conf;
    +
    +		require_once DOL_DOCUMENT_ROOT .'/core/lib/functions2.lib.php';
    +
    +		$mask=$conf->global->HOLIDAY_IMMACULATE_MASK;
    +
    +		if (! $mask)
    +		{
    +			$this->error='NotConfigured';
    +			return 0;
    +		}
    +
    +		$numFinal=get_next_value($db,$mask,'holiday','ref','', $user, $holiday->date_create);
    +
    +		return  $numFinal;
    +	}
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *  Return next value
    +	 *
    +	 *  @param  User		$fuser     	User object
    +	 *  @param  Object		$objforref	Holiday object
    +	 *  @return string      			Value if OK, 0 if KO
    +	 */
    +    function holiday_get_num($fuser, $objforref)
    +    {
    +        // phpcs:enable
    +        return $this->getNextValue($fuser, $objforref);
    +    }
    +}
    diff --git a/htdocs/core/modules/holiday/mod_holiday_madonna.php b/htdocs/core/modules/holiday/mod_holiday_madonna.php
    new file mode 100644
    index 00000000000..f53e55be6fd
    --- /dev/null
    +++ b/htdocs/core/modules/holiday/mod_holiday_madonna.php
    @@ -0,0 +1,170 @@
    +<?php
    +/* Copyright (C) 2011      Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2018      Charlene Benke		<charlie@patas-monkey.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *  \file       htdocs/core/modules/holiday/mod_holiday_madonna.php
    + *  \ingroup    contract
    + *  \brief      File of class to manage contract numbering rules Serpis
    + */
    +require_once DOL_DOCUMENT_ROOT .'/core/modules/holiday/modules_holiday.php';
    +
    +/**
    + * 	Class to manage contract numbering rules madonna
    + */
    +class mod_holiday_madonna extends ModelNumRefHolidays
    +{
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $prefix='HL';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see $name
    +	 */
    +	public $nom='Madonna';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Madonna';
    +
    +	public $code_auto=1;
    +
    +
    +	/**
    +	 *	Return default description of numbering model
    +	 *
    +	 *	@return     string      text description
    +	 */
    +    function info()
    +    {
    +    	global $langs;
    +      	return $langs->trans("SimpleNumRefModelDesc",$this->prefix);
    +    }
    +
    +
    +	/**
    +	 *	Return numbering example
    +	 *
    +	 *	@return     string      Example
    +	 */
    +	function getExample()
    +	{
    +		return $this->prefix."0501-0001";
    +	}
    +
    +
    +	/**
    +	 *	Test if existing numbers make problems with numbering
    +	 *
    +	 *	@return     boolean     false if conflit, true if ok
    +	 */
    +	function canBeActivated()
    +	{
    +		global $conf,$langs,$db;
    +
    +		$coyymm=''; $max='';
    +
    +		$posindice=8;
    +		$sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."holiday";
    +		$sql.= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
    +		$sql.= " AND entity = ".$conf->entity;
    +
    +		$resql=$db->query($sql);
    +		if ($resql)
    +		{
    +			$row = $db->fetch_row($resql);
    +			if ($row) { $coyymm = substr($row[0],0,6); $max=$row[0]; }
    +		}
    +		if ($coyymm && ! preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i',$coyymm))
    +		{
    +			$langs->load("errors");
    +			$this->error=$langs->trans('ErrorNumRefModel', $max);
    +			return false;
    +		}
    +
    +		return true;
    +	}
    +
    +	/**
    +	 *	Return next value
    +	 *
    +	 *	@param	Societe		$objsoc     third party object
    +	 *	@param	Object		$holiday	Holiday object
    +	 *	@return string      			Value if OK, 0 if KO
    +	 */
    +	function getNextValue($objsoc, $holiday)
    +	{
    +		global $db,$conf;
    +
    +		$posindice=8;
    +		$sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."holiday";
    +		$sql.= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'";
    +		$sql.= " AND entity = ".$conf->entity;
    +
    +		$resql=$db->query($sql);
    +		if ($resql)
    +		{
    +			$obj = $db->fetch_object($resql);
    +			if ($obj) $max = intval($obj->max);
    +			else $max=0;
    +		}
    +		else
    +		{
    +			dol_syslog("mod_holiday_madonna::getNextValue", LOG_DEBUG);
    +			return -1;
    +		}
    +
    +		$date=$holiday->date_debut;
    +		$yymm = strftime("%y%m",$date);
    +
    +		if ($max >= (pow(10, 4) - 1)) $num=$max+1;	// If counter > 9999, we do not format on 4 chars, we take number as it is
    +		else $num = sprintf("%04s",$max+1);
    +
    +		dol_syslog("mod_holiday_madonna::getNextValue return ".$this->prefix.$yymm."-".$num);
    +		return $this->prefix.$yymm."-".$num;
    +	}
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *	Return next value
    +	 *
    +	 *	@param	User		$fuser     	User object
    +	 *	@param	Object		$objforref	Holiday object
    +	 *	@return string      			Value if OK, 0 if KO
    +	 */
    +	function holiday_get_num($fuser,$objforref)
    +	{
    +        // phpcs:enable
    +		return $this->getNextValue($fuser,$objforref);
    +	}
    +}
    diff --git a/htdocs/core/modules/holiday/modules_holiday.php b/htdocs/core/modules/holiday/modules_holiday.php
    new file mode 100644
    index 00000000000..07234c447e6
    --- /dev/null
    +++ b/htdocs/core/modules/holiday/modules_holiday.php
    @@ -0,0 +1,154 @@
    +<?php
    +/* Copyright (C) 2003-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2007 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2004      Eric Seigne          <eric.seigne@ryxeo.com>
    + * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    + * Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
    + * Copyright (C) 2011      Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2013      Philippe Grand	    <philippe.grand@atoo-net.com>
    + * Copyright (C) 2014      Marcos García        <marcosgdf@gmail.com>
    + * Copyright (C) 2018      Charlene Benke		<charlie@patas-monkey.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *  \file       htdocs/core/modules/holiday/modules_holiday.php
    + *  \ingroup    contract
    + *  \brief      File with parent class for generating holiday to PDF and File of class to manage contract numbering
    + */
    +
    + require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
    +
    +
    +/**
    + *	Parent class to manage holidays document templates
    + */
    +abstract class ModelePDFHoliday extends CommonDocGenerator
    +{
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +	 *	Return list of active generation modules
    +	 *
    +     *  @param  DoliDB  $db     			Database handler
    +     *  @param  integer	$maxfilenamelength  Max length of value to show
    +     *  @return	array						List of templates
    +     */
    +	static function liste_modeles($db, $maxfilenamelength=0)
    +	{
    +        // phpcs:enable
    +		global $conf;
    +
    +		$type = 'holiday';
    +		$list = array();
    +
    +		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +		$list = getListOfModels($db, $type, $maxfilenamelength);
    +
    +		return $list;
    +	}
    +}
    +
    +
    +/**
    + * Parent class for all holidays numbering modules
    + */
    +class ModelNumRefHolidays
    +{
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 *	Return if a module can be used or not
    +	 *
    +	 * 	@return		boolean     true if module can be used
    +	 */
    +	function isEnabled()
    +	{
    +		return true;
    +	}
    +
    +	/**
    +	 *	Return default description of numbering model
    +	 *
    +	 *	@return     string      text description
    +	 */
    +	function info()
    +	{
    +		global $langs;
    +		$langs->load("holidays");
    +		return $langs->trans("NoDescription");
    +	}
    +
    +	/**
    +	 *	Return numbering example
    +	 *
    +	 *	@return     string      Example
    +	 */
    +	function getExample()
    +	{
    +		global $langs;
    +		$langs->load("holidays");
    +		return $langs->trans("NoExample");
    +	}
    +
    +	/**
    +	 *	Test if existing numbers make problems with numbering
    +	 *
    +	 *	@return		boolean		false if conflict, true if ok
    +	 */
    +	function canBeActivated()
    +	{
    +		return true;
    +	}
    +
    +	/**
    +	 *	Return next value
    +	 *
    +	 *	@param	Societe		$objsoc     third party object
    +	 *	@param	Object		$contract	contract object
    +	 *	@return	string					Value
    +	 */
    +	function getNextValue($objsoc, $contract)
    +	{
    +		global $langs;
    +		return $langs->trans("NotAvailable");
    +	}
    +
    +	/**
    +	 *	Return numbering version module
    +	 *
    +	 *	@return     string      Value
    +	 */
    +	function getVersion()
    +	{
    +		global $langs;
    +		$langs->load("admin");
    +
    +		if ($this->version == 'development') return $langs->trans("VersionDevelopment");
    +		if ($this->version == 'experimental') return $langs->trans("VersionExperimental");
    +		if ($this->version == 'dolibarr') return DOL_VERSION;
    +		if ($this->version) return $this->version;
    +		return $langs->trans("NotAvailable");
    +	}
    +}
    diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
    index a6473eaeb8e..6b2e480db86 100644
    --- a/htdocs/core/modules/import/import_csv.modules.php
    +++ b/htdocs/core/modules/import/import_csv.modules.php
    @@ -33,30 +33,58 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/import/modules_import.php';
      */
     class ImportCsv extends ModeleImports
     {
    -    var $db;
    -    var $datatoimport;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $error='';
    -	var $errors=array();
    +    public $datatoimport;
     
    -    var $id;           // Id of driver
    -	var $label;        // Label of driver
    -	var $extension;    // Extension of files imported by driver
    -	var $version;      // Version of driver
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -	var $label_lib;    // Label of external lib used by driver
    -	var $version_lib;  // Version of external lib used by driver
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
    -	var $separator;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $file;      // Path of file
    -	var $handle;    // Handle fichier
    +	/**
    +     * @var string label
    +     */
    +    public $label;
     
    -	var $cacheconvert=array();      // Array to cache list of value found after a convertion
    -	var $cachefieldtable=array();   // Array to cache list of value found into fields@tables
    +	public $extension;    // Extension of files imported by driver
     
    -	var $nbinsert = 0; // # of insert done during the import
    -	var $nbupdate = 0; // # of update done during the import
    +	/**
    +     * Dolibarr version of driver
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $label_lib;    // Label of external lib used by driver
    +
    +	public $version_lib;  // Version of external lib used by driver
    +
    +	public $separator;
    +
    +	public $file;      // Path of file
    +
    +	public $handle;    // Handle fichier
    +
    +	public $cacheconvert=array();      // Array to cache list of value found after a convertion
    +
    +	public $cachefieldtable=array();   // Array to cache list of value found into fields@tables
    +
    +	public $nbinsert = 0; // # of insert done during the import
    +
    +	public $nbupdate = 0; // # of update done during the import
     
     
     	/**
    @@ -67,7 +95,7 @@ class ImportCsv extends ModeleImports
     	 */
     	function __construct($db,$datatoimport)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     		$this->db = $db;
     
     		$this->separator=(GETPOST('separator')?GETPOST('separator'):(empty($conf->global->IMPORT_CSV_SEPARATOR_TO_USE)?',':$conf->global->IMPORT_CSV_SEPARATOR_TO_USE));
    @@ -90,6 +118,7 @@ class ImportCsv extends ModeleImports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output header of an example file for this format
     	 *
    @@ -98,9 +127,11 @@ class ImportCsv extends ModeleImports
     	 */
     	function write_header_example($outputlangs)
     	{
    +        // phpcs:enable
     		return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output title line of an example file for this format
     	 *
    @@ -110,10 +141,12 @@ class ImportCsv extends ModeleImports
     	 */
     	function write_title_example($outputlangs,$headerlinefields)
     	{
    +        // phpcs:enable
     		$s=join($this->separator,array_map('cleansep',$headerlinefields));
     		return $s."\n";
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output record of an example file for this format
     	 *
    @@ -123,10 +156,12 @@ class ImportCsv extends ModeleImports
     	 */
     	function write_record_example($outputlangs,$contentlinevalues)
     	{
    +        // phpcs:enable
     		$s=join($this->separator,array_map('cleansep',$contentlinevalues));
     		return $s."\n";
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output footer of an example file for this format
     	 *
    @@ -135,11 +170,13 @@ class ImportCsv extends ModeleImports
     	 */
     	function write_footer_example($outputlangs)
     	{
    +        // phpcs:enable
     		return '';
     	}
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Open input file
     	 *
    @@ -148,6 +185,7 @@ class ImportCsv extends ModeleImports
     	 */
     	function import_open_file($file)
     	{
    +        // phpcs:enable
     		global $langs;
     		$ret=1;
     
    @@ -171,6 +209,7 @@ class ImportCsv extends ModeleImports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Return nb of records. File must be closed.
     	 *
    @@ -179,10 +218,12 @@ class ImportCsv extends ModeleImports
     	 */
     	function import_get_nb_of_lines($file)
     	{
    -	   return dol_count_nb_of_line($file);
    +        // phpcs:enable
    +       return dol_count_nb_of_line($file);
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Input header line from file
     	 *
    @@ -190,10 +231,12 @@ class ImportCsv extends ModeleImports
     	 */
     	function import_read_header()
     	{
    +        // phpcs:enable
     		return 0;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Return array of next record in input file.
     	 *
    @@ -201,6 +244,7 @@ class ImportCsv extends ModeleImports
     	 */
     	function import_read_record()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$arrayres=fgetcsv($this->handle,100000,$this->separator,$this->enclosure,$this->escape);
    @@ -249,6 +293,7 @@ class ImportCsv extends ModeleImports
     		return $newarrayres;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Close file handle
     	 *
    @@ -256,11 +301,13 @@ class ImportCsv extends ModeleImports
     	 */
     	function import_close_file()
     	{
    +        // phpcs:enable
     		fclose($this->handle);
     		return 0;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Insert a record into database
     	 *
    @@ -274,6 +321,7 @@ class ImportCsv extends ModeleImports
     	 */
     	function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$maxfields,$importid,$updatekeys)
     	{
    +        // phpcs:enable
     		global $langs,$conf,$user;
             global $thirdparty_static;    	// Specific to thirdparty import
     		global $tablewithentity_cache;	// Cache to avoid to call  desc at each rows on tables
    @@ -418,7 +466,6 @@ class ImportCsv extends ModeleImports
                                                 }
                                             }
                                         }
    -
                                     }
                                     elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='zeroifnull')
                                     {
    @@ -548,9 +595,13 @@ class ImportCsv extends ModeleImports
     						$listfields[] = $fieldname;
     
     						// Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert
    -						if (empty($newval) && $arrayrecord[($key-1)]['type'] < 0)		 $listvalues[] = ($newval=='0'?$newval:"null");
    -						elseif (empty($newval) && $arrayrecord[($key-1)]['type'] == 0)	 $listvalues[] = "''";
    -						else															 $listvalues[] = "'".$this->db->escape($newval)."'";
    +						if (empty($newval) && $arrayrecord[($key-1)]['type'] < 0) {
    +                            $listvalues[] = ($newval=='0'?$newval:"null");
    +                        } elseif (empty($newval) && $arrayrecord[($key-1)]['type'] == 0) {
    +                            $listvalues[] = "''";
    +                        } else {
    +                            $listvalues[] = "'".$this->db->escape($newval)."'";
    +                        }
     					}
     					$i++;
     				}
    @@ -581,6 +632,7 @@ class ImportCsv extends ModeleImports
     				//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';
     
     				// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
    +				// so we can try to make the insert or update now.
     				if (! $errorforthistable)
     				{
     					//print "$alias/$tablename/$listfields/$listvalues<br>";
    @@ -592,7 +644,7 @@ class ImportCsv extends ModeleImports
     						if (!empty($updatekeys)) {
     							// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
     
    -							if (empty($lastinsertid)) {
    +							if (empty($lastinsertid)) {	// No insert done yet for a parent table
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								$data = array_combine($listfields, $listvalues);
    @@ -628,10 +680,11 @@ class ImportCsv extends ModeleImports
     									$error++;
     								}
     							} else {
    -								// We have a last INSERT ID. Check if we have a row referencing this foreign key.
    -								// This is required when updating table with some extrafields. When inserting a record in parent table, we can make 
    -								// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record 
    -								// may already exists. So we rescan the extrafield table to be know if record exists or not for the rowid.
    +								// We have a last INSERT ID (got by previous pass), so we check if we have a row referencing this foreign key.
    +								// This is required when updating table with some extrafields. When inserting a record in parent table, we can make
    +								// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
    +								// may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
    +								// Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								if(empty($keyfield)) $keyfield = 'rowid';
    @@ -739,7 +792,6 @@ class ImportCsv extends ModeleImports
     
     		return 1;
     	}
    -
     }
     
     /**
    @@ -752,5 +804,3 @@ function cleansep($value)
     {
     	return str_replace(array(',',';'),'/',$value);
     };
    -
    -
    diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
    index 7f222f523ca..f8b6aa99a82 100644
    --- a/htdocs/core/modules/import/import_xlsx.modules.php
    +++ b/htdocs/core/modules/import/import_xlsx.modules.php
    @@ -33,31 +33,60 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/import/modules_import.php';
      */
     class ImportXlsx extends ModeleImports
     {
    -    var $db;
    -    var $datatoimport;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -	var $error='';
    -	var $errors=array();
    +    public $datatoimport;
     
    -    var $id;           // Id of driver
    -	var $label;        // Label of driver
    -	var $extension;    // Extension of files imported by driver
    -	var $version;      // Version of driver
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -	var $label_lib;    // Label of external lib used by driver
    -	var $version_lib;  // Version of external lib used by driver
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
    -	var $separator;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -    var $file;      // Path of file
    -	var $handle;    // Handle fichier
    +	/**
    +     * @var string label
    +     */
    +    public $label;
     
    -	var $cacheconvert=array();      // Array to cache list of value found after a convertion
    -	var $cachefieldtable=array();   // Array to cache list of value found into fields@tables
    +	public $extension;    // Extension of files imported by driver
     
    -	var $workbook; // temporary import file
    -	var $record; // current record
    -	var $headers;
    +	/**
    +     * Dolibarr version of driver
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	public $label_lib;    // Label of external lib used by driver
    +
    +	public $version_lib;  // Version of external lib used by driver
    +
    +	public $separator;
    +
    +    public $file;      // Path of file
    +
    +	public $handle;    // Handle fichier
    +
    +	public $cacheconvert=array();      // Array to cache list of value found after a convertion
    +
    +	public $cachefieldtable=array();   // Array to cache list of value found into fields@tables
    +
    +	public $workbook; // temporary import file
    +
    +	public $record; // current record
    +
    +	public $headers;
     
     
     	/**
    @@ -96,6 +125,7 @@ class ImportXlsx extends ModeleImports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output header of an example file for this format
     	 *
    @@ -104,29 +134,31 @@ class ImportXlsx extends ModeleImports
     	 */
     	function write_header_example($outputlangs)
     	{
    -	  global $user,$conf,$langs;
    -	  // create a temporary object, the final output will be generated in footer
    -          if (!empty($conf->global->MAIN_USE_FILECACHE_EXPORT_EXCEL_DIR)) {
    +        // phpcs:enable
    +        global $user,$conf,$langs;
    +        // create a temporary object, the final output will be generated in footer
    +        if (!empty($conf->global->MAIN_USE_FILECACHE_EXPORT_EXCEL_DIR)) {
                 $cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_discISAM;
                 $cacheSettings = array (
    -              'dir' => $conf->global->MAIN_USE_FILECACHE_EXPORT_EXCEL_DIR
    -          );
    -          PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
    +                'dir' => $conf->global->MAIN_USE_FILECACHE_EXPORT_EXCEL_DIR
    +            );
    +            PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);
             }
     
    -            $this->workbook = new PHPExcel();
    -            $this->workbook->getProperties()->setCreator($user->getFullName($outputlangs).' - Dolibarr '.DOL_VERSION);
    -            $this->workbook->getProperties()->setTitle($outputlangs->trans("Import").' - '.$file);
    -            $this->workbook->getProperties()->setSubject($outputlangs->trans("Import").' - '.$file);
    -            $this->workbook->getProperties()->setDescription($outputlangs->trans("Import").' - '.$file);
    +        $this->workbook = new PHPExcel();
    +        $this->workbook->getProperties()->setCreator($user->getFullName($outputlangs).' - Dolibarr '.DOL_VERSION);
    +        $this->workbook->getProperties()->setTitle($outputlangs->trans("Import").' - '.$file);
    +        $this->workbook->getProperties()->setSubject($outputlangs->trans("Import").' - '.$file);
    +        $this->workbook->getProperties()->setDescription($outputlangs->trans("Import").' - '.$file);
     
    -            $this->workbook->setActiveSheetIndex(0);
    -            $this->workbook->getActiveSheet()->setTitle($outputlangs->trans("Sheet"));
    -            $this->workbook->getActiveSheet()->getDefaultRowDimension()->setRowHeight(16);
    +        $this->workbook->setActiveSheetIndex(0);
    +        $this->workbook->getActiveSheet()->setTitle($outputlangs->trans("Sheet"));
    +        $this->workbook->getActiveSheet()->getDefaultRowDimension()->setRowHeight(16);
     
    -	    return '';
    -	}
    +        return '';
    +    }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output title line of an example file for this format
     	 *
    @@ -136,6 +168,7 @@ class ImportXlsx extends ModeleImports
     	 */
     	function write_title_example($outputlangs,$headerlinefields)
     	{
    +        // phpcs:enable
     		global $conf;
     		$this->workbook->getActiveSheet()->getStyle('1')->getFont()->setBold(true);
     		$this->workbook->getActiveSheet()->getStyle('1')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
    @@ -151,6 +184,7 @@ class ImportXlsx extends ModeleImports
     		return ''; // final output will be generated in footer
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output record of an example file for this format
     	 *
    @@ -160,6 +194,7 @@ class ImportXlsx extends ModeleImports
     	 */
     	function write_record_example($outputlangs,$contentlinevalues)
     	{
    +        // phpcs:enable
     		$col = 0;
     		$row = 2;
     		foreach($contentlinevalues as $cell) {
    @@ -170,6 +205,7 @@ class ImportXlsx extends ModeleImports
     		return ''; // final output will be generated in footer
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Output footer of an example file for this format
     	 *
    @@ -178,7 +214,8 @@ class ImportXlsx extends ModeleImports
     	 */
     	function write_footer_example($outputlangs)
     	{
    -		// return te file content as a string
    +        // phpcs:enable
    +		// return the file content as a string
     		$tempfile = tempnam(sys_get_temp_dir(), 'dol');
     		$objWriter = new PHPExcel_Writer_Excel2007($this->workbook);
     		$objWriter->save($tempfile);
    @@ -192,6 +229,7 @@ class ImportXlsx extends ModeleImports
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Open input file
     	 *
    @@ -200,6 +238,7 @@ class ImportXlsx extends ModeleImports
     	 */
     	function import_open_file($file)
     	{
    +        // phpcs:enable
     		global $langs;
     		$ret=1;
     
    @@ -214,6 +253,7 @@ class ImportXlsx extends ModeleImports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Return nb of records. File must be closed.
     	 *
    @@ -222,6 +262,7 @@ class ImportXlsx extends ModeleImports
     	 */
     	function import_get_nb_of_lines($file)
     	{
    +        // phpcs:enable
     		$reader = new PHPExcel_Reader_Excel2007();
     		$this->workbook = $reader->load($file);
     
    @@ -234,6 +275,7 @@ class ImportXlsx extends ModeleImports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Input header line from file
     	 *
    @@ -241,6 +283,7 @@ class ImportXlsx extends ModeleImports
     	 */
     	function import_read_header()
     	{
    +        // phpcs:enable
     		// This is not called by the import code !!!
     		$this->headers = array();
     		$colcount = PHPExcel_Cell::columnIndexFromString($this->workbook->getActiveSheet()->getHighestDataColumn());
    @@ -251,6 +294,7 @@ class ImportXlsx extends ModeleImports
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Return array of next record in input file.
     	 *
    @@ -258,6 +302,7 @@ class ImportXlsx extends ModeleImports
     	 */
     	function import_read_record()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
    @@ -274,6 +319,7 @@ class ImportXlsx extends ModeleImports
     		return $array;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Close file handle
     	 *
    @@ -281,11 +327,14 @@ class ImportXlsx extends ModeleImports
     	 */
     	function import_close_file()
     	{
    +        // phpcs:enable
     		$this->workbook->disconnectWorksheets();
     		unset($this->workbook);
     	}
     
     
    +    // What is this doing here ? it is common to all imports, is should be in the parent class
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Insert a record into database
     	 *
    @@ -297,9 +346,9 @@ class ImportXlsx extends ModeleImports
     	 * @param	array	$updatekeys						Array of keys to use to try to do an update first before insert. This field are defined into the module descriptor.
     	 * @return	int										<0 if KO, >0 if OK
     	 */
    -	// What is this doing here ? it is common to all imports, is should be in the parent class
     	function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$maxfields,$importid,$updatekeys)
     	{
    +        // phpcs:enable
     		global $langs,$conf,$user;
             global $thirdparty_static;    	// Specific to thirdparty import
     		global $tablewithentity_cache;	// Cache to avoid to call  desc at each rows on tables
    @@ -444,7 +493,6 @@ class ImportXlsx extends ModeleImports
                                                 }
                                             }
                                         }
    -
                                     }
                                     elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='zeroifnull')
                                     {
    @@ -607,6 +655,7 @@ class ImportXlsx extends ModeleImports
     				//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';
     
     				// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
    +				// so we can try to make the insert or update now.
     				if (! $errorforthistable)
     				{
     					//print "$alias/$tablename/$listfields/$listvalues<br>";
    @@ -616,7 +665,8 @@ class ImportXlsx extends ModeleImports
     						$insertdone = false;
     						if (!empty($updatekeys)) {
     							// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
    -							if (empty($lastinsertid)) {
    +
    +							if (empty($lastinsertid)) {	// No insert done yet for a parent table
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								$data = array_combine($listfields, $listvalues);
    @@ -653,9 +703,10 @@ class ImportXlsx extends ModeleImports
     								}
     							} else {
     								// We have a last INSERT ID. Check if we have a row referencing this foreign key.
    -								// This is required when updating table with some extrafields. When inserting a record in parent table, we can make 
    -								// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record 
    -								// may already exists. So we rescan the extrafield table to be know if record exists or not for the rowid.
    +								// This is required when updating table with some extrafields. When inserting a record in parent table, we can make
    +								// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
    +								// may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
    +								// Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								if(empty($keyfield)) $keyfield = 'rowid';
    @@ -763,5 +814,4 @@ class ImportXlsx extends ModeleImports
     
     		return 1;
     	}
    -
     }
    diff --git a/htdocs/core/modules/import/modules_import.php b/htdocs/core/modules/import/modules_import.php
    index 548bb128193..214c04ad857 100644
    --- a/htdocs/core/modules/import/modules_import.php
    +++ b/htdocs/core/modules/import/modules_import.php
    @@ -30,25 +30,49 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
      */
     class ModeleImports
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
    +
         public $datatoimport;
     
    -    public $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    /**
    +	 * @var int id of driver
    +	 */
    +	public $id;
    +
    +    /**
    +     * @var string label
    +     */
    +    public $label;
     
    -    public $id;           // Id of driver
    -	public $label;        // Label of driver
     	public $extension;    // Extension of files imported by driver
    -	public $version;      // Version of driver
    +
    +	/**
    +     * Dolibarr version of driver
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     	public $label_lib;    // Label of external lib used by driver
    +
     	public $version_lib;  // Version of external lib used by driver
     
     	// Array of all drivers
     	public $driverlabel=array();
    +
     	public $driverdesc=array();
    +
     	public $driverversion=array();
     
     	public $liblabel=array();
    +
     	public $libversion=array();
     
     
    @@ -131,15 +155,17 @@ class ModeleImports
     	}
     
     
    -	/**
    -	 *  Charge en memoire et renvoie la liste des modeles actifs
    -	 *
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Charge en memoire et renvoie la liste des modeles actifs
    +     *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
     	 */
     	function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		dol_syslog(get_class($this)."::liste_modeles");
     
     		$dir=DOL_DOCUMENT_ROOT."/core/modules/import/";
    @@ -246,6 +272,4 @@ class ModeleImports
     	{
     		return $this->libversion[$key];
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
    index 6b0bb759a19..4793ebe7b27 100644
    --- a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
    +++ b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php
    @@ -35,27 +35,82 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     
     /**
    - *	Classe permettant de generer les bons de livraison au modele Typho
    + *	Class to build Delivery Order documents with typhon model
      */
     class pdf_typhon extends ModelePDFDeliveryOrder
     {
    -    var $db;
    -    var $name;
    -    var $description;
    -    var $type;
    +	/**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -    var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -    var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -    var $page_largeur;
    -    var $page_hauteur;
    -    var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
     
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     	/**
     	 *	Constructor
    @@ -65,7 +120,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills", "sendings", "companies"));
     
    @@ -119,7 +174,8 @@ class pdf_typhon extends ModelePDFDeliveryOrder
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -129,16 +185,17 @@ class pdf_typhon extends ModelePDFDeliveryOrder
          *  @param		int			$hidedesc			Do not show desc
          *  @param		int			$hideref			Do not show ref
          *  @return     int             			1=OK, 0=KO
    -	 */
    +     */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load translation files required by the page
     		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "sendings", "deliveries"));
     
     		if ($conf->expedition->dir_output)
    @@ -574,6 +631,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -585,6 +643,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -896,6 +955,4 @@ class pdf_typhon extends ModelePDFDeliveryOrder
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'DELIVERY_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/livraison/mod_livraison_jade.php b/htdocs/core/modules/livraison/mod_livraison_jade.php
    index 228b73aad8b..1fd598d02a7 100644
    --- a/htdocs/core/modules/livraison/mod_livraison_jade.php
    +++ b/htdocs/core/modules/livraison/mod_livraison_jade.php
    @@ -34,11 +34,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/livraison/modules_livraison.php';
     
     class mod_livraison_jade extends ModeleNumRefDeliveryOrder
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = "Jade";
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
     
    -    var $prefix='BL';
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Jade';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Jade';
    +
    +    public $prefix='BL';
     
     
     	/**
    @@ -142,16 +161,17 @@ class mod_livraison_jade extends ModeleNumRefDeliveryOrder
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free ref
     	 *
    -     *  @param	Societe		$objsoc      	Object thirdparty
    +     *  @param  Societe		$objsoc      	Object thirdparty
          *  @param  Object		$object			Object livraison
    -     *  @return string      				Texte descripif
    +     *  @return string      				Texte descriptif
          */
         function livraison_get_num($objsoc=0,$object='')
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$object);
         }
    -
     }
    diff --git a/htdocs/core/modules/livraison/mod_livraison_saphir.php b/htdocs/core/modules/livraison/mod_livraison_saphir.php
    index 1192656bf8d..cbe105ef75c 100644
    --- a/htdocs/core/modules/livraison/mod_livraison_saphir.php
    +++ b/htdocs/core/modules/livraison/mod_livraison_saphir.php
    @@ -31,9 +31,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/livraison/modules_livraison.php';
      */
     class mod_livraison_saphir extends ModeleNumRefDeliveryOrder
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Saphir';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Saphir';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Saphir';
     
     
         /**
    @@ -43,7 +62,7 @@ class mod_livraison_saphir extends ModeleNumRefDeliveryOrder
          */
     	function info()
     	{
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -139,17 +158,17 @@ class mod_livraison_saphir extends ModeleNumRefDeliveryOrder
         }
     
     
    -	/**
    -	 *  Return next free ref
    -	 *
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Return next free ref
    +     *
          *  @param	Societe		$objsoc      	Object thirdparty
          *  @param  Object		$object			Objet livraison
          *  @return string      				Texte descripif
          */
         function livraison_get_num($objsoc=0,$object='')
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$object);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/livraison/modules_livraison.php b/htdocs/core/modules/livraison/modules_livraison.php
    index a433f42930d..f9f7a5380f3 100644
    --- a/htdocs/core/modules/livraison/modules_livraison.php
    +++ b/htdocs/core/modules/livraison/modules_livraison.php
    @@ -36,8 +36,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFDeliveryOrder extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
    @@ -47,6 +51,7 @@ abstract class ModelePDFDeliveryOrder extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='delivery';
    @@ -67,7 +72,10 @@ abstract class ModelePDFDeliveryOrder extends CommonDocGenerator
      */
     abstract class ModeleNumRefDeliveryOrder
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 * Return if a module can be used or not
    diff --git a/htdocs/core/modules/mailings/advthirdparties.modules.php b/htdocs/core/modules/mailings/advthirdparties.modules.php
    index 78aab1a5bd7..4d149e0e5ef 100644
    --- a/htdocs/core/modules/mailings/advthirdparties.modules.php
    +++ b/htdocs/core/modules/mailings/advthirdparties.modules.php
    @@ -32,7 +32,11 @@ class mailing_advthirdparties extends MailingTargets
     
     	var $require_module=array("none");	// This module should not be displayed as Selector in mailling
     	var $picto='company';
    -	var $db;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
     	/**
    @@ -42,12 +46,11 @@ class mailing_advthirdparties extends MailingTargets
     	 */
     	function __construct($db)
     	{
    -		global $conf;
    -
     		$this->db=$db;
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    This is the main function that returns the array of emails
     	 *
    @@ -59,6 +62,7 @@ class mailing_advthirdparties extends MailingTargets
     	 */
     	function add_to_target_spec($mailing_id,$socid,$type_of_target, $contactid)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		dol_syslog(get_class($this)."::add_to_target socid=".var_export($socid,true).' contactid='.var_export($contactid,true));
    @@ -273,7 +277,6 @@ class mailing_advthirdparties extends MailingTargets
     
     		$s.='</select>';
     		return $s;
    -
     	}
     
     
    @@ -296,5 +299,4 @@ class mailing_advthirdparties extends MailingTargets
     			return $contactstatic->getNomUrl(0, '', 0, '', -1, 1);
     		}
     	}
    -
     }
    diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php
    index 90d81dca4a5..8efefdbd079 100644
    --- a/htdocs/core/modules/mailings/contacts1.modules.php
    +++ b/htdocs/core/modules/mailings/contacts1.modules.php
    @@ -39,7 +39,10 @@ class mailing_contacts1 extends MailingTargets
     	var $require_admin=0;                               // Module mailing actif pour user admin ou non
     	var $picto='contact';
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
     	/**
    @@ -113,10 +116,9 @@ class mailing_contacts1 extends MailingTargets
     	function formFilter()
     	{
     		global $langs;
    -		$langs->load("companies");
    -		$langs->load("commercial");
    -		$langs->load("suppliers");
    -		$langs->load("categories");
    +
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("commercial","companies","suppliers","categories"));
     
     		$s='';
     
    @@ -324,15 +326,17 @@ class mailing_contacts1 extends MailingTargets
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Ajoute destinataires dans table des cibles
     	 *
    -	 *  @param	int		$mailing_id    	Id of emailing
    +	 *  @param  int		$mailing_id    	Id of emailing
     	 *  @param  array	$filtersarray   Optional filter data (deprecated)
     	 *  @return int           			<0 si erreur, nb ajout si ok
     	 */
     	function add_to_target($mailing_id,$filtersarray=array())
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$filter = GETPOST('filter','alpha');
    @@ -446,6 +450,4 @@ class mailing_contacts1 extends MailingTargets
     
     		return parent::add_to_target($mailing_id, $cibles);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/example.modules.php b/htdocs/core/modules/mailings/example.modules.php
    index 548510f81a0..0af52dc5bd2 100644
    --- a/htdocs/core/modules/mailings/example.modules.php
    +++ b/htdocs/core/modules/mailings/example.modules.php
    @@ -32,12 +32,16 @@ class mailing_example extends MailingTargets
         var $desc='Put here a description';
     	// CHANGE THIS: Set to 1 if selector is available for admin users only
         var $require_admin=0;
    -    // CHANGE THIS: Add a tooltip language key to add a tooltip help icon after the email target selector 
    +    // CHANGE THIS: Add a tooltip language key to add a tooltip help icon after the email target selector
         var $tooltip='MyTooltipLangKey';
    -    
    +
         var $require_module=array();
         var $picto='';
    -    var $db;
    +
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
         // CHANGE THIS: Constructor name must be called mailing_xxx with xxx=name of your selector
    @@ -52,6 +56,7 @@ class mailing_example extends MailingTargets
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  This is the main function that returns the array of emails
          *
    @@ -61,6 +66,7 @@ class mailing_example extends MailingTargets
          */
         function add_to_target($mailing_id,$filtersarray=array())
         {
    +        // phpcs:enable
             $target = array();
     
     	    // CHANGE THIS
    @@ -107,7 +113,7 @@ class mailing_example extends MailingTargets
          */
         function getNbOfRecipients($sql='')
         {
    -	    // CHANGE THIS: Optionnal
    +        // CHANGE THIS: Optionnal
     
             // Example: return parent::getNbOfRecipients("SELECT count(*) as nb from dolibarr_table");
             // Example: return 500;
    @@ -122,7 +128,7 @@ class mailing_example extends MailingTargets
          */
         function formFilter()
         {
    -	    // CHANGE THIS: Optionnal
    +        // CHANGE THIS: Optionnal
     
             $s='';
             return $s;
    @@ -138,10 +144,8 @@ class mailing_example extends MailingTargets
          */
         function url($id)
         {
    -	    // CHANGE THIS: Optionnal
    +        // CHANGE THIS: Optionnal
     
             return '';
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php
    index f71b6b925f0..9cf0f56f7e2 100644
    --- a/htdocs/core/modules/mailings/fraise.modules.php
    +++ b/htdocs/core/modules/mailings/fraise.modules.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2005      Laurent Destailleur <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2009 Regis Houssin       <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2005       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -41,7 +42,10 @@ class mailing_fraise extends MailingTargets
         var $require_module=array('adherent');
         var $picto='user';
     
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
         /**
          *    Constructor
    @@ -50,7 +54,7 @@ class mailing_fraise extends MailingTargets
          */
         function __construct($db)
         {
    -        $this->db=$db;
    +        $this->db = $db;
         }
     
     
    @@ -106,9 +110,9 @@ class mailing_fraise extends MailingTargets
         function formFilter()
         {
             global $conf, $langs;
    -        $langs->load("members");
    -		$langs->load("categories");
    -		$langs->load("companies");
    +
    +        // Load translation files required by the page
    +        $langs->loadLangs(array("members","companies","categories"));
     
             $form=new Form($this->db);
     
    @@ -196,9 +200,9 @@ class mailing_fraise extends MailingTargets
     
             $s.='<br>';
             $s.=$langs->trans("DateEndSubscription").': &nbsp;';
    -        $s.=$langs->trans("After").' > '.$form->select_date(-1,'subscriptionafter',0,0,1,'fraise',1,0,1,0);
    +        $s.=$langs->trans("After").' > '.$form->selectDate(-1,'subscriptionafter',0,0,1,'fraise',1,0,0);
             $s.=' &nbsp; ';
    -        $s.=$langs->trans("Before").' < '.$form->select_date(-1,'subscriptionbefore',0,0,1,'fraise',1,0,1,0);
    +        $s.=$langs->trans("Before").' < '.$form->selectDate(-1,'subscriptionbefore',0,0,1,'fraise',1,0,0);
     
             return $s;
         }
    @@ -216,6 +220,7 @@ class mailing_fraise extends MailingTargets
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Ajoute destinataires dans table des cibles
          *
    @@ -225,14 +230,16 @@ class mailing_fraise extends MailingTargets
          */
         function add_to_target($mailing_id,$filtersarray=array())
         {
    +        // phpcs:enable
     	    // Deprecation warning
     	    if ($filtersarray) {
     		    dol_syslog(__METHOD__ . ": filtersarray parameter is deprecated", LOG_WARNING);
     	    }
     
         	global $langs,$_POST;
    -		$langs->load("members");
    -        $langs->load("companies");
    +
    +    	// Load translation files required by the page
    +        $langs->loadLangs(array("members","companies"));
     
             $cibles = array();
             $now=dol_now();
    @@ -265,8 +272,8 @@ class mailing_fraise extends MailingTargets
             // Filter on type
             if ($_POST['filter_type']) $sql.= " AND ta.rowid='".$_POST['filter_type']."'";
             // Filter on category
    -		if ($_POST['filter_category']) $sql.= " AND c.rowid='".$_POST['filter_category']."'";
    -		$sql.= " ORDER BY a.email";
    +        if ($_POST['filter_category']) $sql.= " AND c.rowid='".$_POST['filter_category']."'";
    +        $sql.= " ORDER BY a.email";
             //print $sql;
     
             // Add targets into table
    @@ -316,5 +323,4 @@ class mailing_fraise extends MailingTargets
     
             return parent::add_to_target($mailing_id, $cibles);
         }
    -
     }
    diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php
    index 1a97f3502b7..f7136d4aa63 100644
    --- a/htdocs/core/modules/mailings/modules_mailings.php
    +++ b/htdocs/core/modules/mailings/modules_mailings.php
    @@ -29,12 +29,20 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
     /**
      *		Parent class of emailing target selectors modules
      */
    -class MailingTargets    // This can't be abstract as it is used for some method
    +class MailingTargets // This can't be abstract as it is used for some method
     {
    -    var $db;
    -    var $error;
    -    var $tooltip='';
    -    
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    public $tooltip='';
    +
     
         /**
     	 *	Constructor
    @@ -54,7 +62,7 @@ class MailingTargets    // This can't be abstract as it is used for some method
         function getDesc()
         {
             global $langs, $form;
    -        
    +
             $langs->load("mails");
             $transstring="MailingModuleDesc".$this->name;
             $s='';
    @@ -109,6 +117,7 @@ class MailingTargets    // This can't be abstract as it is used for some method
             return '';
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Met a jour nombre de destinataires
          *
    @@ -117,6 +126,7 @@ class MailingTargets    // This can't be abstract as it is used for some method
          */
         function update_nb($mailing_id)
         {
    +        // phpcs:enable
             // Mise a jour nombre de destinataire dans table des mailings
             $sql = "SELECT COUNT(*) nb FROM ".MAIN_DB_PREFIX."mailing_cibles";
             $sql .= " WHERE fk_mailing = ".$mailing_id;
    @@ -141,6 +151,7 @@ class MailingTargets    // This can't be abstract as it is used for some method
             return $nb;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Ajoute destinataires dans table des cibles
          *
    @@ -150,6 +161,7 @@ class MailingTargets    // This can't be abstract as it is used for some method
          */
         function add_to_target($mailing_id, $cibles)
         {
    +        // phpcs:enable
         	global $conf;
     
         	$this->db->begin();
    @@ -224,14 +236,16 @@ class MailingTargets    // This can't be abstract as it is used for some method
             return $j;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Supprime tous les destinataires de la table des cibles
          *
    -     *	@param	int		$mailing_id        Id of emailing
    +     *	@param  int		$mailing_id        Id of emailing
          *	@return	void
          */
         function clear_target($mailing_id)
         {
    +        // phpcs:enable
             $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
             $sql .= " WHERE fk_mailing = ".$mailing_id;
     
    @@ -242,6 +256,4 @@ class MailingTargets    // This can't be abstract as it is used for some method
     
             $this->update_nb($mailing_id);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/pomme.modules.php b/htdocs/core/modules/mailings/pomme.modules.php
    index 5824f456365..11ff4812d67 100644
    --- a/htdocs/core/modules/mailings/pomme.modules.php
    +++ b/htdocs/core/modules/mailings/pomme.modules.php
    @@ -37,7 +37,10 @@ class mailing_pomme extends MailingTargets
     	var $require_admin=1;                           // Module mailing actif pour user admin ou non
     	var $picto='user';
     
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
     	/**
    @@ -118,7 +121,7 @@ class mailing_pomme extends MailingTargets
     		$s.='<option value="1">'.$langs->trans("Enabled").'</option>';
     		$s.='<option value="0">'.$langs->trans("Disabled").'</option>';
     		$s.='</select>';
    -		
    +
     		$s.=' ';
     		$s.=$langs->trans("Employee").': ';
     		$s.='<select name="filteremployee" class="flat">';
    @@ -126,7 +129,7 @@ class mailing_pomme extends MailingTargets
     		$s.='<option value="1">'.$langs->trans("Yes").'</option>';
     		$s.='<option value="0">'.$langs->trans("No").'</option>';
     		$s.='</select>';
    -		
    +
     		return $s;
     	}
     
    @@ -143,6 +146,7 @@ class mailing_pomme extends MailingTargets
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Ajoute destinataires dans table des cibles
     	 *
    @@ -150,13 +154,14 @@ class mailing_pomme extends MailingTargets
     	 *  @param  array	$filtersarray   Requete sql de selection des destinataires
     	 *  @return int           			< 0 si erreur, nb ajout si ok
     	 */
    -	function add_to_target($mailing_id,$filtersarray=array())
    +	function add_to_target($mailing_id, $filtersarray=array())
     	{
    +        // phpcs:enable
     		// Deprecation warning
     	    if ($filtersarray) {
     		    dol_syslog(__METHOD__ . ": filtersarray parameter is deprecated", LOG_WARNING);
     	    }
    -	    
    +
     	    global $conf, $langs;
     		$langs->load("companies");
     
    @@ -169,10 +174,10 @@ class mailing_pomme extends MailingTargets
     		$sql.= " WHERE u.email <> ''"; // u.email IS NOT NULL est implicite dans ce test
     		$sql.= " AND u.entity IN (0,".$conf->entity.")";
     		$sql.= " AND u.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")";
    -		if (isset($_POST["filter"]) && $_POST["filter"] == '1') $sql.= " AND u.statut=1"; 
    -		if (isset($_POST["filter"]) && $_POST["filter"] == '0') $sql.= " AND u.statut=0"; 
    -		if (isset($_POST["filteremployee"]) && $_POST["filteremployee"] == '1') $sql.= " AND u.employee=1"; 
    -		if (isset($_POST["filteremployee"]) && $_POST["filteremployee"] == '0') $sql.= " AND u.employee=0"; 
    +		if (isset($_POST["filter"]) && $_POST["filter"] == '1') $sql.= " AND u.statut=1";
    +		if (isset($_POST["filter"]) && $_POST["filter"] == '0') $sql.= " AND u.statut=0";
    +		if (isset($_POST["filteremployee"]) && $_POST["filteremployee"] == '1') $sql.= " AND u.employee=1";
    +		if (isset($_POST["filteremployee"]) && $_POST["filteremployee"] == '0') $sql.= " AND u.employee=0";
     		$sql.= " ORDER BY u.email";
     
     		// Stocke destinataires dans cibles
    @@ -220,6 +225,4 @@ class mailing_pomme extends MailingTargets
     
     		return parent::add_to_target($mailing_id, $cibles);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/thirdparties.modules.php b/htdocs/core/modules/mailings/thirdparties.modules.php
    index 57a69475000..ad19264620a 100644
    --- a/htdocs/core/modules/mailings/thirdparties.modules.php
    +++ b/htdocs/core/modules/mailings/thirdparties.modules.php
    @@ -31,7 +31,11 @@ class mailing_thirdparties extends MailingTargets
     
     	var $require_module=array("societe");	// This module allows to select by categories must be also enabled if category module is not activated
     	var $picto='company';
    -	var $db;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
     	/**
    @@ -48,6 +52,7 @@ class mailing_thirdparties extends MailingTargets
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    This is the main function that returns the array of emails
     	 *
    @@ -55,8 +60,9 @@ class mailing_thirdparties extends MailingTargets
     	 *    @param	array	$filtersarray   If you used the formFilter function. Empty otherwise.
     	 *    @return   int 					<0 if error, number of emails added if ok
     	 */
    -	function add_to_target($mailing_id,$filtersarray=array())
    +	function add_to_target($mailing_id, $filtersarray=array())
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$cibles = array();
    @@ -91,53 +97,53 @@ class mailing_thirdparties extends MailingTargets
     		    $sql.= " AND c.rowid='".$this->db->escape($_POST['filter'])."'";
     		}
     
    -                $addDescription= "";
    -                if (isset($_POST["filter_client"]) && $_POST["filter_client"] <> '-1')
    -                {
    -                    $sql.= " AND s.client=" . $_POST["filter_client"];
    -                    $addDescription= $langs->trans('ProspectCustomer')."=";
    -                    if ($_POST["filter_client"] == 0)
    -                    {
    -                        $addDescription.= $langs->trans('NorProspectNorCustomer');
    -                    }
    -                    else if ($_POST["filter_client"] == 1)
    -                    {
    -                        $addDescription.= $langs->trans('Customer');
    -                    }
    -                    else if ($_POST["filter_client"] == 2)
    -                    {
    -                        $addDescription.= $langs->trans('Prospect');
    -                    }
    -                    else if ($_POST["filter_client"] == 3)
    -                    {
    -                        $addDescription.= $langs->trans('ProspectCustomer');
    -                    }
    -                    else
    -                    {
    -                        $addDescription.= "Unknown status ".$_POST["filter_client"];
    -                    }
    -                }
    -                if (isset($_POST["filter_status"]))
    -                {
    -                    if (strlen($addDescription) > 0)
    -                    {
    -                        $addDescription.= ";";
    -                    }
    -                    $addDescription.= $langs->trans("Status")."=";
    -                    if ($_POST["filter_status"] == '1')
    -                    {
    -                        $sql.= " AND s.status=1";
    -                        $addDescription.= $langs->trans("Enabled");
    -                    }
    -                    else
    -                    {
    -                        $sql.= " AND s.status=0";
    -                        $addDescription.= $langs->trans("Disabled");
    -                    }
    -                }
    -		$sql.= " ORDER BY email";
    +        $addDescription= "";
    +        if (isset($_POST["filter_client"]) && $_POST["filter_client"] <> '-1')
    +        {
    +            $sql.= " AND s.client=" . $_POST["filter_client"];
    +            $addDescription= $langs->trans('ProspectCustomer')."=";
    +            if ($_POST["filter_client"] == 0)
    +            {
    +                $addDescription.= $langs->trans('NorProspectNorCustomer');
    +            }
    +            elseif ($_POST["filter_client"] == 1)
    +            {
    +                $addDescription.= $langs->trans('Customer');
    +            }
    +            elseif ($_POST["filter_client"] == 2)
    +            {
    +                $addDescription.= $langs->trans('Prospect');
    +            }
    +            elseif ($_POST["filter_client"] == 3)
    +            {
    +                $addDescription.= $langs->trans('ProspectCustomer');
    +            }
    +            else
    +            {
    +                $addDescription.= "Unknown status ".$_POST["filter_client"];
    +            }
    +        }
    +        if (isset($_POST["filter_status"]))
    +        {
    +            if (strlen($addDescription) > 0)
    +            {
    +                $addDescription.= ";";
    +            }
    +            $addDescription.= $langs->trans("Status")."=";
    +            if ($_POST["filter_status"] == '1')
    +            {
    +                $sql.= " AND s.status=1";
    +                $addDescription.= $langs->trans("Enabled");
    +            }
    +            else
    +            {
    +                $sql.= " AND s.status=0";
    +                $addDescription.= $langs->trans("Disabled");
    +            }
    +        }
    +        $sql.= " ORDER BY email";
     
    -		// Stock recipients emails into targets table
    +        // Stock recipients emails into targets table
     		$result=$this->db->query($sql);
     		if ($result)
     		{
    @@ -305,11 +311,10 @@ class mailing_thirdparties extends MailingTargets
                     $s.='<option value="0">'.$langs->trans("Disabled").'</option>';
     		$s.='</select>';
     		return $s;
    -
     	}
     
     
    -	/**
    +    /**
     	 *  Can include an URL link on each record provided by selector shown on target page.
     	 *
          *  @param	int		$id		ID
    @@ -319,6 +324,4 @@ class mailing_thirdparties extends MailingTargets
     	{
     		return '<a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.$id.'">'.img_object('',"company").'</a>';
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php
    index 08473f3cb6d..91bd5127c1f 100644
    --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php
    +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php
    @@ -29,7 +29,12 @@ class mailing_thirdparties_services_expired extends MailingTargets
     
         var $require_module=array('contrat');
         var $picto='company';
    -    var $db;
    +
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
         var $arrayofproducts=array();
     
     
    @@ -64,7 +69,6 @@ class mailing_thirdparties_services_expired extends MailingTargets
                     $i++;
                     $this->arrayofproducts[$i]=$obj->ref;
                 }
    -
             }
             else
             {
    @@ -73,6 +77,7 @@ class mailing_thirdparties_services_expired extends MailingTargets
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  This is the main function that returns the array of emails
          *
    @@ -82,6 +87,7 @@ class mailing_thirdparties_services_expired extends MailingTargets
          */
         function add_to_target($mailing_id,$filtersarray=array())
         {
    +        // phpcs:enable
             $target = array();
     
             // ----- Your code start here -----
    @@ -236,6 +242,4 @@ class mailing_thirdparties_services_expired extends MailingTargets
         {
             return '<a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.$id.'">'.img_object('',"company").'</a>';
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/xinputfile.modules.php b/htdocs/core/modules/mailings/xinputfile.modules.php
    index 152322c2899..7de27a0c753 100644
    --- a/htdocs/core/modules/mailings/xinputfile.modules.php
    +++ b/htdocs/core/modules/mailings/xinputfile.modules.php
    @@ -110,6 +110,7 @@ class mailing_xinputfile extends MailingTargets
     		return $s;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Ajoute destinataires dans table des cibles
     	 *
    @@ -119,6 +120,7 @@ class mailing_xinputfile extends MailingTargets
     	 */
     	function add_to_target($mailing_id,$filtersarray=array())
     	{
    +        // phpcs:enable
     		global $conf,$langs,$_FILES;
     
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -220,6 +222,4 @@ class mailing_xinputfile extends MailingTargets
     
     		return parent::add_to_target($mailing_id, $cibles);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/mailings/xinputuser.modules.php b/htdocs/core/modules/mailings/xinputuser.modules.php
    index 794de3d9294..2364eeb08ef 100644
    --- a/htdocs/core/modules/mailings/xinputuser.modules.php
    +++ b/htdocs/core/modules/mailings/xinputuser.modules.php
    @@ -37,7 +37,7 @@ class mailing_xinputuser extends MailingTargets
     	var $require_admin=0;                    // Module mailing actif pour user admin ou non
     	var $picto='generic';
     	var $tooltip='UseFormatInputEmailToTarget';
    -	
    +
     
     	/**
     	 *	Constructor
    @@ -108,6 +108,7 @@ class mailing_xinputuser extends MailingTargets
     		return $s;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Ajoute destinataires dans table des cibles
     	 *
    @@ -117,6 +118,7 @@ class mailing_xinputuser extends MailingTargets
     	 */
     	function add_to_target($mailing_id,$filtersarray=array())
     	{
    +        // phpcs:enable
     		global $conf,$langs,$_FILES;
     
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -153,12 +155,9 @@ class mailing_xinputuser extends MailingTargets
     		}
     		else
     		{
    -		   	$langs->load("errors");
    -		   	$this->error = $langs->trans("ErrorBadEmail",$email);
    +            $langs->load("errors");
    +            $this->error = $langs->trans("ErrorBadEmail",$email);
     			return -1;
     		}
    -
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/member/doc/pdf_standard.class.php b/htdocs/core/modules/member/doc/pdf_standard.class.php
    index 4d08be83a43..524d1446427 100644
    --- a/htdocs/core/modules/member/doc/pdf_standard.class.php
    +++ b/htdocs/core/modules/member/doc/pdf_standard.class.php
    @@ -42,10 +42,12 @@ class pdf_standard extends CommonStickerGenerator
     	 * @param	array		$param			Associative array containing label content and optional parameters
     	 * @return	void
     	 */
    -	function addSticker(&$pdf,$outputlangs,$param) {
    +    function addSticker(&$pdf,$outputlangs,$param)
    +    {
     		// use this method in future refactoring
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0)
     	 * - __LOGO__ is replace with company logo
    @@ -63,6 +65,7 @@ class pdf_standard extends CommonStickerGenerator
     	 */
     	function Add_PDF_card(&$pdf,$textleft,$header,$footer,$outputlangs,$textright='',$idmember=0,$photo='')
     	{
    +        // phpcs:enable
     		global $db,$mysoc,$conf,$langs;
     		global $forceimgscalewidth,$forceimgscaleheight;
     
    @@ -234,6 +237,7 @@ class pdf_standard extends CommonStickerGenerator
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build PDF on disk, then output on HTTP stream.
     	 *
    @@ -246,6 +250,7 @@ class pdf_standard extends CommonStickerGenerator
     	 */
     	function write_file($object, $outputlangs, $srctemplatepath, $mode='member', $nooutput=0)
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$mysoc,$_Avery_Labels;
     
     		$this->code=$srctemplatepath;
    @@ -324,11 +329,8 @@ class pdf_standard extends CommonStickerGenerator
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("admin");
    -		$outputlangs->load("members");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "admin", "members"));
     
     		if (empty($mode) || $mode == 'member')
     		{
    @@ -443,5 +445,4 @@ class pdf_standard extends CommonStickerGenerator
     
     		return 1;
     	}
    -
     }
    diff --git a/htdocs/core/modules/member/modules_cards.php b/htdocs/core/modules/member/modules_cards.php
    index f7ef8b94590..c931abce4ed 100644
    --- a/htdocs/core/modules/member/modules_cards.php
    +++ b/htdocs/core/modules/member/modules_cards.php
    @@ -34,9 +34,13 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
      */
     class ModelePDFCards
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of active generation modules
     	 *
    @@ -46,6 +50,7 @@ class ModelePDFCards
     	 */
     	function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='member';
    @@ -59,6 +64,7 @@ class ModelePDFCards
     }
     
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *	Cree un fichier de cartes de visites en fonction du modele de ADHERENT_CARDS_ADDON_PDF
      *
    @@ -72,20 +78,21 @@ class ModelePDFCards
      */
     function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $outputdir='', $template='standard')
     {
    +    // phpcs:enable
     	global $conf,$langs;
     	$langs->load("members");
     
     	$error=0;
    -	
    +
     	// Increase limit for PDF build
     	$err=error_reporting();
     	error_reporting(0);
     	@set_time_limit(120);
     	error_reporting($err);
    -	
    +
     	$code='';
     	$srctemplatepath='';
    -	
    +
     	// Positionne le modele sur le nom du modele a utiliser
     	if (! dol_strlen($modele))
     	{
    @@ -108,7 +115,7 @@ function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $o
     		$srctemplatepath=$tmp[1];
     	}
     	else $srctemplatepath=$code;
    -	
    +
     	// Search template files
     	$file=''; $classname=''; $filefound=0;
     	$dirmodels=array('/');
    @@ -118,7 +125,7 @@ function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $o
     		foreach(array('doc','pdf') as $prefix)
     		{
     			$file = $prefix."_".$template.".class.php";
    -			
    +
     			// On verifie l'emplacement du modele
     			$file=dol_buildpath($reldir."core/modules/member/doc/".$file,0);
     			if (file_exists($file))
    @@ -130,8 +137,8 @@ function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $o
     		}
     		if ($filefound) break;
     	}
    -	
    -	
    +
    +
     	// Charge le modele
     	if ($filefound)
     	{
    @@ -160,7 +167,4 @@ function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $o
     		dol_print_error('',$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file));
     		return -1;
     	}
    -
    -
     }
    -
    diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php
    index 42cd67b9dab..20b9bf54edd 100644
    --- a/htdocs/core/modules/modAccounting.class.php
    +++ b/htdocs/core/modules/modAccounting.class.php
    @@ -45,7 +45,7 @@ class modAccounting extends DolibarrModules
     		$this->numero = 50400;
     
     		$this->family = "financial";
    -		$this->module_position = 610;
    +		$this->module_position = '61';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i', '', get_class($this));
     		$this->description = "Advanced accounting management";
    @@ -66,7 +66,7 @@ class modAccounting extends DolibarrModules
     		$this->depends = array("modFacture","modBanque","modTax"); // List of modules id that must be enabled if this module is enabled
     		$this->requiredby = array(); // List of modules id to disable if this one is disabled
     		$this->conflictwith = array("modComptabilite"); // List of modules are in conflict with this module
    -		$this->phpmin = array(5, 3); // Minimum version of PHP required by module
    +		$this->phpmin = array(5, 4); // Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3, 9); // Minimum version of Dolibarr required by module
     		$this->langfiles = array("accountancy","compta");
     
    @@ -287,6 +287,5 @@ class modAccounting extends DolibarrModules
     			'aa.account_parent'=>array('rule'=>'zeroifnull'),
     		);
     		$this->import_examplevalues_array[$r]=array('aa.fk_pcg_version'=>"PCG99-ABREGE",'aa.account_number'=>"707",'aa.label'=>"Product sales",'aa.account_parent'=>"1407","aa.fk_accounting_category"=>"","aa.pcg_type"=>"PROD",'aa.pcg_subtype'=>'PRODUCT','aa.active'=>'1','aa.datec'=>"2017-04-28");
    -
     	}
     }
    diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php
    index f5f63324063..e6a3f294c82 100644
    --- a/htdocs/core/modules/modAdherent.class.php
    +++ b/htdocs/core/modules/modAdherent.class.php
    @@ -49,7 +49,7 @@ class modAdherent extends DolibarrModules
             $this->numero = 310;
     
             $this->family = "hr";
    -        $this->module_position = 20;
    +        $this->module_position = '20';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
             $this->description = "Management of members of a foundation or association";
    @@ -62,17 +62,17 @@ class modAdherent extends DolibarrModules
             $this->dirs = array("/adherent/temp");
     
             // Config pages
    -        //-------------
             $this->config_page_url = array("adherent.php@adherents");
     
             // Dependencies
    -        //------------
    -        $this->depends = array();
    -        $this->requiredby = array('modMailmanSpip');
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array('modMailmanSpip');	// List of module class names as string this module is in conflict with
             $this->langfiles = array("members","companies");
    +        $this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
             // Constants
    -        //-----------
             $this->const = array();
             $r=0;
     
    @@ -347,6 +347,8 @@ class modAdherent extends DolibarrModules
     		);
     
             // Cronjobs
    +        $arraydate=dol_getdate(dol_now());
    +        $datestart=dol_mktime(22, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']);
             $this->cronjobs = array(
     			0=>array(
     				'label'=>'SendReminderForExpiredSubscriptionTitle',
    @@ -360,9 +362,9 @@ class modAdherent extends DolibarrModules
     				'priority'=>50,
     				'status'=>0,
     				'test'=>true,
    +				'datestart'=>$datestart
     			),
             );
    -
         }
     
     
    diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php
    index 30a606bb7c9..1f6fa467469 100644
    --- a/htdocs/core/modules/modAgenda.class.php
    +++ b/htdocs/core/modules/modAgenda.class.php
    @@ -51,7 +51,7 @@ class modAgenda extends DolibarrModules
     		$this->numero = 2400;
     
     		$this->family = "projects";
    -		$this->module_position = 15;
    +		$this->module_position = '15';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Follow events or rendez-vous. Record manual events into Agendas or let application record automatic events for log tracking.";
    @@ -65,14 +65,15 @@ class modAgenda extends DolibarrModules
     		$this->dirs = array("/agenda/temp");
     
     		// Config pages
    -		//-------------
     		$this->config_page_url = array("agenda_other.php");
     
    -		// Dependancies
    -		//-------------
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
     		$this->langfiles = array("companies");
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Module parts
             $this->module_parts = array();
    @@ -112,9 +113,9 @@ class modAgenda extends DolibarrModules
     
     		// Cronjobs
     		//------------
    +		$datestart=dol_now();
     		$this->cronjobs = array(
    -			0=>array('label'=>'SendEmailsReminders', 'jobtype'=>'method', 'class'=>'comm/action/class/actioncomm.class.php', 'objectname'=>'ActionComm', 'method'=>'sendEmailsReminder', 'parameters'=>'', 'comment'=>'SendEMailsReminder', 'frequency'=>10, 'unitfrequency'=>60, 'priority'=>10, 'status'=>1, 'test'=>'$conf->agenda->enabled'),
    -		    // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24)
    +			0=>array('label'=>'SendEmailsReminders', 'jobtype'=>'method', 'class'=>'comm/action/class/actioncomm.class.php', 'objectname'=>'ActionComm', 'method'=>'sendEmailsReminder', 'parameters'=>'', 'comment'=>'SendEMailsReminder', 'frequency'=>10, 'unitfrequency'=>60, 'priority'=>10, 'status'=>1, 'test'=>'$conf->agenda->enabled', 'datestart'=>$datestart),
     		);
     
     		// Permissions
    @@ -418,7 +419,5 @@ class modAgenda extends DolibarrModules
     		if (empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND (sc.fk_user = '.(empty($user)?0:$user->id).' OR ac.fk_soc IS NULL)';
     		if (empty($user->rights->agenda->allactions->read)) $this->export_sql_end[$r] .=' AND acr.fk_element = '.(empty($user)?0:$user->id);
     		$this->export_sql_end[$r] .=' ORDER BY ac.datep';
    -
     	}
    -
     }
    diff --git a/htdocs/core/modules/modApi.class.php b/htdocs/core/modules/modApi.class.php
    index c8dc7ae84ba..71374e136e5 100644
    --- a/htdocs/core/modules/modApi.class.php
    +++ b/htdocs/core/modules/modApi.class.php
    @@ -82,7 +82,7 @@ class modApi extends DolibarrModules
     		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
     		$this->requiredby = array();	// List of modules id to disable if this one is disabled
     		$this->conflictwith = array();	// List of modules id this module is in conflict with
    -		$this->phpmin = array(5,3);					// Minimum version of PHP required by module
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("other");
     
     		// Constants
    diff --git a/htdocs/core/modules/modAsset.class.php b/htdocs/core/modules/modAsset.class.php
    index 9b82a6015c4..dd61c75df2a 100644
    --- a/htdocs/core/modules/modAsset.class.php
    +++ b/htdocs/core/modules/modAsset.class.php
    @@ -27,15 +27,11 @@
     include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
     
    -// The class name should start with a lower case mod for Dolibarr to pick it up
    -// so we ignore the Squiz.Classes.ValidClassName.NotCamelCaps rule.
    -// @codingStandardsIgnoreStart
     /**
      *  Description and activation class for module FixedAssets
      */
     class modAsset extends DolibarrModules
     {
    -	// @codingStandardsIgnoreEnd
     	/**
     	 * Constructor. Define names, constants, directories, boxes, permissions
     	 *
    @@ -57,7 +53,7 @@ class modAsset extends DolibarrModules
     		// It is used to group modules by family in module setup page
     		$this->family = "financial";
     		// Module position in the family on 2 digits ('01', '10', '20', ...)
    -		$this->module_position = '90';
    +		$this->module_position = '70';
     		// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
     		//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
     
    @@ -96,7 +92,7 @@ class modAsset extends DolibarrModules
     		$this->requiredby = array();	// List of module ids to disable if this one is disabled
     		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
     		$this->langfiles = array("assets");
    -		$this->phpmin = array(5,3);					// Minimum version of PHP required by module
    +		$this->phpmin = array(5,4);					// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(7,0);	// Minimum version of Dolibarr required by module
     		$this->warnings_activation = array();                     // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
     		$this->warnings_activation_ext = array();                 // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    @@ -178,9 +174,9 @@ class modAsset extends DolibarrModules
     
     		// Cronjobs (List of cron jobs entries to add when module is enabled)
     		// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
    -		$this->cronjobs = array(
    -			0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/asset/class/asset.class.php', 'objectname'=>'Asset', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true)
    -		);
    +		//$this->cronjobs = array(
    +		//	0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/asset/class/asset.class.php', 'objectname'=>'Asset', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true)
    +		//);
     		// 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'=>true),
     		//                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
     		// );
    @@ -335,5 +331,4 @@ class modAsset extends DolibarrModules
     
     		return $this->_init($sql,$options);
     	}
    -
     }
    diff --git a/htdocs/core/modules/modBanque.class.php b/htdocs/core/modules/modBanque.class.php
    index 602085b9f5a..d6cc2431948 100644
    --- a/htdocs/core/modules/modBanque.class.php
    +++ b/htdocs/core/modules/modBanque.class.php
    @@ -49,7 +49,7 @@ class modBanque extends DolibarrModules
     		$this->numero = 85;
     
     		$this->family = "financial";
    -		$this->module_position = 510;
    +		$this->module_position = '51';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des comptes financiers de type Comptes bancaires ou postaux";
    @@ -86,49 +86,49 @@ class modBanque extends DolibarrModules
     
     		$r++;
     		$this->rights[$r][0] = 111; // id de la permission
    -		$this->rights[$r][1] = 'Lire les comptes bancaires'; // libelle de la permission
    +		$this->rights[$r][1] = 'Read bank account and transactions';
     		$this->rights[$r][2] = 'r';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'lire';
     
     		$r++;
     		$this->rights[$r][0] = 112; // id de la permission
    -		$this->rights[$r][1] = 'Creer/modifier montant/supprimer ecriture bancaire'; // libelle de la permission
    +		$this->rights[$r][1] = 'Creer/modifier montant/supprimer ecriture bancaire';
     		$this->rights[$r][2] = 'w';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'modifier';
     
     		$r++;
     		$this->rights[$r][0] = 113; // id de la permission
    -		$this->rights[$r][1] = 'Configurer les comptes bancaires (creer, gerer categories)'; // libelle de la permission
    +		$this->rights[$r][1] = 'Configurer les comptes bancaires (creer, gerer categories)';
     		$this->rights[$r][2] = 'a';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'configurer';
     
     		$r++;
     		$this->rights[$r][0] = 114; // id de la permission
    -		$this->rights[$r][1] = 'Rapprocher les ecritures bancaires'; // libelle de la permission
    +		$this->rights[$r][1] = 'Rapprocher les ecritures bancaires';
     		$this->rights[$r][2] = 'w';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'consolidate';
     
     		$r++;
     		$this->rights[$r][0] = 115; // id de la permission
    -		$this->rights[$r][1] = 'Exporter transactions et releves'; // libelle de la permission
    +		$this->rights[$r][1] = 'Exporter transactions et releves';
     		$this->rights[$r][2] = 'r';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'export';
     
     		$r++;
     		$this->rights[$r][0] = 116; // id de la permission
    -		$this->rights[$r][1] = 'Virements entre comptes'; // libelle de la permission
    +		$this->rights[$r][1] = 'Virements entre comptes';
     		$this->rights[$r][2] = 'w';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'transfer';
     
     		$r++;
     		$this->rights[$r][0] = 117; // id de la permission
    -		$this->rights[$r][1] = 'Gerer les envois de cheques'; // libelle de la permission
    +		$this->rights[$r][1] = 'Gerer les envois de cheques';
     		$this->rights[$r][2] = 'w';
     		$this->rights[$r][3] = 0;
     		$this->rights[$r][4] = 'cheque';
    @@ -199,7 +199,6 @@ class modBanque extends DolibarrModules
     		$this->export_sql_end[$r] .=' AND p.fk_paiement = 7';
     		$this->export_sql_end[$r] .=' AND ba.entity IN ('.getEntity('bank_account').')';
     		$this->export_sql_order[$r] =' ORDER BY b.datev, b.num_releve';
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php
    index 07331bcbc3c..2c422cb4ad6 100644
    --- a/htdocs/core/modules/modBlockedLog.class.php
    +++ b/htdocs/core/modules/modBlockedLog.class.php
    @@ -47,11 +47,11 @@ class modBlockedLog extends DolibarrModules
     		// It is used to group modules in module setup page
             $this->family = "base";
             // Module position in the family on 2 digits ('01', '10', '20', ...)
    -        $this->module_position = '90';
    +        $this->module_position = '75';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
             $this->description = "Enable a log on some business events into a non reversible log. This module may be mandatory for some countries.";
    -		// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
    +        // Possible values for version are: 'development', 'experimental', 'dolibarr' or version
             $this->version = 'dolibarr';
             // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
             $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
    @@ -145,7 +145,8 @@ class modBlockedLog extends DolibarrModules
          *
          * @return	boolean		True if already used, otherwise False
          */
    -    function alreadyUsed() {
    +    function alreadyUsed()
    +    {
     
         	require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
         	$b=new BlockedLog($this->db);
    @@ -204,7 +205,8 @@ class modBlockedLog extends DolibarrModules
     	 * @param      string	$options    Options when enabling module ('', 'noboxes')
     	 * @return     int             		1 if OK, 0 if KO
     	 */
    -    function remove($options = '') {
    +    function remove($options = '')
    +    {
     
         	global $conf, $user;
     
    diff --git a/htdocs/core/modules/modBookmark.class.php b/htdocs/core/modules/modBookmark.class.php
    index 191e12bc2eb..db844393cd0 100644
    --- a/htdocs/core/modules/modBookmark.class.php
    +++ b/htdocs/core/modules/modBookmark.class.php
    @@ -101,6 +101,5 @@ class modBookmark extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     }
    diff --git a/htdocs/core/modules/modCashDesk.class.php b/htdocs/core/modules/modCashDesk.class.php
    index 4be7a937d1a..d9d4a6c2816 100644
    --- a/htdocs/core/modules/modCashDesk.class.php
    +++ b/htdocs/core/modules/modCashDesk.class.php
    @@ -46,7 +46,7 @@ class modCashDesk extends DolibarrModules
     		$this->rights_class = 'cashdesk';
     
     		$this->family = "portal";
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "CashDesk module";
    @@ -64,9 +64,10 @@ class modCashDesk extends DolibarrModules
     		$this->config_page_url = array("cashdesk.php@cashdesk");
     
     		// Dependencies
    +		$this->hidden = false;			            // A condition to hide module
     		$this->depends = array('always'=>"modBanque", 'always'=>"modFacture", 'always'=>"modProduct", 'FR'=>'modBlockedLog');	// List of modules id that must be enabled if this module is enabled
     		$this->requiredby = array();			    // List of modules id to disable if this one is disabled
    -		$this->phpmin = array(4,1);					// Minimum version of PHP required by module
    +		$this->phpmin = array(5,4);					// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(2,4);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("cashdesk");
     		$this->warnings_activation = array('FR'=>'WarningNoteModulePOSForFrenchLaw');                     // Warning to show when we activate module. array('always'='text') or array('FR'='text')
    @@ -80,7 +81,6 @@ class modCashDesk extends DolibarrModules
     
     		// Permissions
     		$this->rights = array();
    -		$this->rights_class = 'cashdesk';
     		$r=0;
     
     		$r++;
    diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php
    index 50074779955..1006869d69f 100644
    --- a/htdocs/core/modules/modCategorie.class.php
    +++ b/htdocs/core/modules/modCategorie.class.php
    @@ -45,7 +45,7 @@ class modCategorie extends DolibarrModules
     		$this->numero = 1780;
     
     		$this->family = "technic";
    -		$this->module_position = 20;
    +		$this->module_position = '20';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des categories (produits, clients, fournisseurs...)";
    diff --git a/htdocs/core/modules/modCollab.class.php b/htdocs/core/modules/modCollab.class.php
    index 5349b000ac3..90cffc85448 100644
    --- a/htdocs/core/modules/modCollab.class.php
    +++ b/htdocs/core/modules/modCollab.class.php
    @@ -46,7 +46,7 @@ class modCollab extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
     		// It is used to group modules in module setup page
             $this->family = "portal";
    -        $this->module_position = 51;
    +        $this->module_position = '51';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
             $this->description = "Enable the public collaboration features, like shared pad, shared online sheets, etc...";
    diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php
    index 91a86e4e842..f8f96a119f0 100644
    --- a/htdocs/core/modules/modCommande.class.php
    +++ b/htdocs/core/modules/modCommande.class.php
    @@ -51,7 +51,7 @@ class modCommande extends DolibarrModules
     		$this->numero = 25;
     
     		$this->family = "crm";
    -		$this->module_position = 30;
    +		$this->module_position = '30';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des commandes clients";
    diff --git a/htdocs/core/modules/modComptabilite.class.php b/htdocs/core/modules/modComptabilite.class.php
    index 41349d214fc..2d0f81cf0cc 100644
    --- a/htdocs/core/modules/modComptabilite.class.php
    +++ b/htdocs/core/modules/modComptabilite.class.php
    @@ -48,7 +48,7 @@ class modComptabilite extends DolibarrModules
     		$this->numero = 10;
     
     		$this->family = "financial";
    -		$this->module_position = 600;
    +		$this->module_position = '60';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion sommaire de comptabilite";
    @@ -98,7 +98,6 @@ class modComptabilite extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modContrat.class.php b/htdocs/core/modules/modContrat.class.php
    index ac722cd04ef..36764d43ba4 100644
    --- a/htdocs/core/modules/modContrat.class.php
    +++ b/htdocs/core/modules/modContrat.class.php
    @@ -47,6 +47,7 @@ class modContrat extends DolibarrModules
     		$this->numero = 54;
     
     		$this->family = "crm";
    +		$this->module_position = '35';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des contrats de services";
    diff --git a/htdocs/core/modules/modDataPolicy.class.php b/htdocs/core/modules/modDataPolicy.class.php
    new file mode 100644
    index 00000000000..ca53440a3b9
    --- /dev/null
    +++ b/htdocs/core/modules/modDataPolicy.class.php
    @@ -0,0 +1,275 @@
    +<?php
    +
    +/* Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018      Nicolas ZABOURI      <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * 	\defgroup   datapolicy     Module datapolicy
    + *  \brief      datapolicy module descriptor.
    + *
    + *  \file       htdocs/datapolicy/core/modules/modDataPolicy.class.php
    + *  \ingroup    datapolicy
    + *  \brief      Description and activation file for module DATAPOLICY
    + */
    +include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php';
    +
    +
    +
    +// The class name should start with a lower case mod for Dolibarr to pick it up
    +// so we ignore the Squiz.Classes.ValidClassName.NotCamelCaps rule.
    +// @codingStandardsIgnoreStart
    +/**
    + *  Description and activation class for module datapolicy
    + */
    +class modDataPolicy extends DolibarrModules {
    +
    +    // @codingStandardsIgnoreEnd
    +    /**
    +     * Constructor. Define names, constants, directories, boxes, permissions
    +     *
    +     * @param DoliDB $db Database handler
    +     */
    +    public function __construct($db)
    +    {
    +        global $langs, $conf;
    +
    +        $this->db = $db;
    +
    +        // Id for module (must be unique).
    +        // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
    +        $this->numero = 4100;
    +        // Key text used to identify module (for permissions, menus, etc...)
    +        $this->rights_class = 'datapolicy';
    +
    +        // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
    +        // It is used to group modules by family in module setup page
    +        $this->family = "hr";
    +        // Module position in the family on 2 digits ('01', '10', '20', ...)
    +        $this->module_position = '70';
    +        // Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
    +        //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
    +        // Module label (no space allowed), used if translation string 'ModuledatapolicyName' not found (MyModue is name of module).
    +        $this->name = preg_replace('/^mod/i', '', get_class($this));
    +        // Module description, used if translation string 'ModuledatapolicyDesc' not found (MyModue is name of module).
    +        $this->description = "Module to manage Data policy (for compliance with GDPR in Europe or other Data policy rules)";
    +        // Used only if file README.md and README-LL.md not found.
    +        $this->descriptionlong = "";
    +
    +        // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
    +        $this->version = 'development';
    +        // Key used in llx_const table to save module status enabled/disabled (where datapolicy is value of property name of module in uppercase)
    +        $this->const_name = 'MAIN_MODULE_' . strtoupper($this->name);
    +        // Name of image file used for this module.
    +        // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
    +        // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
    +        $this->picto = 'generic';
    +
    +        // Defined all module parts (triggers, login, substitutions, menus, css, etc...)
    +        // for default path (eg: /datapolicy/core/xxxxx) (0=disable, 1=enable)
    +        // for specific path of parts (eg: /datapolicy/core/modules/barcode)
    +        // for specific css file (eg: /datapolicy/css/datapolicy.css.php)
    +        $this->module_parts = array(
    +            'triggers' => 0, // Set this to 1 if module has its own trigger directory (core/triggers)
    +            'login' => 0, // Set this to 1 if module has its own login method file (core/login)
    +            'substitutions' => 0, // Set this to 1 if module has its own substitution function file (core/substitutions)
    +            'menus' => 0, // Set this to 1 if module has its own menus handler directory (core/menus)
    +            'theme' => 0, // Set this to 1 if module has its own theme directory (theme)
    +            'tpl' => 0, // Set this to 1 if module overwrite template dir (core/tpl)
    +            'barcode' => 0, // Set this to 1 if module has its own barcode directory (core/modules/barcode)
    +            'models' => 0, // Set this to 1 if module has its own models directory (core/modules/xxx)
    +            'hooks' => array('data' => array('membercard', 'contactcard', 'thirdpartycard'), 'entity' => $conf->entity)  // Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
    +        );
    +
    +        // Data directories to create when module is enabled.
    +        // Example: this->dirs = array("/datapolicy/temp","/datapolicy/subdir");
    +        $this->dirs = array("/datapolicy/temp");
    +
    +        // Config pages. Put here list of php page, stored into datapolicy/admin directory, to use to setup module.
    +        $this->config_page_url = array("setup.php@datapolicy");
    +
    +        // Dependencies
    +        $this->hidden = false;   // A condition to hide module
    +        $this->depends = array();  // List of module class names as string that must be enabled if this module is enabled
    +        $this->requiredby = array(); // List of module ids to disable if this one is disabled
    +        $this->conflictwith = array(); // List of module class names as string this module is in conflict with
    +        $this->langfiles = array("datapolicy@datapolicy");
    +        $this->phpmin = array(5, 3);     // Minimum version of PHP required by module
    +        $this->need_dolibarr_version = array(4, 0); // Minimum version of Dolibarr required by module
    +        $this->warnings_activation = array();                     // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    +        $this->warnings_activation_ext = array();                 // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    +        //$this->automatic_activation = array('FR'=>'datapolicyWasAutomaticallyActivatedBecauseOfYourCountryChoice');
    +        //$this->always_enabled = true;								// If true, can't be disabled
    +        // Constants
    +        // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
    +        // Example: $this->const=array(0=>array('datapolicy_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
    +        //                             1=>array('datapolicy_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
    +        // );
    +        $this->const = array(
    +            array('DATAPOLICY_TIERS_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_ADHERENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +        );
    +
    +        $country = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
    +
    +        // Some keys to add into the overwriting translation tables
    +        /* $this->overwrite_translation = array(
    +          'en_US:ParentCompany'=>'Parent company or reseller',
    +          'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
    +          ) */
    +
    +        if (!isset($conf->datapolicy) || !isset($conf->datapolicy->enabled)) {
    +            $conf->datapolicy = new stdClass();
    +            $conf->datapolicy->enabled = 0;
    +        }
    +
    +
    +        // Array to add new pages in new tabs
    +        $this->tabs = array();
    +        // Example:
    +        // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@datapolicy:$user->rights->datapolicy->read:/datapolicy/mynewtab1.php?id=__ID__');  					// To add a new tab identified by code tabname1
    +        // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@datapolicy:$user->rights->othermodule->read:/datapolicy/mynewtab2.php?id=__ID__',  	// To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
    +        // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove');                                                     										// To remove an existing tab identified by code tabname
    +        //
    +        // Where objecttype can be
    +        // 'categories_x'	  to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
    +        // 'contact'          to add a tab in contact view
    +        // 'contract'         to add a tab in contract view
    +        // 'group'            to add a tab in group view
    +        // 'intervention'     to add a tab in intervention view
    +        // 'invoice'          to add a tab in customer invoice view
    +        // 'invoice_supplier' to add a tab in supplier invoice view
    +        // 'member'           to add a tab in fundation member view
    +        // 'opensurveypoll'	  to add a tab in opensurvey poll view
    +        // 'order'            to add a tab in customer order view
    +        // 'order_supplier'   to add a tab in supplier order view
    +        // 'payment'		  to add a tab in payment view
    +        // 'payment_supplier' to add a tab in supplier payment view
    +        // 'product'          to add a tab in product view
    +        // 'propal'           to add a tab in propal view
    +        // 'project'          to add a tab in project view
    +        // 'stock'            to add a tab in stock view
    +        // 'thirdparty'       to add a tab in third party view
    +        // 'user'             to add a tab in user view
    +        // Dictionaries
    +        $this->dictionaries = array();
    +        /* Example:
    +          $this->dictionaries=array(
    +          'langs'=>'mylangfile@datapolicy',
    +          'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"),		// List of tables we want to see into dictonnary editor
    +          'tablib'=>array("Table1","Table2","Table3"),													// Label of tables
    +          'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),	// Request to select fields
    +          'tabsqlsort'=>array("label ASC","label ASC","label ASC"),																					// Sort order
    +          'tabfield'=>array("code,label","code,label","code,label"),																					// List of fields (result of select to show dictionary)
    +          'tabfieldvalue'=>array("code,label","code,label","code,label"),																				// List of fields (list of fields to edit a record)
    +          'tabfieldinsert'=>array("code,label","code,label","code,label"),																			// List of fields (list of fields for insert)
    +          'tabrowid'=>array("rowid","rowid","rowid"),																									// Name of columns with primary key (try to always name it 'rowid')
    +          'tabcond'=>array($conf->datapolicy->enabled,$conf->datapolicy->enabled,$conf->datapolicy->enabled)												// Condition to show each dictionary
    +          );
    +         */
    +
    +
    +        // Boxes/Widgets
    +        // Add here list of php file(s) stored in datapolicy/core/boxes that contains class to show a widget.
    +        $this->boxes = array();
    +
    +
    +        // Cronjobs (List of cron jobs entries to add when module is enabled)
    +        // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
    +        $this->cronjobs = array(
    +            0 => array('label' => 'DATAPOLICY Cron', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'exec', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 1, 'test' => true),
    +            //1 => array('label' => 'DATAPOLICY Mailing', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
    +        );
    +        // 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'=>true),
    +        //                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
    +        // );
    +        // Permissions
    +        $this->rights = array();  // Permission array used by this module
    +        // Main menu entries
    +        $this->menu = array();   // List of menus to add
    +        $r = 0;
    +    }
    +
    +    /**
    +     * 	Function called when module is enabled.
    +     * 	The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
    +     * 	It also creates data directories
    +     *
    +     * 	@param      string	$options    Options when enabling module ('', 'noboxes')
    +     * 	@return     int             	1 if OK, 0 if KO
    +     */
    +    public function init($options = '')
    +    {
    +    	global $langs;
    +
    +    	$this->_load_tables('/datapolicy/sql/');
    +
    +        // Create extrafields
    +        include_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
    +        $extrafields = new ExtraFields($this->db);
    +
    +		/*
    +        // Extrafield contact
    +        $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0);
    +        $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'thirdparty', 0, 0, '', '', 0, '', '0', 0);
    +
    +        // Extrafield Tiers
    +        $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'contact', 0, 0, '', '', 1, '', '3', 0);
    +        $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'contact', 0, 0, '', '', 0, '', '0', 0);
    +
    +        // Extrafield Adherent
    +        $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0);
    +        $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'adherent', 0, 0, '', '', 0, '', '0', 0);
    +		*/
    +
    +        $sql = array();
    +
    +        return $this->_init($sql, $options);
    +    }
    +
    +    /**
    +     * 	Function called when module is disabled.
    +     * 	Remove from database constants, boxes and permissions from Dolibarr database.
    +     * 	Data directories are not deleted
    +     *
    +     * 	@param      string	$options    Options when enabling module ('', 'noboxes')
    +     * 	@return     int             	1 if OK, 0 if KO
    +     */
    +    public function remove($options = '')
    +    {
    +        $sql = array();
    +
    +        return $this->_remove($sql, $options);
    +    }
    +}
    diff --git a/htdocs/core/modules/modDav.class.php b/htdocs/core/modules/modDav.class.php
    index 77c3f8feef7..92153d83688 100644
    --- a/htdocs/core/modules/modDav.class.php
    +++ b/htdocs/core/modules/modDav.class.php
    @@ -26,15 +26,11 @@
     include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
     
    -// The class name should start with a lower case mod for Dolibarr to pick it up
    -// so we ignore the Squiz.Classes.ValidClassName.NotCamelCaps rule.
    -// @codingStandardsIgnoreStart
     /**
      *  Description and activation class for module dav
      */
     class modDav extends DolibarrModules
     {
    -	// @codingStandardsIgnoreEnd
     	/**
     	 * Constructor. Define names, constants, directories, boxes, permissions
     	 *
    @@ -48,7 +44,7 @@ class modDav extends DolibarrModules
     
     		// Id for module (must be unique).
     		// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
    -		$this->numero = 50310;		// TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve id number for your module
    +		$this->numero = 50310;
     		// Key text used to identify module (for permissions, menus, etc...)
     		$this->rights_class = 'dav';
     
    @@ -56,7 +52,7 @@ class modDav extends DolibarrModules
     		// It is used to group modules by family in module setup page
     		$this->family = "interface";
     		// Module position in the family on 2 digits ('01', '10', '20', ...)
    -		$this->module_position = '90';
    +		$this->module_position = '75';
     		// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
     		//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
     
    @@ -68,7 +64,7 @@ class modDav extends DolibarrModules
     		$this->descriptionlong = "davDescription";
     
     		// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
    -		$this->version = 'experimental';
    +		$this->version = 'dolibarr';
     		// Key used in llx_const table to save module status enabled/disabled (where DAV is value of property name of module in uppercase)
     		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
     		// Name of image file used for this module.
    @@ -108,7 +104,7 @@ class modDav extends DolibarrModules
     		//                             1=>array('DAV_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
     		// );
     		$this->const = array(
    -			1=>array('DAV_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
    +			//1=>array('DAV_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
     		);
     
     
    @@ -177,9 +173,9 @@ class modDav extends DolibarrModules
     
     		// Cronjobs (List of cron jobs entries to add when module is enabled)
     		// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
    -		$this->cronjobs = array(
    +		//$this->cronjobs = array(
     			//0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/dav/class/myobject.class.php', 'objectname'=>'MyObject', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true)
    -		);
    +		//);
     		// 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'=>true),
     		//                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
     		// );
    @@ -324,5 +320,4 @@ class modDav extends DolibarrModules
     
     		return $this->_remove($sql, $options);
     	}
    -
     }
    diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php
    index 3baa7b74590..9fd5b618c0c 100644
    --- a/htdocs/core/modules/modDeplacement.class.php
    +++ b/htdocs/core/modules/modDeplacement.class.php
    @@ -45,7 +45,7 @@ class modDeplacement extends DolibarrModules
     		$this->numero = 75 ;
     
     		$this->family = "hr";
    -		$this->module_position = 41;
    +		$this->module_position = '41';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des notes de frais et deplacements";		// Si traduction Module75Desc non trouvee
    diff --git a/htdocs/core/modules/modDocumentGeneration.class.php b/htdocs/core/modules/modDocumentGeneration.class.php
    index 211fb38feca..f9e3378f5ea 100644
    --- a/htdocs/core/modules/modDocumentGeneration.class.php
    +++ b/htdocs/core/modules/modDocumentGeneration.class.php
    @@ -45,7 +45,7 @@ class modDocumentGeneration extends DolibarrModules
     		$this->numero = 1520;
     
     		$this->family = "technic";
    -		$this->module_position = 80;
    +		$this->module_position = '80';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Direct mail document generation";
    diff --git a/htdocs/core/modules/modDon.class.php b/htdocs/core/modules/modDon.class.php
    index dacfad736bf..76bdb2ccb63 100644
    --- a/htdocs/core/modules/modDon.class.php
    +++ b/htdocs/core/modules/modDon.class.php
    @@ -140,7 +140,6 @@ class modDon extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modDynamicPrices.class.php b/htdocs/core/modules/modDynamicPrices.class.php
    index c7bc152ff64..a164bec953c 100644
    --- a/htdocs/core/modules/modDynamicPrices.class.php
    +++ b/htdocs/core/modules/modDynamicPrices.class.php
    @@ -82,6 +82,5 @@ class modDynamicPrices extends DolibarrModules
             $this->rights = array();
             $this->rights_class = 'dynamicprices';
             $r=0;
    -
         }
     }
    diff --git a/htdocs/core/modules/modECM.class.php b/htdocs/core/modules/modECM.class.php
    index 5b85ada7f70..c4c00597885 100644
    --- a/htdocs/core/modules/modECM.class.php
    +++ b/htdocs/core/modules/modECM.class.php
    @@ -48,7 +48,7 @@ class modECM extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','product','ecm','technic','other'
     		// It is used to sort modules in module setup page
     		$this->family = "ecm";
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		// Module description used if translation string 'ModuleXXXDesc' not found (XXX is id value)
    diff --git a/htdocs/core/modules/modEmailCollector.class.php b/htdocs/core/modules/modEmailCollector.class.php
    new file mode 100644
    index 00000000000..6d266fbe6f7
    --- /dev/null
    +++ b/htdocs/core/modules/modEmailCollector.class.php
    @@ -0,0 +1,323 @@
    +<?php
    +/* Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * 	\defgroup   dav     Module dav
    + *  \brief      dav module descriptor.
    + *
    + *  \file       htdocs/dav/core/modules/modDav.class.php
    + *  \ingroup    dav
    + *  \brief      Description and activation file for module dav
    + */
    +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
    +
    +
    +/**
    + *  Description and activation class for module dav
    + */
    +class modEmailCollector extends DolibarrModules
    +{
    +	/**
    +	 * Constructor. Define names, constants, directories, boxes, permissions
    +	 *
    +	 * @param DoliDB $db Database handler
    +	 */
    +	public function __construct($db)
    +	{
    +        global $langs,$conf;
    +
    +        $this->db = $db;
    +
    +		// Id for module (must be unique).
    +		// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
    +		$this->numero = 50320;
    +		// Key text used to identify module (for permissions, menus, etc...)
    +		$this->rights_class = 'dav';
    +
    +		// Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
    +		// It is used to group modules by family in module setup page
    +		$this->family = "interface";
    +		// Module position in the family on 2 digits ('01', '10', '20', ...)
    +		$this->module_position = '75';
    +		// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
    +		//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
    +
    +		// Module label (no space allowed), used if translation string 'ModuledavName' not found (MyModue is name of module).
    +		$this->name = preg_replace('/^mod/i','',get_class($this));
    +		// Module description, used if translation string 'ModuledavDesc' not found (MyModue is name of module).
    +		$this->description = "EmailCollectorDescription";
    +		// Used only if file README.md and README-LL.md not found.
    +		$this->descriptionlong = "EmailCollectorDescription";
    +
    +		// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
    +		$this->version = 'development';
    +		// Key used in llx_const table to save module status enabled/disabled (where DAV is value of property name of module in uppercase)
    +		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
    +		// Name of image file used for this module.
    +		// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
    +		// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
    +		$this->picto='generic';
    +
    +		// Defined all module parts (triggers, login, substitutions, menus, css, etc...)
    +		// for default path (eg: /dav/core/xxxxx) (0=disable, 1=enable)
    +		// for specific path of parts (eg: /dav/core/modules/barcode)
    +		// for specific css file (eg: /dav/css/dav.css.php)
    +		$this->module_parts = array();
    +
    +		// Data directories to create when module is enabled.
    +		// Example: this->dirs = array("/dav/temp","/dav/subdir");
    +		$this->dirs = array();
    +
    +		// Config pages. Put here list of php page, stored into dav/admin directory, to use to setup module.
    +		$this->config_page_url = array("emailcollector.php");
    +
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->langfiles = array("admin");
    +		$this->phpmin = array(5,4);					// Minimum version of PHP required by module
    +		$this->need_dolibarr_version = array(7,0);	// Minimum version of Dolibarr required by module
    +		$this->warnings_activation = array();                     // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    +		$this->warnings_activation_ext = array();                 // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    +		//$this->automatic_activation = array('FR'=>'davWasAutomaticallyActivatedBecauseOfYourCountryChoice');
    +		//$this->always_enabled = true;								// If true, can't be disabled
    +
    +		// Constants
    +		// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
    +		// Example: $this->const=array(0=>array('DAV_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
    +		//                             1=>array('DAV_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
    +		// );
    +		$this->const = array(
    +			//1=>array('DAV_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
    +		);
    +
    +
    +		if (! isset($conf->dav) || ! isset($conf->dav->enabled))
    +		{
    +			$conf->dav=new stdClass();
    +			$conf->dav->enabled=0;
    +		}
    +
    +
    +		// Array to add new pages in new tabs
    +        $this->tabs = array();
    +		// Example:
    +		// $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@dav:$user->rights->dav->read:/dav/mynewtab1.php?id=__ID__');  					// To add a new tab identified by code tabname1
    +        // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@dav:$user->rights->othermodule->read:/dav/mynewtab2.php?id=__ID__',  	// To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
    +        // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove');                                                     										// To remove an existing tab identified by code tabname
    +        //
    +        // Where objecttype can be
    +		// 'categories_x'	  to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
    +		// 'contact'          to add a tab in contact view
    +		// 'contract'         to add a tab in contract view
    +		// 'group'            to add a tab in group view
    +		// 'intervention'     to add a tab in intervention view
    +		// 'invoice'          to add a tab in customer invoice view
    +		// 'invoice_supplier' to add a tab in supplier invoice view
    +		// 'member'           to add a tab in fundation member view
    +		// 'opensurveypoll'	  to add a tab in opensurvey poll view
    +		// 'order'            to add a tab in customer order view
    +		// 'order_supplier'   to add a tab in supplier order view
    +		// 'payment'		  to add a tab in payment view
    +		// 'payment_supplier' to add a tab in supplier payment view
    +		// 'product'          to add a tab in product view
    +		// 'propal'           to add a tab in propal view
    +		// 'project'          to add a tab in project view
    +		// 'stock'            to add a tab in stock view
    +		// 'thirdparty'       to add a tab in third party view
    +		// 'user'             to add a tab in user view
    +
    +
    +        // Dictionaries
    +		$this->dictionaries=array();
    +        /* Example:
    +        $this->dictionaries=array(
    +            'langs'=>'mylangfile@dav',
    +            'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"),		// List of tables we want to see into dictonnary editor
    +            'tablib'=>array("Table1","Table2","Table3"),													// Label of tables
    +            'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),	// Request to select fields
    +            'tabsqlsort'=>array("label ASC","label ASC","label ASC"),																					// Sort order
    +            'tabfield'=>array("code,label","code,label","code,label"),																					// List of fields (result of select to show dictionary)
    +            'tabfieldvalue'=>array("code,label","code,label","code,label"),																				// List of fields (list of fields to edit a record)
    +            'tabfieldinsert'=>array("code,label","code,label","code,label"),																			// List of fields (list of fields for insert)
    +            'tabrowid'=>array("rowid","rowid","rowid"),																									// Name of columns with primary key (try to always name it 'rowid')
    +            'tabcond'=>array($conf->dav->enabled,$conf->dav->enabled,$conf->dav->enabled)												// Condition to show each dictionary
    +        );
    +        */
    +
    +
    +        // Boxes/Widgets
    +		// Add here list of php file(s) stored in dav/core/boxes that contains class to show a widget.
    +        $this->boxes = array(
    +        	//0=>array('file'=>'davwidget1.php@dav','note'=>'Widget provided by dav','enabledbydefaulton'=>'Home'),
    +        	//1=>array('file'=>'davwidget2.php@dav','note'=>'Widget provided by dav'),
    +        	//2=>array('file'=>'davwidget3.php@dav','note'=>'Widget provided by dav')
    +        );
    +
    +
    +		// Cronjobs (List of cron jobs entries to add when module is enabled)
    +		// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
    +		//$this->cronjobs = array(
    +			//0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/dav/class/myobject.class.php', 'objectname'=>'MyObject', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true)
    +		//);
    +		// 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'=>true),
    +		//                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
    +		// );
    +
    +
    +		// Permissions
    +		$this->rights = array();		// Permission array used by this module
    +
    +		/*
    +		$r=0;
    +		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
    +		$this->rights[$r][1] = 'Read myobject of dav';	// Permission label
    +		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
    +		$this->rights[$r][4] = 'read';				// In php code, permission will be checked by test if ($user->rights->dav->level1->level2)
    +		$this->rights[$r][5] = '';				    // In php code, permission will be checked by test if ($user->rights->dav->level1->level2)
    +
    +		$r++;
    +		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
    +		$this->rights[$r][1] = 'Create/Update myobject of dav';	// Permission label
    +		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
    +		$this->rights[$r][4] = 'write';				// In php code, permission will be checked by test if ($user->rights->dav->level1->level2)
    +		$this->rights[$r][5] = '';				    // In php code, permission will be checked by test if ($user->rights->dav->level1->level2)
    +
    +		$r++;
    +		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
    +		$this->rights[$r][1] = 'Delete myobject of dav';	// Permission label
    +		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
    +		$this->rights[$r][4] = 'delete';				// In php code, permission will be checked by test if ($user->rights->dav->level1->level2)
    +		$this->rights[$r][5] = '';				    // In php code, permission will be checked by test if ($user->rights->dav->level1->level2)
    +		*/
    +
    +		// Main menu entries
    +		$this->menu = array();			// List of menus to add
    +		$r=0;
    +
    +		// Add here entries to declare new menus
    +
    +		/* BEGIN MODULEBUILDER TOPMENU */
    +		/*$this->menu[$r++]=array('fk_menu'=>'',			                // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
    +								'type'=>'top',			                // This is a Top menu entry
    +								'titre'=>'dav',
    +								'mainmenu'=>'dav',
    +								'leftmenu'=>'',
    +								'url'=>'/dav/davindex.php',
    +								'langs'=>'dav@dav',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
    +								'position'=>1000+$r,
    +								'enabled'=>'$conf->dav->enabled',	// Define condition to show or hide menu entry. Use '$conf->dav->enabled' if entry must be visible if module is enabled.
    +								'perms'=>'1',			                // Use 'perms'=>'$user->rights->dav->level1->level2' if you want your menu with a permission rules
    +								'target'=>'',
    +								'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
    +		*/
    +		/* END MODULEBUILDER TOPMENU */
    +
    +		/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT
    +		$this->menu[$r++]=array(	'fk_menu'=>'fk_mainmenu=dav',	    // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
    +								'type'=>'left',			                // This is a Left menu entry
    +								'titre'=>'List MyObject',
    +								'mainmenu'=>'dav',
    +								'leftmenu'=>'dav_myobject_list',
    +								'url'=>'/dav/myobject_list.php',
    +								'langs'=>'dav@dav',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
    +								'position'=>1000+$r,
    +								'enabled'=>'$conf->dav->enabled',  // Define condition to show or hide menu entry. Use '$conf->dav->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
    +								'perms'=>'1',			                // Use 'perms'=>'$user->rights->dav->level1->level2' if you want your menu with a permission rules
    +								'target'=>'',
    +								'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
    +		$this->menu[$r++]=array(	'fk_menu'=>'fk_mainmenu=dav,fk_leftmenu=dav',	    // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
    +								'type'=>'left',			                // This is a Left menu entry
    +								'titre'=>'New MyObject',
    +								'mainmenu'=>'dav',
    +								'leftmenu'=>'dav_myobject_new',
    +								'url'=>'/dav/myobject_page.php?action=create',
    +								'langs'=>'dav@dav',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
    +								'position'=>1000+$r,
    +								'enabled'=>'$conf->dav->enabled',  // Define condition to show or hide menu entry. Use '$conf->dav->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
    +								'perms'=>'1',			                // Use 'perms'=>'$user->rights->dav->level1->level2' if you want your menu with a permission rules
    +								'target'=>'',
    +								'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
    +		END MODULEBUILDER LEFTMENU MYOBJECT */
    +
    +
    +		// Exports
    +		$r=1;
    +
    +		/* BEGIN MODULEBUILDER EXPORT MYOBJECT */
    +		/*
    +		$langs->load("dav@dav");
    +		$this->export_code[$r]=$this->rights_class.'_'.$r;
    +		$this->export_label[$r]='MyObjectLines';	// Translation key (used only if key ExportDataset_xxx_z not found)
    +		$this->export_icon[$r]='myobject@dav';
    +		$keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject';
    +		include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
    +		$keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject';
    +		include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
    +		//$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
    +		$this->export_sql_start[$r]='SELECT DISTINCT ';
    +		$this->export_sql_end[$r]  =' FROM '.MAIN_DB_PREFIX.'myobject as t';
    +		$this->export_sql_end[$r] .=' WHERE 1 = 1';
    +		$this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')';
    +		$r++; */
    +		/* END MODULEBUILDER EXPORT MYOBJECT */
    +	}
    +
    +	/**
    +	 *	Function called when module is enabled.
    +	 *	The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
    +	 *	It also creates data directories
    +	 *
    +     *	@param      string	$options    Options when enabling module ('', 'noboxes')
    +	 *	@return     int             	1 if OK, 0 if KO
    +	 */
    +	public function init($options='')
    +	{
    +		//$this->_load_tables('/dav/sql/');
    +
    +		// Create extrafields
    +		include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
    +		$extrafields = new ExtraFields($this->db);
    +
    +		//$result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1,  3, 'thirdparty',   0, 0, '', '', 1, '', 0, 0, '', '', 'dav@dav', '$conf->dav->enabled');
    +		//$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project',      0, 0, '', '', 1, '', 0, 0, '', '', 'dav@dav', '$conf->dav->enabled');
    +		//$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'dav@dav', '$conf->dav->enabled');
    +		//$result4=$extrafields->addExtraField('myattr4', "New Attr 4 label", 'select',  1,  3, 'thirdparty',   0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1 '', 0, 0, '', '', 'dav@dav', '$conf->dav->enabled');
    +		//$result5=$extrafields->addExtraField('myattr5', "New Attr 5 label", 'text',    1, 10, 'user',         0, 0, '', '', 1, '', 0, 0, '', '', 'dav@dav', '$conf->dav->enabled');
    +
    +		$sql = array();
    +
    +		return $this->_init($sql, $options);
    +	}
    +
    +	/**
    +	 *	Function called when module is disabled.
    +	 *	Remove from database constants, boxes and permissions from Dolibarr database.
    +	 *	Data directories are not deleted
    +	 *
    +	 *	@param      string	$options    Options when enabling module ('', 'noboxes')
    +	 *	@return     int             	1 if OK, 0 if KO
    +	 */
    +	public function remove($options = '')
    +	{
    +		$sql = array();
    +
    +		return $this->_remove($sql, $options);
    +	}
    +}
    diff --git a/htdocs/core/modules/modExpedition.class.php b/htdocs/core/modules/modExpedition.class.php
    index daf7ec4b3cc..8634adb0348 100644
    --- a/htdocs/core/modules/modExpedition.class.php
    +++ b/htdocs/core/modules/modExpedition.class.php
    @@ -49,7 +49,7 @@ class modExpedition extends DolibarrModules
     		$this->numero = 80;
     
     		$this->family = "crm";
    -		$this->module_position = 40;
    +		$this->module_position = '40';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des expeditions";
    diff --git a/htdocs/core/modules/modExpenseReport.class.php b/htdocs/core/modules/modExpenseReport.class.php
    index 2dd46c9b788..62daf54a395 100644
    --- a/htdocs/core/modules/modExpenseReport.class.php
    +++ b/htdocs/core/modules/modExpenseReport.class.php
    @@ -23,7 +23,7 @@
      *      \ingroup    expensereport
      *      \brief      Description and activation file for module ExpenseReport
      */
    -include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php");
    +include_once DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php";
     
     
     /**
    @@ -44,7 +44,7 @@ class modExpenseReport extends DolibarrModules
     		$this->numero = 770;
     
     		$this->family = "hr";
    -		$this->module_position = 40;
    +		$this->module_position = '40';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
    @@ -61,10 +61,11 @@ class modExpenseReport extends DolibarrModules
     		$this->config_page_url = array('expensereport.php');
     
     		// Dependencies
    -		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
     		// $this->conflictwith = array("modDeplacement"); // Deactivate for access on old information
     		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->phpmin = array(4,3);					// Minimum version of PHP required by module
    +		$this->phpmin = array(5,4);					// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,7);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("companies","trips");
     
    diff --git a/htdocs/core/modules/modExport.class.php b/htdocs/core/modules/modExport.class.php
    index b88438f5fe1..9c6f7af335f 100644
    --- a/htdocs/core/modules/modExport.class.php
    +++ b/htdocs/core/modules/modExport.class.php
    @@ -44,7 +44,7 @@ class modExport extends DolibarrModules
     		$this->numero = 240;
     
     		$this->family = "technic";
    -		$this->module_position = 72;
    +		$this->module_position = '72';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Outils d'exports de donnees Dolibarr (via un assistant)";
    @@ -94,6 +94,5 @@ class modExport extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     }
    diff --git a/htdocs/core/modules/modExternalRss.class.php b/htdocs/core/modules/modExternalRss.class.php
    index cf02888b9d2..8d1bf055673 100644
    --- a/htdocs/core/modules/modExternalRss.class.php
    +++ b/htdocs/core/modules/modExternalRss.class.php
    @@ -135,5 +135,4 @@ class modExternalRss extends DolibarrModules
     
     		return $this->_remove($sql,$options);
         }
    -
     }
    diff --git a/htdocs/core/modules/modExternalSite.class.php b/htdocs/core/modules/modExternalSite.class.php
    index 18bb0b000b2..374e9b2f02a 100644
    --- a/htdocs/core/modules/modExternalSite.class.php
    +++ b/htdocs/core/modules/modExternalSite.class.php
    @@ -113,7 +113,6 @@ class modExternalSite extends DolibarrModules
     			'user'=>0
     		);
     		$r++;
    -
     	}
     }
     
    diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php
    index 0326625b943..54aa96b5aa3 100644
    --- a/htdocs/core/modules/modFacture.class.php
    +++ b/htdocs/core/modules/modFacture.class.php
    @@ -48,7 +48,7 @@ class modFacture extends DolibarrModules
     		$this->numero = 30;
     
     		$this->family = "financial";
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i', '', get_class($this));
     		$this->description = "Gestion des factures";
    @@ -114,13 +114,14 @@ class modFacture extends DolibarrModules
     				2=>array('file'=>'box_graph_invoices_permonth.php', 'enabledbydefaulton'=>'Home')
     		);
     
    -        // Cronjobs
    -        $this->cronjobs = array(
    -            0=>array('label'=>'RecurringInvoices', 'jobtype'=>'method', 'class'=>'compta/facture/class/facture-rec.class.php', 'objectname'=>'FactureRec', 'method'=>'createRecurringInvoices', 'parameters'=>'', 'comment'=>'Generate recurring invoices', 'frequency'=>1, 'unitfrequency'=>3600 * 24, 'priority'=>50, 'status'=>1, 'test'=>'$conf->facture->enabled'),
    -            // 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>3600, 'unitfrequency'=>3600)
    -        );
    +		// Cronjobs
    +		$arraydate=dol_getdate(dol_now());
    +		$datestart=dol_mktime(23, 0, 0, $arraydate['mon'], $arraydate['mday'], $arraydate['year']);
    +		$this->cronjobs = array(
    +			0=>array('label'=>'RecurringInvoices', 'jobtype'=>'method', 'class'=>'compta/facture/class/facture-rec.class.php', 'objectname'=>'FactureRec', 'method'=>'createRecurringInvoices', 'parameters'=>'', 'comment'=>'Generate recurring invoices', 'frequency'=>1, 'unitfrequency'=>3600 * 24, 'priority'=>50, 'status'=>1, 'test'=>'$conf->facture->enabled', 'datestart'=>$datestart),
    +		);
     
    -        // Permissions
    +		// Permissions
     		$this->rights = array();
     		$this->rights_class = 'facture';
     		$r = 0;
    diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php
    index 812aa227ff6..fe2fac72b7a 100644
    --- a/htdocs/core/modules/modFckeditor.class.php
    +++ b/htdocs/core/modules/modFckeditor.class.php
    @@ -45,7 +45,7 @@ class modFckeditor extends DolibarrModules
     		$this->numero = 2000;
     
     		$this->family = "technic";
    -		$this->module_position = 20;
    +		$this->module_position = '20';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Editeur WYSIWYG";
    diff --git a/htdocs/core/modules/modFicheinter.class.php b/htdocs/core/modules/modFicheinter.class.php
    index 7db2ac45e30..5e4dda76868 100644
    --- a/htdocs/core/modules/modFicheinter.class.php
    +++ b/htdocs/core/modules/modFicheinter.class.php
    @@ -50,6 +50,7 @@ class modFicheinter extends DolibarrModules
             $this->numero = 70;
     
             $this->family = "crm";
    +        $this->module_position = '45';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
             $this->description = "Gestion des fiches d'intervention";
    @@ -196,7 +197,6 @@ class modFicheinter extends DolibarrModules
             $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid';
             $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('intervention').')';
             $r++;
    -
         }
     
     
    diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php
    index 0dc4284df7c..7b50cb7ae3e 100644
    --- a/htdocs/core/modules/modFournisseur.class.php
    +++ b/htdocs/core/modules/modFournisseur.class.php
    @@ -50,7 +50,7 @@ class modFournisseur extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','product','ecm','technic','other'
     		// It is used to group modules in module setup page
     		$this->family = "srm";
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des fournisseurs";
    diff --git a/htdocs/core/modules/modGeoIPMaxmind.class.php b/htdocs/core/modules/modGeoIPMaxmind.class.php
    index 88bc8b7e8b9..81eddf86076 100644
    --- a/htdocs/core/modules/modGeoIPMaxmind.class.php
    +++ b/htdocs/core/modules/modGeoIPMaxmind.class.php
    @@ -65,9 +65,11 @@ class modGeoIPMaxmind extends DolibarrModules
     		$this->config_page_url = array("geoipmaxmind.php");
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    -		$this->phpmin = array(4,2,0);
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);
     		$this->phpmax = array();
     		$this->need_dolibarr_version = array(2,7,-1);	// Minimum version of Dolibarr required by module
     		$this->need_javascript_ajax = 1;
    diff --git a/htdocs/core/modules/modGravatar.class.php b/htdocs/core/modules/modGravatar.class.php
    index b6b9d4c9a59..44b4f8a6e80 100644
    --- a/htdocs/core/modules/modGravatar.class.php
    +++ b/htdocs/core/modules/modGravatar.class.php
    @@ -71,9 +71,11 @@ class modGravatar extends DolibarrModules
     		$this->config_page_url = array();
     
     		// Dependencies
    -		$this->depends = array(); // List of modules id that must be enabled if this module is enabled
    -		$this->requiredby = array(); // List of modules id to disable if this one is disabled
    -		$this->phpmin = array(4, 3); // Minimum version of PHP required by module
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5, 4); // Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(2, 7); // Minimum version of Dolibarr required by module
     		$this->langfiles = array();
     
    diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php
    index a209fdccf2e..5da8cf74e71 100644
    --- a/htdocs/core/modules/modHRM.class.php
    +++ b/htdocs/core/modules/modHRM.class.php
    @@ -20,7 +20,7 @@
      * \ingroup HRM
      * \brief   Description and activation file for module HRM
      */
    -include_once (DOL_DOCUMENT_ROOT . "/core/modules/DolibarrModules.class.php");
    +include_once DOL_DOCUMENT_ROOT . "/core/modules/DolibarrModules.class.php";
     
     /**
      * Class to describe and activate the HRM module
    @@ -66,27 +66,16 @@ class modHRM extends DolibarrModules
     		$this->config_page_url = array('admin_hrm.php@hrm');
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array(/*"
    -			modSalaries,
    -			modExpenseReport,
    -			modHoliday
    -		"*/);
    -		$this->conflictwith = array();
    -		$this->phpmin = array (
    -			5,
    -			3
    -		); // Minimum version of PHP required by module
    -		$this->need_dolibarr_version = array (
    -			3,
    -			9
    -		); // Minimum version of Dolibarr required by module
    -		$this->langfiles = array (
    -			"hrm"
    -		);
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array(/*"modSalaries, modExpenseReport, modHoliday"*/);	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
    +		$this->need_dolibarr_version = array (3,9); // Minimum version of Dolibarr required by module
    +		$this->langfiles = array ("hrm");
     
    -		// Dictionnaries
    -		$this->dictionnaries=array();
    +		// Dictionaries
    +		$this->dictionaries=array();
     
     		// Constantes
     		$this->const = array ();
    @@ -131,7 +120,6 @@ class modHRM extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     
     	/**
    diff --git a/htdocs/core/modules/modHoliday.class.php b/htdocs/core/modules/modHoliday.class.php
    index 78a1c71fbcb..91fb69dd4de 100644
    --- a/htdocs/core/modules/modHoliday.class.php
    +++ b/htdocs/core/modules/modHoliday.class.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2005-2010 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2011      Dimitri Mouillard 	<dmouillard@teclib.com>
      * Copyright (C) 2013      Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2018      Charlene Benke		<charlie@patas-monkey.com>
      *
      * 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
    @@ -27,7 +28,7 @@
      *    \ingroup    holiday
      *    \brief      Description and activation file for module holiday
      */
    -include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php");
    +include_once DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php";
     
     
     /**
    @@ -53,7 +54,7 @@ class modHoliday extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
     		// It is used to group modules in module setup page
     		$this->family = "hr";
    -		$this->module_position = 30;
    +		$this->module_position = '30';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
    @@ -69,16 +70,22 @@ class modHoliday extends DolibarrModules
     
     		// Data directories to create when module is enabled.
     		// Example: this->dirs = array("/mymodule/temp");
    -		$this->dirs = array();
    +		$this->dirs = array("/holiday/temp");
     		$r=0;
     
    +		// Config pages
    +		$this->config_page_url = array("holiday.php");
    +
    +
     		// Config pages. Put here list of php page names stored in admmin directory used to setup module.
     		// $this->config_page_url = array("holiday.php?leftmenu=setup@holiday");
     
     		// Dependencies
    -		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
    -		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->phpmin = array(4,3);					// Minimum version of PHP required by module
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);					// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,0);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("holiday");
     
    @@ -87,6 +94,28 @@ class modHoliday extends DolibarrModules
     		//                             1=>array('MYMODULE_MYNEWCONST2','chaine','myvalue','This is another constant to add',0) );
     		//                             2=>array('MAIN_MODULE_MYMODULE_NEEDSMARTY','chaine',1,'Constant to say module need smarty',0)
     		$this->const = array();			// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 0 or 'allentities')
    +		$r=0;
    +
    +		$this->const[$r][0] = "HOLIDAY_ADDON";
    +		$this->const[$r][1] = "chaine";
    +		$this->const[$r][2] = "mod_holiday_madonna";
    +		$this->const[$r][3] = 'Nom du gestionnaire de numerotation des congés';
    +		$this->const[$r][4] = 0;
    +		$r++;
    +
    +		$this->const[$r][0] = "HOLIDAY_ADDON_PDF";
    +		$this->const[$r][1] = "chaine";
    +		$this->const[$r][2] = "celebrate";
    +		$this->const[$r][3] = 'Name of PDF model of holiday';
    +		$this->const[$r][4] = 0;
    +		$r++;
    +
    +		$this->const[$r][0] = "HOLIDAY_ADDON_PDF_ODT_PATH";
    +		$this->const[$r][1] = "chaine";
    +		$this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/holiday";
    +		$this->const[$r][3] = "";
    +		$this->const[$r][4] = 0;
    +		$r++;
     
     		// Array to add new pages in new tabs
     		//$this->tabs[] = array('data'=>'user:+paidholidays:CPTitreMenu:holiday:$user->rights->holiday->read:/holiday/list.php?mainmenu=hrm&id=__ID__');	// We avoid to get one tab for each module. RH data are already in RH tab.
    diff --git a/htdocs/core/modules/modImport.class.php b/htdocs/core/modules/modImport.class.php
    index 01d66644dc7..72677787d94 100644
    --- a/htdocs/core/modules/modImport.class.php
    +++ b/htdocs/core/modules/modImport.class.php
    @@ -44,7 +44,7 @@ class modImport extends DolibarrModules
     		$this->numero = 250;
     
     		$this->family = "technic";
    -        $this->module_position = 70;
    +        $this->module_position = '70';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Outils d'imports de donnees Dolibarr (via un assistant)";
    @@ -60,9 +60,11 @@ class modImport extends DolibarrModules
     		$this->config_page_url = array();
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    -		$this->phpmin = array(4,3,0);	// Need auto_detect_line_endings php option to solve MAC pbs.
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module - Need auto_detect_line_endings php option to solve MAC pbs.
     		$this->phpmax = array();
     		$this->need_dolibarr_version = array(2,7,-1);	// Minimum version of Dolibarr required by module
     		$this->need_javascript_ajax = 1;
    @@ -89,6 +91,5 @@ class modImport extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     }
    diff --git a/htdocs/core/modules/modIncoterm.class.php b/htdocs/core/modules/modIncoterm.class.php
    index 7d4d1251f31..95949eeb05a 100644
    --- a/htdocs/core/modules/modIncoterm.class.php
    +++ b/htdocs/core/modules/modIncoterm.class.php
    @@ -65,9 +65,11 @@ class modIncoterm extends DolibarrModules
     		$this->config_page_url = array();
     
     		// Dependencies
    -		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
    -		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->phpmin = array(5,0);					// Minimum version of PHP required by module
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,0);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("incoterm");
     
    diff --git a/htdocs/core/modules/modLabel.class.php b/htdocs/core/modules/modLabel.class.php
    index 2d91fd121bb..8c8a670a54d 100644
    --- a/htdocs/core/modules/modLabel.class.php
    +++ b/htdocs/core/modules/modLabel.class.php
    @@ -44,7 +44,7 @@ class modLabel extends DolibarrModules
     		$this->numero = 60;
     
     		$this->family = "technic";
    -		$this->module_position = 80;
    +		$this->module_position = '75';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des etiquettes";
    @@ -56,9 +56,12 @@ class modLabel extends DolibarrModules
     		// Data directories to create when module is enabled
     		$this->dirs = array("/label/temp");
     
    -		// Dependancies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Config pages
     		// $this->config_page_url = array("label.php");
    @@ -87,7 +90,6 @@ class modLabel extends DolibarrModules
     		$this->rights[4][1] = 'Supprimer les etiquettes'; // libelle de la permission
     		$this->rights[4][3] = 0; // La permission est-elle une permission par defaut
     		$this->rights[4][4] = 'supprimer';
    -
     	}
     
     	/**
    diff --git a/htdocs/core/modules/modLdap.class.php b/htdocs/core/modules/modLdap.class.php
    index 0f183bd6c76..90577ae3ccf 100644
    --- a/htdocs/core/modules/modLdap.class.php
    +++ b/htdocs/core/modules/modLdap.class.php
    @@ -60,9 +60,12 @@ class modLdap extends DolibarrModules
     		// Config pages
     		$this->config_page_url = array("ldap.php");
     
    -		// Dependancies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Constants
     		$this->const = array(
    diff --git a/htdocs/core/modules/modLoan.class.php b/htdocs/core/modules/modLoan.class.php
    index 51779f6ffc5..662ded1da21 100644
    --- a/htdocs/core/modules/modLoan.class.php
    +++ b/htdocs/core/modules/modLoan.class.php
    @@ -63,9 +63,11 @@ class modLoan extends DolibarrModules
     		$this->config_page_url = array('loan.php');
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    -		$this->conflictwith = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("loan");
     
     		// Constants
    @@ -143,7 +145,6 @@ class modLoan extends DolibarrModules
     		// Exports
     		//--------
     		$r=0;
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modMailing.class.php b/htdocs/core/modules/modMailing.class.php
    index 46b31a08696..749369ee8e9 100644
    --- a/htdocs/core/modules/modMailing.class.php
    +++ b/htdocs/core/modules/modMailing.class.php
    @@ -57,8 +57,11 @@ class modMailing extends DolibarrModules
     		$this->dirs = array("/mailing/temp");
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("mails");
     
     		// Config pages
    @@ -130,7 +133,6 @@ class modMailing extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modMailmanSpip.class.php b/htdocs/core/modules/modMailmanSpip.class.php
    index 9a019db7fea..e1a8f7c2cd6 100644
    --- a/htdocs/core/modules/modMailmanSpip.class.php
    +++ b/htdocs/core/modules/modMailmanSpip.class.php
    @@ -58,8 +58,11 @@ class modMailmanSpip extends DolibarrModules
     		$this->dirs = array();
     
     		// Dependencies
    -		$this->depends = array('modAdherent');
    -		$this->requiredby = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array('modAdherent');		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Config pages
     		$this->config_page_url = array('mailman.php');
    @@ -80,6 +83,5 @@ class modMailmanSpip extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     }
    diff --git a/htdocs/core/modules/modMargin.class.php b/htdocs/core/modules/modMargin.class.php
    index 53fba120656..58de64c8aad 100644
    --- a/htdocs/core/modules/modMargin.class.php
    +++ b/htdocs/core/modules/modMargin.class.php
    @@ -48,7 +48,7 @@ class modMargin extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
     		// It is used to group modules in module setup page
     		$this->family = "financial";
    -		$this->module_position = 550;
    +		$this->module_position = '55';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
    @@ -68,9 +68,11 @@ class modMargin extends DolibarrModules
     		$this->config_page_url = array("margin.php@margin");
     
     		// Dependencies
    -		$this->depends = array("modPropale", "modProduct");		// List of modules id that must be enabled if this module is enabled
    -		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->phpmin = array(5,1);					// Minimum version of PHP required by module
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array("modPropale", "modProduct");		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,2);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("margins");
     
    diff --git a/htdocs/core/modules/modModuleBuilder.class.php b/htdocs/core/modules/modModuleBuilder.class.php
    index b6ba08a84a5..7f4132d7e44 100644
    --- a/htdocs/core/modules/modModuleBuilder.class.php
    +++ b/htdocs/core/modules/modModuleBuilder.class.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2017   Laurent Destailleur  <eldy@users.sourcefore.net>
    + * Copyright (C) 2018   Nicolas ZABOURI   <info@inovea-conseil.com>
      *
      * 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
    @@ -48,7 +49,7 @@ class modModuleBuilder extends DolibarrModules
             $this->name = preg_replace('/^mod/i','',get_class($this));
             $this->description = "A RAD (Rapid Application Development) tool to help developers to build their own module.";
     		// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
    -        $this->version = 'experimental';
    +        $this->version = 'dolibarr';
             // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
             $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
             // Name of image file used for this module.
    @@ -59,9 +60,9 @@ class modModuleBuilder extends DolibarrModules
     
             // Config pages
             //-------------
    -        $this->config_page_url = array();
    +        $this->config_page_url = array('setup.php@modulebuilder');
     
    -        // Dependancies
    +        // Dependencies
             //-------------
     	    $this->hidden = false;	// A condition to disable module
     	    $this->depends = array();		// List of modules id that must be enabled if this module is enabled
    @@ -97,6 +98,5 @@ class modModuleBuilder extends DolibarrModules
                 'enabled'=>'$conf->modulebuilder->enabled && preg_match(\'/^(admintools|all)/\',$leftmenu) && ($user->admin || $conf->global->MODULEBUILDER_FOREVERYONE)',
                 'target'=>'_modulebuilder',
                 'user'=>0);
    -
         }
     }
    diff --git a/htdocs/core/modules/modMultiCurrency.class.php b/htdocs/core/modules/modMultiCurrency.class.php
    index 2d443c2e7bb..9e838a8605b 100644
    --- a/htdocs/core/modules/modMultiCurrency.class.php
    +++ b/htdocs/core/modules/modMultiCurrency.class.php
    @@ -54,7 +54,7 @@ class modMultiCurrency extends DolibarrModules
     		// It is used to group modules in module setup page
     		$this->family = "technic";
     		// Module position in the family
    -		$this->module_position = 40;
    +		$this->module_position = '40';
     
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i', '', get_class($this));
    @@ -88,7 +88,7 @@ class modMultiCurrency extends DolibarrModules
     		$this->depends = array(); // List of modules id that must be enabled if this module is enabled
     		$this->requiredby = array(); // List of modules id to disable if this one is disabled
     		$this->conflictwith = array(); // List of modules id this module is in conflict with
    -		$this->phpmin = array(5, 0); // Minimum version of PHP required by module
    +		$this->phpmin = array(5, 4); // Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3, 0); // Minimum version of Dolibarr required by module
     		$this->langfiles = array("multicurrency");
     
    diff --git a/htdocs/core/modules/modNotification.class.php b/htdocs/core/modules/modNotification.class.php
    index cc016d294b5..9dbd77fae86 100644
    --- a/htdocs/core/modules/modNotification.class.php
    +++ b/htdocs/core/modules/modNotification.class.php
    @@ -55,8 +55,11 @@ class modNotification extends DolibarrModules
     		$this->dirs = array();
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("mails");
     
     		// Config pages
    diff --git a/htdocs/core/modules/modOauth.class.php b/htdocs/core/modules/modOauth.class.php
    index 3177e41e787..f563baa9c92 100644
    --- a/htdocs/core/modules/modOauth.class.php
    +++ b/htdocs/core/modules/modOauth.class.php
    @@ -40,19 +40,19 @@ class modOauth extends DolibarrModules
          *
          *  @param      DoliDB      $db      Database handler
          */
    -    function  __construct($db)
    +    function __construct($db)
         {
             $this->db = $db ;
             $this->numero = 66000;
             // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
             // It is used to group modules in module setup page
             $this->family = "interface";
    -        $this->module_position = 510;
    +        $this->module_position = '51';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
             // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
             $this->description = "Enable OAuth authentication";
    -		// Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version
    +        // Possible values for version are: 'development', 'experimental', 'dolibarr' or 'dolibarr_deprecated' or version
             $this->version = 'dolibarr';
             $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
             // Name of image file used for this module.
    @@ -67,9 +67,11 @@ class modOauth extends DolibarrModules
             $this->config_page_url = array("oauth.php");
     
             // Dependencies
    -        $this->depends = array();
    -        $this->requiredby = array();
    -        $this->phpmin = array(5,1);                     // Minimum version of PHP required by module
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module                    // Minimum version of PHP required by module
             $this->need_dolibarr_version = array(3,7,-2);   // Minimum version of Dolibarr required by module
             $this->conflictwith = array();
             $this->langfiles = array("oauth");
    @@ -117,8 +119,6 @@ class modOauth extends DolibarrModules
             //                        'user'=>0);                     // 0=Menu for internal users, 1=external users, 2=both
     
             //$r++;
    -
    -
         }
     
     
    diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php
    index fcee9f585aa..be0b67950d7 100644
    --- a/htdocs/core/modules/modOpenSurvey.class.php
    +++ b/htdocs/core/modules/modOpenSurvey.class.php
    @@ -23,7 +23,7 @@
      *      \ingroup    opensurvey
      *      \brief      Description and activation file for module OpenSurvey
      */
    -include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php");
    +include_once DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php";
     
     
     /**
    @@ -52,7 +52,7 @@ class modOpenSurvey extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','product','technic','other'
     		// It is used to group modules in module setup page
     		$this->family = "portal";
    -		$this->module_position = 40;
    +		$this->module_position = '40';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		// Module description used if translation string 'ModuleXXXDesc' not found (XXX is value MyModule)
    @@ -72,9 +72,11 @@ class modOpenSurvey extends DolibarrModules
     		//$this->dirs[1] = DOL_DATA_ROOT.'/mymodule/temp;
     
     		// Dependencies
    -		$this->depends = array();		// List of modules id that must be enabled if this module is enabled
    -		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->phpmin = array(4,1);					// Minimum version of PHP required by module
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,4,0);	// Minimum version of Dolibarr required by module
     
     		// Constants
    diff --git a/htdocs/core/modules/modPaybox.class.php b/htdocs/core/modules/modPaybox.class.php
    index 727e6723ce2..ba7851aad4a 100644
    --- a/htdocs/core/modules/modPaybox.class.php
    +++ b/htdocs/core/modules/modPaybox.class.php
    @@ -69,9 +69,11 @@ class modPayBox extends DolibarrModules
             $this->config_page_url = array("paybox.php@paybox");
     
             // Dependencies
    -        $this->depends = array();		// List of modules id that must be enabled if this module is enabled
    -        $this->requiredby = array();	// List of modules id to disable if this one is disabled
    -        $this->phpmin = array(4,1);					// Minimum version of PHP required by module
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->need_dolibarr_version = array(2,6);	// Minimum version of Dolibarr required by module
             $this->langfiles = array("paybox");
     
    diff --git a/htdocs/core/modules/modPaypal.class.php b/htdocs/core/modules/modPaypal.class.php
    index e713685691c..a11fa41b7a6 100644
    --- a/htdocs/core/modules/modPaypal.class.php
    +++ b/htdocs/core/modules/modPaypal.class.php
    @@ -70,9 +70,11 @@ class modPaypal extends DolibarrModules
             $this->config_page_url = array("paypal.php@paypal");
     
             // Dependencies
    -        $this->depends = array();						// List of modules id that must be enabled if this module is enabled
    -        $this->requiredby = array('modPaypalPlus');		// List of modules id to disable if this one is disabled
    -        $this->phpmin = array(5,2);						// Minimum version of PHP required by module
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array('modPaypalPlus');	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->need_dolibarr_version = array(3,0);		// Minimum version of Dolibarr required by module
             $this->langfiles = array("paypal");
     
    diff --git a/htdocs/core/modules/modPrelevement.class.php b/htdocs/core/modules/modPrelevement.class.php
    index 4d91c937d99..e3f8c76498e 100644
    --- a/htdocs/core/modules/modPrelevement.class.php
    +++ b/htdocs/core/modules/modPrelevement.class.php
    @@ -48,7 +48,7 @@ class modPrelevement extends DolibarrModules
     		$this->numero = 57;
     
     		$this->family = "financial";
    -		$this->module_position = 520;
    +		$this->module_position = '52';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des Prelevements";
    @@ -63,9 +63,12 @@ class modPrelevement extends DolibarrModules
     		// Data directories to create when module is enabled
     		$this->dirs = array("/prelevement/temp","/prelevement/receipts");
     
    -		// Dependancies
    -		$this->depends = array("modFacture","modBanque");
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array("modFacture","modBanque");		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Config pages
     		$this->config_page_url = array("prelevement.php");
    @@ -132,7 +135,6 @@ class modPrelevement extends DolibarrModules
     		// Menus
     		//-------
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php
    index 1aa36bdacce..7e16b26d8ab 100644
    --- a/htdocs/core/modules/modPrinting.class.php
    +++ b/htdocs/core/modules/modPrinting.class.php
    @@ -40,17 +40,17 @@ class modPrinting extends DolibarrModules
          *
          *  @param      DoliDB      $db      Database handler
          */
    -    function  __construct($db)
    +    function __construct($db)
         {
             $this->db = $db ;
             $this->numero = 64000;
             // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
             // It is used to group modules in module setup page
             $this->family = "interface";
    -        $this->module_position = 520;
    +        $this->module_position = '52';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
    -		// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
    +        // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
             $this->description = "Enable Direct Printing System.";
             $this->version = 'dolibarr';    // 'development' or 'experimental' or 'dolibarr' or version
             $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
    @@ -66,9 +66,11 @@ class modPrinting extends DolibarrModules
             $this->config_page_url = array("printing.php@printing");
     
             // Dependencies
    -        $this->depends = array();
    -        $this->requiredby = array();
    -        $this->phpmin = array(5,1);                     // Minimum version of PHP required by module
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->need_dolibarr_version = array(3,7,-2);   // Minimum version of Dolibarr required by module
             $this->conflictwith = array();
             $this->langfiles = array("printing");
    @@ -115,7 +117,5 @@ class modPrinting extends DolibarrModules
                                     'user'=>0);                     // 0=Menu for internal users, 1=external users, 2=both
     
             $r++;
    -
    -
         }
     }
    diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php
    index 6ad67ac089c..58fc5b78c9f 100644
    --- a/htdocs/core/modules/modProduct.class.php
    +++ b/htdocs/core/modules/modProduct.class.php
    @@ -50,7 +50,7 @@ class modProduct extends DolibarrModules
     		$this->numero = 50;
     
     		$this->family = "products";
    -		$this->module_position = 20;
    +		$this->module_position = '20';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Product management";
    @@ -65,8 +65,11 @@ class modProduct extends DolibarrModules
     		$this->dirs = array("/product/temp");
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array("modStock","modBarcode","modProductBatch");
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array("modStock","modBarcode","modProductBatch");	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Config pages
     		$this->config_page_url = array("product.php@product");
    @@ -130,6 +133,13 @@ class modProduct extends DolibarrModules
     		$this->rights[$r][4] = 'export';
             $r++;
     
    +		$this->rights[$r][0] = 39;
    +		$this->rights[$r][1] = 'Ignore minimum price';
    +		$this->rights[$r][2] = 'r';
    +		$this->rights[$r][3] = 0;
    +		$this->rights[$r][4] = 'ignore_price_min_advance';
    +        $r++;
    +
             // Menus
             //-------
     
    diff --git a/htdocs/core/modules/modProductBatch.class.php b/htdocs/core/modules/modProductBatch.class.php
    index 91e8ddbae3c..99c2a6fa73c 100644
    --- a/htdocs/core/modules/modProductBatch.class.php
    +++ b/htdocs/core/modules/modProductBatch.class.php
    @@ -46,7 +46,7 @@ class modProductBatch extends DolibarrModules
     		$this->numero = 39000;
     
     		$this->family = "products";
    -		$this->module_position = 45;
    +		$this->module_position = '45';
     
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Batch number, eat-by and sell-by date management module";
    @@ -68,9 +68,11 @@ class modProductBatch extends DolibarrModules
     		$this->config_page_url = array("product_lot_extrafields.php@product");
     
     		// Dependencies
    -		$this->depends = array("modProduct","modStock","modExpedition","modFournisseur");		// List of modules id that must be enabled if this module is enabled. modExpedition is required to manage batch exit (by manual stock decrease on shipment), modSupplier to manage batch entry (after supplier order).
    -		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->phpmin = array(5,0);					// Minimum version of PHP required by module
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array("modProduct","modStock","modExpedition","modFournisseur");		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,0);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("productbatch");
     
    @@ -102,7 +104,6 @@ class modProductBatch extends DolibarrModules
     
     		// Exports
     		$r=0;
    -
     	}
     
     	/**
    diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php
    index d38fc743de1..47b02916bb0 100644
    --- a/htdocs/core/modules/modProjet.class.php
    +++ b/htdocs/core/modules/modProjet.class.php
    @@ -36,7 +36,6 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
      */
     class modProjet extends DolibarrModules
     {
    -
     	/**
     	 *   Constructor. Define names, constants, directories, boxes, permissions
     	 *
    @@ -50,7 +49,7 @@ class modProjet extends DolibarrModules
     		$this->numero = 400;
     
     		$this->family = "projects";
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des projets";
    @@ -64,10 +63,12 @@ class modProjet extends DolibarrModules
     		// Data directories to create when module is enabled
     		$this->dirs = array("/projet/temp");
     
    -		// Dependancies
    -		$this->depends = array();
    -		$this->requiredby = array();
    -		$this->conflictwith = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array('projects');
     
     		// Constants
    @@ -359,7 +360,7 @@ class modProjet extends DolibarrModules
     		$sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('beluga','project',".$conf->entity.")";
     		$sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'baleine' AND type = 'project' AND entity = ".$conf->entity;
     		$sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('baleine','project',".$conf->entity.")";
    -		
    +
     
     		return $this->_init($sql,$options);
     	}
    diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php
    index c0701d3bfe2..644b8f2e2f0 100644
    --- a/htdocs/core/modules/modPropale.class.php
    +++ b/htdocs/core/modules/modPropale.class.php
    @@ -49,7 +49,7 @@ class modPropale extends DolibarrModules
     		$this->numero = 20;
     
     		$this->family = "crm";
    -		$this->module_position = 20;
    +		$this->module_position = '20';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des propositions commerciales";
    @@ -63,9 +63,12 @@ class modPropale extends DolibarrModules
     		// Data directories to create when module is enabled
     		$this->dirs = array("/propale/temp");
     
    -		// Dependancies
    -		$this->depends = array("modSociete");
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array("modSociete");		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->config_page_url = array("propal.php");
     		$this->langfiles = array("propal","bills","companies","deliveries","products");
     
    @@ -280,6 +283,5 @@ class modPropale extends DolibarrModules
     		);
     
     		return $this->_init($sql,$options);
    -
     	}
     }
    diff --git a/htdocs/core/modules/modReceiptPrinter.class.php b/htdocs/core/modules/modReceiptPrinter.class.php
    index 19df7ca0726..0cb05499843 100644
    --- a/htdocs/core/modules/modReceiptPrinter.class.php
    +++ b/htdocs/core/modules/modReceiptPrinter.class.php
    @@ -40,14 +40,14 @@ class modReceiptPrinter extends DolibarrModules
          *
          *  @param      DoliDB      $db      Database handler
          */
    -    function  __construct($db)
    +    function __construct($db)
         {
             $this->db = $db ;
             $this->numero = 67000;
             // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
             // It is used to group modules in module setup page
             $this->family = "interface";
    -        $this->module_position = 530;
    +        $this->module_position = '53';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
             // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
    @@ -67,9 +67,11 @@ class modReceiptPrinter extends DolibarrModules
             $this->config_page_url = array("receiptprinter.php");
     
             // Dependencies
    -        $this->depends = array();
    -        $this->requiredby = array();
    -        $this->phpmin = array(5,1);                     // Minimum version of PHP required by module
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->need_dolibarr_version = array(3,9,-2);   // Minimum version of Dolibarr required by module
             $this->conflictwith = array();
             $this->langfiles = array("receiptprinter");
    @@ -117,8 +119,6 @@ class modReceiptPrinter extends DolibarrModules
             //                        'user'=>0);                     // 0=Menu for internal users, 1=external users, 2=both
     
             $r++;
    -
    -
         }
     
     
    @@ -141,5 +141,4 @@ class modReceiptPrinter extends DolibarrModules
                 );
             return $this->_init($sql,$options);
         }
    -
     }
    diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php
    index 15b414947ef..7e68ac7a83e 100644
    --- a/htdocs/core/modules/modResource.class.php
    +++ b/htdocs/core/modules/modResource.class.php
    @@ -55,7 +55,7 @@ class modResource extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
     		// It is used to group modules in module setup page
     		$this->family = "projects";
    -		$this->module_position = 20;
    +		$this->module_position = '20';
     		// Module label (no space allowed)
     		// used if translation string 'ModuleXXXName' not found
     		// (where XXX is value of numeric property 'numero' of module)
    @@ -95,7 +95,7 @@ class modResource extends DolibarrModules
     		// List of modules id to disable if this one is disabled
     		$this->requiredby = array('modPlace');
     		// Minimum version of PHP required by module
    -		$this->phpmin = array(5, 3);
    +		$this->phpmin = array(5, 4);
     
     		$this->langfiles = array("resource"); // langfiles@resource
     		// Constants
    @@ -285,7 +285,6 @@ class modResource extends DolibarrModules
     		$this->import_regex_array[$r]=array('s.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$');
     		$this->import_examplevalues_array[$r]=array('r.ref'=>"REF1",'r.fk_code_type_resource'=>"Code from dictionary resource type",'r.datec'=>"2017-01-01 or 2017-01-01 12:30:00");
     		$this->import_updatekeys_array[$r]=array('r.rf'=>'ResourceFormLabel_ref');
    -
     	}
     
     	/**
    diff --git a/htdocs/core/modules/modSalaries.class.php b/htdocs/core/modules/modSalaries.class.php
    index 52c417c0848..727b410cacb 100644
    --- a/htdocs/core/modules/modSalaries.class.php
    +++ b/htdocs/core/modules/modSalaries.class.php
    @@ -5,7 +5,7 @@
      * Copyright (C) 2004		Benoit Mortier       <benoit.mortier@opensides.be>
      * Copyright (C) 2005-2012	Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2014		Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2014		Alexandre Spangaro	 <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2014		Alexandre Spangaro	 <aspangaro@zendsi.com>
      *
      * 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
    @@ -23,11 +23,11 @@
      */
     
     /**
    - * 		\defgroup   salaries		Module salaries
    - * 		\brief      Module to include salaries management
    - *      \file       htdocs/core/modules/modSalaries.class.php
    - *      \ingroup    salaries
    - *      \brief      File to activate module salaries
    + *  \defgroup   salaries		Module salaries
    + *  \brief      Module to include salaries management
    + *  \file       htdocs/core/modules/modSalaries.class.php
    + *  \ingroup    salaries
    + *  \brief      File to activate module salaries
      */
     include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
    @@ -72,9 +72,11 @@ class modSalaries extends DolibarrModules
     		$this->config_page_url = array();
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    -		$this->conflictwith = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("salaries","bills");
     
     		// Constants
    @@ -161,7 +163,7 @@ class modSalaries extends DolibarrModules
     	 *		The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
     	 *		It also creates data directories
     	 *
    -     *      @param      string	$options    Options when enabling module ('', 'noboxes')
    +	 *      @param      string	$options    Options when enabling module ('', 'noboxes')
     	 *      @return     int             	1 if OK, 0 if KO
     	 */
     	function init($options='')
    diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php
    index 90b530df262..9ddf3f8b2e5 100644
    --- a/htdocs/core/modules/modService.class.php
    +++ b/htdocs/core/modules/modService.class.php
    @@ -48,7 +48,7 @@ class modService extends DolibarrModules
     		$this->numero = 53;
     
     		$this->family = "products";
    -		$this->module_position = 30;
    +		$this->module_position = '30';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Service management";
    @@ -62,9 +62,12 @@ class modService extends DolibarrModules
     		// Data directories to create when module is enabled
     		$this->dirs = array("/product/temp");
     
    -		// Dependancies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Config pages
     		$this->config_page_url = array("product.php@product");
    diff --git a/htdocs/core/modules/modSkype.class.php b/htdocs/core/modules/modSocialNetworks.class.php
    similarity index 64%
    rename from htdocs/core/modules/modSkype.class.php
    rename to htdocs/core/modules/modSocialNetworks.class.php
    index d84520318a3..6aceeff6a70 100644
    --- a/htdocs/core/modules/modSkype.class.php
    +++ b/htdocs/core/modules/modSocialNetworks.class.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2013   Alexandre Spangaro  <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2014   Laurent Destailleur <eldy@users.sourceforge.net>
      *
      * 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
    @@ -16,18 +17,18 @@
      */
     
     /**
    - * 	\defgroup   Skype   Module skype
    - *  \brief      Add a skype button.
    - *  \file       htdocs/core/modules/modSkype.class.php
    - *  \ingroup    Skype
    - *  \brief      Description and activation file for module skype
    + * 	\defgroup   SocialNetworks   Module SocialNetworks
    + *  \brief      Add a SocialNetworks button.
    + *  \file       htdocs/core/modules/modSocialNetworks.class.php
    + *  \ingroup    socialnetworks
    + *  \brief      Description and activation file for module SocialNetworks
      */
     include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
     /**
    - *	Class to describe a Cron module
    + *	Class to describe a SocialNetworks module
      */
    -class modSkype extends DolibarrModules
    +class modSocialNetworks extends DolibarrModules
     {
     
         /**
    @@ -40,50 +41,45 @@ class modSkype extends DolibarrModules
         	global $langs,$conf;
     
             $this->db = $db;
    -        $this->numero = 3100;
    +        $this->numero = 3400;
     
     		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
     		// It is used to group modules in module setup page
             $this->family = "interface";
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
    -        $this->description = "Enable Skype links into contacts";
    +        $this->description = "Enable Social Networks fields into third parties and addresses (skype, twitter, facebook, ...)";
     		// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
             $this->version = 'dolibarr';
             // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
             $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
             // Name of image file used for this module.
    -        $this->picto='skype';
    +        $this->picto='generic';
     
             // Data directories to create when module is enabled
             $this->dirs = array();
     
             // Config pages
    -        //-------------
    -        $this->config_page_url = array();
    +        $this->config_page_url = array("socialnetworks.php");
     
    -        // Dependancies
    -        //-------------
    -	    $this->hidden = ! empty($conf->global->MODULE_SKYPE_DISABLED);	// A condition to disable module
    -	    $this->depends = array('modSociete');		// List of modules id that must be enabled if this module is enabled
    -        $this->requiredby = array();	// List of modules id to disable if this one is disabled
    -	    $this->conflictwith = array();	// List of modules id this module is in conflict with
    +        // Dependencies
    +        $this->hidden = ! empty($conf->global->MODULE_SOCIALNETWORKS_DISABLED);	// A condition to hide module
    +		$this->depends = array('modSociete');	// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->langfiles = array();
     
             // Constants
    -        //-----------
     
     
             // New pages on tabs
    -        // -----------------
             $this->tabs = array();
     
             // Boxes
    -        //------
             $this->boxes = array();
     
             // Main menu entries
    -        //------------------
             $this->menu = array();
         }
     }
    diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php
    index 9fd03cb04c7..4ee331dc017 100644
    --- a/htdocs/core/modules/modSociete.class.php
    +++ b/htdocs/core/modules/modSociete.class.php
    @@ -49,7 +49,7 @@ class modSociete extends DolibarrModules
     		$this->numero = 1;
     
     		$this->family = "crm";
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des sociétés et contacts";
    @@ -66,8 +66,11 @@ class modSociete extends DolibarrModules
     		$this->dirs = array("/societe/temp");
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array("modExpedition","modFacture","modFournisseur","modFicheinter","modPropale","modContrat","modCommande");
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array("modExpedition","modFacture","modFournisseur","modFicheinter","modPropale","modContrat","modCommande");	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("companies",'bills');
     
     		// Constants
    diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php
    index ff767dd3658..01b4e9d4474 100644
    --- a/htdocs/core/modules/modStock.class.php
    +++ b/htdocs/core/modules/modStock.class.php
    @@ -48,7 +48,7 @@ class modStock extends DolibarrModules
     		$this->numero = 52;
     
     		$this->family = "products";
    -		$this->module_position = 40;
    +		$this->module_position = '40';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des stocks";
    @@ -65,16 +65,19 @@ class modStock extends DolibarrModules
     		$this->config_page_url = array("stock.php");
     
     		// Dependencies
    -		$this->depends = array("modProduct");
    -		$this->requiredby = array("modProductBatch");
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array("modProduct");		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array("modProductBatch");	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("stocks");
     
     		// Constants
     		$this->const = array();
     		$r=0;
    -		
    +
     		$this->const[$r] = array('STOCK_ALLOW_NEGATIVE_TRANSFER','chaine','1','',1);
    -		
    +
     		$r++;
     		$this->const[$r][0] = "STOCK_ADDON_PDF";
     		$this->const[$r][1] = "chaine";
    @@ -170,7 +173,6 @@ class modStock extends DolibarrModules
     		$this->rights[9][3] = 0; 					// Permission by default for new user (0/1)
     		$this->rights[9][4] = 'inventory_advance';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
     		$this->rights[9][5] = 'changePMP';			// In php code, permission will be checked by test if ($user->rights->permkey->level1->level2)
    -
     		}
     
     		// Main menu entries
    @@ -270,7 +272,7 @@ class modStock extends DolibarrModules
     			'e.rowid'=>'IdWarehouse','e.ref'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip',
     			'e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",
     			'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation',
    -			'p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'LabelMovement',
    +			'p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'MovementLabel',
     			'sm.inventorycode'=>'InventoryCode'
     		);
     		$this->export_TypeFields_array[$r]=array(
    @@ -345,10 +347,9 @@ class modStock extends DolibarrModules
     		$this->import_run_sql_after_array[$r]=array(    // Because we may change data that are denormalized, we must update dernormalized data after.
     		    'UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid);'
     		);
    -
     	}
    -	
    -	
    +
    +
     	/**
     	 *		Function called when module is enabled.
     	 *		The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
    diff --git a/htdocs/core/modules/modStripe.class.php b/htdocs/core/modules/modStripe.class.php
    index ac11e53e733..348b44aaa1d 100644
    --- a/htdocs/core/modules/modStripe.class.php
    +++ b/htdocs/core/modules/modStripe.class.php
    @@ -65,10 +65,11 @@ class modStripe extends DolibarrModules
             // Data directories to create when module is enabled.
             $this->dirs = array();
     
    -        // Config pages. Put here list of php page names stored in admmin directory used to setup module.
    +        // Config pages. Put here list of php page names stored in admin directory used to setup module.
             $this->config_page_url = array("stripe.php@stripe");
     
             // Dependencies
    +        $this->hidden = false;			// A condition to hide module
             $this->depends = array();		// List of modules id that must be enabled if this module is enabled
             $this->requiredby = array();	// List of modules id to disable if this one is disabled
             $this->phpmin = array(5,4);					// Minimum version of PHP required by module
    @@ -130,7 +131,7 @@ class modStripe extends DolibarrModules
     			'url' => '/stripe/charge.php',
     			'langs' => 'stripe',
     			'position' => 102,
    -			'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 2',
    +			'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1',
     			'perms' => '$user->rights->banque->lire',
     			'target' => '',
     			'user' => 0
    @@ -144,7 +145,7 @@ class modStripe extends DolibarrModules
     			'url' => '/stripe/transaction.php',
     			'langs' => 'stripe',
     			'position' => 102,
    -			'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 2',
    +			'enabled' => '$conf->stripe->enabled && $conf->banque->enabled && $conf->global->MAIN_FEATURES_LEVEL >= 1',
     			'perms' => '$user->rights->banque->lire',
     			'target' => '',
     			'user' => 0
    diff --git a/htdocs/core/modules/modSupplierProposal.class.php b/htdocs/core/modules/modSupplierProposal.class.php
    index b1881f11c71..ca8f5960f03 100644
    --- a/htdocs/core/modules/modSupplierProposal.class.php
    +++ b/htdocs/core/modules/modSupplierProposal.class.php
    @@ -32,7 +32,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
     
     /**
    - *	Class to describe and enable module AskPriceSupllier
    + *	Class to describe and enable module SupplierProposal
      */
     class modSupplierProposal extends DolibarrModules
     {
    @@ -57,13 +57,19 @@ class modSupplierProposal extends DolibarrModules
     
     		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
     		$this->picto='supplier_proposal';
    -
    +        
    +		// Data directories to create when module is enabled.
     		$this->dirs = array();
    +		
    +		 // Config pages. Put here list of php page names stored in admin directory used to setup module.
    +        $this->config_page_url = array("supplier_proposal.php");
     
    -		// Dependancies
    -		$this->depends = array('modFournisseur');
    -		$this->requiredby = array();
    -		$this->config_page_url = array("supplier_proposal.php");
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array('modFournisseur');		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("supplier_proposal");
     
     		// Constants
    @@ -251,5 +257,4 @@ class modSupplierProposal extends DolibarrModules
     
     	    return $this->_remove($sql, $options);
     	}
    -
     }
    \ No newline at end of file
    diff --git a/htdocs/core/modules/modSyslog.class.php b/htdocs/core/modules/modSyslog.class.php
    index ba08d54c888..7166a787809 100644
    --- a/htdocs/core/modules/modSyslog.class.php
    +++ b/htdocs/core/modules/modSyslog.class.php
    @@ -67,8 +67,11 @@ class modSyslog extends DolibarrModules
     		$this->config_page_url = array("syslog.php");
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     
     		// Constants
     		$this->const = array();
    @@ -82,7 +85,20 @@ class modSyslog extends DolibarrModules
     
     		// Cronjobs
     		$this->cronjobs = array(
    -		    0=>array('label'=>'CompressSyslogs', 'jobtype'=>'method', 'class'=>'core/class/utils.class.php', 'objectname'=>'Utils', 'method'=>'compressSyslogs', 'parameters'=>'', 'comment'=>'Compress and archive log files. Warning: batch must be run with same account than your web server to avoid to get log files with different owner than required by web server. Another solution is to set web server Operating System group as the group of directory documents and set GROUP permission "rws" on this directory so log files will always have the group and permissions of the web server Operating System group', 'frequency'=>1, 'unitfrequency'=> 3600 * 24, 'priority'=>50, 'status'=>0, 'test'=>true),
    +		    0 => array(
    +                'label' => 'CompressSyslogs',
    +                'jobtype' => 'method',
    +                'class' => 'core/class/utils.class.php',
    +                'objectname' => 'Utils',
    +                'method' => 'compressSyslogs',
    +                'parameters' => '',
    +                'comment' => 'Compress and archive log files. Warning: batch must be run with same account than your web server to avoid to get log files with different owner than required by web server. Another solution is to set web server Operating System group as the group of directory documents and set GROUP permission "rws" on this directory so log files will always have the group and permissions of the web server Operating System group',
    +                'frequency' => 1,
    +                'unitfrequency' => 3600 * 24,
    +                'priority' => 50,
    +                'status' => 0,
    +                'test' => true,
    +            ),
     		);
     	}
     }
    diff --git a/htdocs/core/modules/modTakePos.class.php b/htdocs/core/modules/modTakePos.class.php
    new file mode 100644
    index 00000000000..4603ba74c04
    --- /dev/null
    +++ b/htdocs/core/modules/modTakePos.class.php
    @@ -0,0 +1,326 @@
    +<?php
    +/* Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018 SuperAdmin
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * 	\defgroup   takepos     Module TakePos
    + *  \brief      TakePos module descriptor.
    + *
    + *  \file       htdocs/takepos/core/modules/modTakePos.class.php
    + *  \ingroup    takepos
    + *  \brief      Description and activation file for module TakePos
    + */
    +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
    +
    +
    +/**
    + *  Class to describe and enable module TakePos
    + */
    +class modTakePos extends DolibarrModules
    +{
    +	/**
    +	 * Constructor. Define names, constants, directories, boxes, permissions
    +	 *
    +	 * @param DoliDB $db Database handler
    +	 */
    +	public function __construct($db)
    +	{
    +        global $langs,$conf;
    +
    +        $this->db = $db;
    +
    +		// Id for module (must be unique).
    +		// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
    +		$this->numero = 50150;
    +		// Key text used to identify module (for permissions, menus, etc...)
    +		$this->rights_class = 'takepos';
    +
    +		// Family can be 'crm','financial','hr','projects','products','ecm','technic','interface','other'
    +		// It is used to group modules by family in module setup page
    +		$this->family = "portal";
    +		// Module position in the family on 2 digits ('01', '10', '20', ...)
    +		$this->module_position = '90';
    +		// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
    +		//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
    +
    +		// Module label (no space allowed), used if translation string 'ModuleTakePosName' not found (MyModue is name of module).
    +		$this->name = preg_replace('/^mod/i','',get_class($this));
    +		// Module description, used if translation string 'ModuleTakePosDesc' not found (MyModue is name of module).
    +		$this->description = "Point of sales module (Touch Screen POS)";
    +		// Used only if file README.md and README-LL.md not found.
    +		$this->descriptionlong = "Point Of Sales (compliant with touch screen)";
    +
    +		// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
    +		$this->version = 'experimental';
    +		// Key used in llx_const table to save module status enabled/disabled (where TAKEPOS is value of property name of module in uppercase)
    +		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
    +		// Name of image file used for this module.
    +		// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
    +		// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
    +		$this->picto='list';
    +
    +		// Defined all module parts (triggers, login, substitutions, menus, css, etc...)
    +		// for default path (eg: /takepos/core/xxxxx) (0=disable, 1=enable)
    +		// for specific path of parts (eg: /takepos/core/modules/barcode)
    +		// for specific css file (eg: /takepos/css/takepos.css.php)
    +		$this->module_parts = array(
    +		                        	'triggers' => 0,                                 	// Set this to 1 if module has its own trigger directory (core/triggers)
    +									'login' => 0,                                    	// Set this to 1 if module has its own login method file (core/login)
    +									'substitutions' => 1,                            	// Set this to 1 if module has its own substitution function file (core/substitutions)
    +									'menus' => 0,                                    	// Set this to 1 if module has its own menus handler directory (core/menus)
    +									'theme' => 0,                                    	// Set this to 1 if module has its own theme directory (theme)
    +		                        	'tpl' => 0,                                      	// Set this to 1 if module overwrite template dir (core/tpl)
    +									'barcode' => 0,                                  	// Set this to 1 if module has its own barcode directory (core/modules/barcode)
    +									'models' => 0,                                   	// Set this to 1 if module has its own models directory (core/modules/xxx)
    +									'hooks' => array('data'=>array('invoicecard'), 'entity'=>'0') 	// Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
    +		                        );
    +
    +		// Data directories to create when module is enabled.
    +		// Example: this->dirs = array("/takepos/temp","/takepos/subdir");
    +		$this->dirs = array();
    +
    +		// Config pages. Put here list of php page, stored into takepos/admin directory, to use to setup module.
    +		$this->config_page_url = array("setup.php@takepos");
    +
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array('always'=>"modBanque", 'always'=>"modFacture", 'always'=>"modProduct", 'always'=>'modCategorie', 'FR'=>'modBlockedLog');			// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->langfiles = array("cashdesk");
    +		$this->phpmin = array(5,43);					// Minimum version of PHP required by module
    +		$this->need_dolibarr_version = array(4,0);	// Minimum version of Dolibarr required by module
    +		$this->warnings_activation = array();                     // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    +		$this->warnings_activation_ext = array();                 // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    +		//$this->automatic_activation = array('FR'=>'TakePosWasAutomaticallyActivatedBecauseOfYourCountryChoice');
    +		//$this->always_enabled = true;								// If true, can't be disabled
    +
    +		// Constants
    +		// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
    +		// Example: $this->const=array(0=>array('TAKEPOS_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
    +		//                             1=>array('TAKEPOS_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
    +		// );
    +		$this->const = array(
    +			//1=>array('TAKEPOS_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
    +		);
    +
    +
    +		if (! isset($conf->takepos) || ! isset($conf->takepos->enabled))
    +		{
    +			$conf->takepos=new stdClass();
    +			$conf->takepos->enabled=0;
    +		}
    +
    +
    +		// Array to add new pages in new tabs
    +        $this->tabs = array();
    +		// Example:
    +		// $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@takepos:$user->rights->takepos->read:/takepos/mynewtab1.php?id=__ID__');  					// To add a new tab identified by code tabname1
    +        // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@takepos:$user->rights->othermodule->read:/takepos/mynewtab2.php?id=__ID__',  	// To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
    +        // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove');                                                     										// To remove an existing tab identified by code tabname
    +        //
    +        // Where objecttype can be
    +		// 'categories_x'	  to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
    +		// 'contact'          to add a tab in contact view
    +		// 'contract'         to add a tab in contract view
    +		// 'group'            to add a tab in group view
    +		// 'intervention'     to add a tab in intervention view
    +		// 'invoice'          to add a tab in customer invoice view
    +		// 'invoice_supplier' to add a tab in supplier invoice view
    +		// 'member'           to add a tab in fundation member view
    +		// 'opensurveypoll'	  to add a tab in opensurvey poll view
    +		// 'order'            to add a tab in customer order view
    +		// 'order_supplier'   to add a tab in supplier order view
    +		// 'payment'		  to add a tab in payment view
    +		// 'payment_supplier' to add a tab in supplier payment view
    +		// 'product'          to add a tab in product view
    +		// 'propal'           to add a tab in propal view
    +		// 'project'          to add a tab in project view
    +		// 'stock'            to add a tab in stock view
    +		// 'thirdparty'       to add a tab in third party view
    +		// 'user'             to add a tab in user view
    +
    +
    +        // Dictionaries
    +		$this->dictionaries=array();
    +        /* Example:
    +        $this->dictionaries=array(
    +            'langs'=>'mylangfile@takepos',
    +            'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"),		// List of tables we want to see into dictonnary editor
    +            'tablib'=>array("Table1","Table2","Table3"),													// Label of tables
    +            'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),	// Request to select fields
    +            'tabsqlsort'=>array("label ASC","label ASC","label ASC"),																					// Sort order
    +            'tabfield'=>array("code,label","code,label","code,label"),																					// List of fields (result of select to show dictionary)
    +            'tabfieldvalue'=>array("code,label","code,label","code,label"),																				// List of fields (list of fields to edit a record)
    +            'tabfieldinsert'=>array("code,label","code,label","code,label"),																			// List of fields (list of fields for insert)
    +            'tabrowid'=>array("rowid","rowid","rowid"),																									// Name of columns with primary key (try to always name it 'rowid')
    +            'tabcond'=>array($conf->takepos->enabled,$conf->takepos->enabled,$conf->takepos->enabled)												// Condition to show each dictionary
    +        );
    +        */
    +
    +
    +        // Boxes/Widgets
    +		// Add here list of php file(s) stored in takepos/core/boxes that contains class to show a widget.
    +        $this->boxes = array(
    +        	//0=>array('file'=>'takeposwidget1.php@takepos','note'=>'Widget provided by TakePos','enabledbydefaulton'=>'Home'),
    +        	//1=>array('file'=>'takeposwidget2.php@takepos','note'=>'Widget provided by TakePos'),
    +        	//2=>array('file'=>'takeposwidget3.php@takepos','note'=>'Widget provided by TakePos')
    +        );
    +
    +
    +		// Cronjobs (List of cron jobs entries to add when module is enabled)
    +		// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
    +		$this->cronjobs = array(
    +			//0=>array('label'=>'MyJob label', 'jobtype'=>'method', 'class'=>'/takepos/class/myobject.class.php', 'objectname'=>'MyObject', 'method'=>'doScheduledJob', 'parameters'=>'', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true)
    +		);
    +		// 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'=>true),
    +		//                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
    +		// );
    +
    +
    +		// Permissions
    +		$this->rights = array();		// Permission array used by this module
    +
    +		/*$r=0;
    +		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
    +		$this->rights[$r][1] = 'Read myobject of TakePos';	// Permission label
    +		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
    +		$this->rights[$r][4] = 'read';				// In php code, permission will be checked by test if ($user->rights->takepos->level1->level2)
    +		$this->rights[$r][5] = '';				    // In php code, permission will be checked by test if ($user->rights->takepos->level1->level2)
    +
    +		$r++;
    +		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
    +		$this->rights[$r][1] = 'Create/Update myobject of TakePos';	// Permission label
    +		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
    +		$this->rights[$r][4] = 'write';				// In php code, permission will be checked by test if ($user->rights->takepos->level1->level2)
    +		$this->rights[$r][5] = '';				    // In php code, permission will be checked by test if ($user->rights->takepos->level1->level2)
    +
    +		$r++;
    +		$this->rights[$r][0] = $this->numero + $r;	// Permission id (must not be already used)
    +		$this->rights[$r][1] = 'Delete myobject of TakePos';	// Permission label
    +		$this->rights[$r][3] = 1; 					// Permission by default for new user (0/1)
    +		$this->rights[$r][4] = 'delete';				// In php code, permission will be checked by test if ($user->rights->takepos->level1->level2)
    +		$this->rights[$r][5] = '';				    // In php code, permission will be checked by test if ($user->rights->takepos->level1->level2)
    +		*/
    +
    +		// Main menu entries
    +		$this->menu = array();			// List of menus to add
    +		$r=0;
    +
    +		// Add here entries to declare new menus
    +
    +		/* BEGIN MODULEBUILDER TOPMENU */
    +		$this->menu[$r++]=array('fk_menu'=>'',			                // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
    +								'type'=>'top',			                // This is a Top menu entry
    +								'titre'=>'PointOfSale',
    +								'mainmenu'=>'takepos',
    +								'leftmenu'=>'',
    +								'url'=>'/takepos/takepos.php',
    +								'langs'=>'cashdesk',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
    +								'position'=>1000+$r,
    +								'enabled'=>'$conf->takepos->enabled',	// Define condition to show or hide menu entry. Use '$conf->takepos->enabled' if entry must be visible if module is enabled.
    +								'perms'=>'1',			                // Use 'perms'=>'$user->rights->takepos->level1->level2' if you want your menu with a permission rules
    +								'target'=>'takepos',
    +								'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
    +
    +		/* END MODULEBUILDER TOPMENU */
    +
    +		/* BEGIN MODULEBUILDER LEFTMENU MYOBJECT
    +		$this->menu[$r++]=array(	'fk_menu'=>'fk_mainmenu=takepos',	    // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
    +								'type'=>'left',			                // This is a Left menu entry
    +								'titre'=>'List MyObject',
    +								'mainmenu'=>'takepos',
    +								'leftmenu'=>'takepos_myobject_list',
    +								'url'=>'/takepos/myobject_list.php',
    +								'langs'=>'cashdesk',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
    +								'position'=>1000+$r,
    +								'enabled'=>'$conf->takepos->enabled',  // Define condition to show or hide menu entry. Use '$conf->takepos->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
    +								'perms'=>'1',			                // Use 'perms'=>'$user->rights->takepos->level1->level2' if you want your menu with a permission rules
    +								'target'=>'',
    +								'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
    +		$this->menu[$r++]=array(	'fk_menu'=>'fk_mainmenu=takepos,fk_leftmenu=takepos',	    // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
    +								'type'=>'left',			                // This is a Left menu entry
    +								'titre'=>'New MyObject',
    +								'mainmenu'=>'takepos',
    +								'leftmenu'=>'takepos_myobject_new',
    +								'url'=>'/takepos/myobject_page.php?action=create',
    +								'langs'=>'cashdesk',	        // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
    +								'position'=>1000+$r,
    +								'enabled'=>'$conf->takepos->enabled',  // Define condition to show or hide menu entry. Use '$conf->takepos->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
    +								'perms'=>'1',			                // Use 'perms'=>'$user->rights->takepos->level1->level2' if you want your menu with a permission rules
    +								'target'=>'',
    +								'user'=>2);				                // 0=Menu for internal users, 1=external users, 2=both
    +		END MODULEBUILDER LEFTMENU MYOBJECT */
    +
    +
    +		// Exports
    +		$r=1;
    +
    +		/* BEGIN MODULEBUILDER EXPORT MYOBJECT */
    +		/*
    +		$langs->load("cashdesk");
    +		$this->export_code[$r]=$this->rights_class.'_'.$r;
    +		$this->export_label[$r]='MyObjectLines';	// Translation key (used only if key ExportDataset_xxx_z not found)
    +		$this->export_icon[$r]='myobject@takepos';
    +		$keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject';
    +		include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
    +		$keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject';
    +		include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
    +		//$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
    +		$this->export_sql_start[$r]='SELECT DISTINCT ';
    +		$this->export_sql_end[$r]  =' FROM '.MAIN_DB_PREFIX.'myobject as t';
    +		$this->export_sql_end[$r] .=' WHERE 1 = 1';
    +		$this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')';
    +		$r++; */
    +		/* END MODULEBUILDER EXPORT MYOBJECT */
    +	}
    +
    +	/**
    +	 *	Function called when module is enabled.
    +	 *	The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
    +	 *	It also creates data directories
    +	 *
    +     *	@param      string	$options    Options when enabling module ('', 'noboxes')
    +	 *	@return     int             	1 if OK, 0 if KO
    +	 */
    +	public function init($options='')
    +	{
    +		$this->_load_tables('/takepos/sql/');
    +
    +		$sql = array();
    +
    +		// Remove permissions and default values
    +		$this->remove($options);
    +
    +		return $this->_init($sql, $options);
    +	}
    +
    +	/**
    +	 *	Function called when module is disabled.
    +	 *	Remove from database constants, boxes and permissions from Dolibarr database.
    +	 *	Data directories are not deleted
    +	 *
    +	 *	@param      string	$options    Options when enabling module ('', 'noboxes')
    +	 *	@return     int             	1 if OK, 0 if KO
    +	 */
    +	public function remove($options = '')
    +	{
    +		$sql = array();
    +
    +		return $this->_remove($sql, $options);
    +	}
    +}
    diff --git a/htdocs/core/modules/modTax.class.php b/htdocs/core/modules/modTax.class.php
    index f3fa7d4e9db..7dacae51b67 100644
    --- a/htdocs/core/modules/modTax.class.php
    +++ b/htdocs/core/modules/modTax.class.php
    @@ -67,9 +67,11 @@ class modTax extends DolibarrModules
     		$this->config_page_url = array("taxes.php");
     
     		// Dependencies
    -		$this->depends = array();
    -		$this->requiredby = array();
    -		$this->conflictwith = array();
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("compta","bills");
     
     		// Constants
    @@ -117,13 +119,10 @@ class modTax extends DolibarrModules
     
     
     		// Menus
    -		//-------
    -
     		$this->menu = 1;        // This module add menu entries. They are coded into menu manager.
     
     
     		// Exports
    -		//--------
     		$r=0;
     
     		$r++;
    @@ -175,7 +174,6 @@ class modTax extends DolibarrModules
     		$this->import_examplevalues_array[$r]=array('t.label'=>"VAT Payment 1st quarter 2016",'t.fk_typepayment'=>"CHQ (must be id or code found into dictionary)",
     		    't.datep'=>"2016-04-02", 't.datev'=>"2016-03-31", 't.amount'=>1000, 't.num_payment'=>'123456'
     		);
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php
    index 01c10a631ca..79e4d015a5e 100644
    --- a/htdocs/core/modules/modTicket.class.php
    +++ b/htdocs/core/modules/modTicket.class.php
    @@ -55,7 +55,7 @@ class modTicket extends DolibarrModules
             // It is used to group modules in module setup page
             $this->family = "crm";
             // Module position in the family
    -        $this->module_position = 500;
    +        $this->module_position = '60';
             // Module label (no space allowed)
             // used if translation string 'ModuleXXXName' not found
             // (where XXX is value of numeric property 'numero' of module)
    @@ -95,12 +95,11 @@ class modTicket extends DolibarrModules
             $this->config_page_url = array("ticket.php");
     
             // Dependencies
    -        // List of modules id that must be enabled if this module is enabled
    -        $this->depends = array();
    -        // List of modules id to disable if this one is disabled
    -        $this->requiredby = array();
    -        // Minimum version of PHP required by module
    -        $this->phpmin = array(5, 3);
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->langfiles = array("ticket");
             // Constants
             // List of particular constants to add when module is enabled
    @@ -115,7 +114,7 @@ class modTicket extends DolibarrModules
                 'project:+ticket:Tickets:@ticket:$user->rights->ticket->read:/ticket/list.php?projectid=__ID__',
             );
     
    -        // Dictionnaries
    +        // Dictionaries
             if (! isset($conf->ticket->enabled)) {
                 $conf->ticket=new stdClass();
                 $conf->ticket->enabled=0;
    @@ -306,5 +305,4 @@ class modTicket extends DolibarrModules
     
             return $this->_init($sql, $options);
         }
    -
     }
    diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php
    index 1c4a08411ad..12961438b24 100644
    --- a/htdocs/core/modules/modUser.class.php
    +++ b/htdocs/core/modules/modUser.class.php
    @@ -46,7 +46,7 @@ class modUser extends DolibarrModules
     		$this->numero = 0;
     
     		$this->family = "hr";		// Family for module (or "base" if core module)
    -		$this->module_position = 10;
    +		$this->module_position = '10';
     		// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
     		$this->name = preg_replace('/^mod/i','',get_class($this));
     		$this->description = "Gestion des utilisateurs (requis)";
    @@ -63,9 +63,12 @@ class modUser extends DolibarrModules
     		// Config pages
     		$this->config_page_url = array("user.php");
     
    -		// Dependancies
    -		$this->depends = array();
    -		$this->requiredby = array();
    +		// Dependencies
    +		$this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->langfiles = array("main","users","companies","members",'salaries');
     		$this->always_enabled = true;	// Can't be disabled
     
    @@ -205,13 +208,10 @@ class modUser extends DolibarrModules
     
     
             // Menus
    -        //-------
    -
             $this->menu = 1;        // This module add menu entries. They are coded into menu manager.
     
     
     		// Exports
    -		//--------
     		$r=0;
     
     		$r++;
    @@ -244,7 +244,6 @@ class modUser extends DolibarrModules
     		$this->export_sql_end[$r] .=' WHERE u.entity IN ('.getEntity('user').')';
     
     		// Imports
    -		//--------
     		$r=0;
     
     		// Import list of users attributes
    @@ -292,7 +291,6 @@ class modUser extends DolibarrModules
     			'u.email'=>"test@mycompany.com",'u.salary'=>"10000",'u.note'=>"This is an example of note for record",'u.datec'=>"2015-01-01 or 2015-01-01 12:30:00"
     		);
     		$this->import_updatekeys_array[$r]=array('u.lastname'=>'Lastname','u.firstname'=>'Firstname','u.login'=>'Login');
    -
     	}
     
     
    diff --git a/htdocs/core/modules/modVariants.class.php b/htdocs/core/modules/modVariants.class.php
    index c56f5c0e49a..faac67da78c 100644
    --- a/htdocs/core/modules/modVariants.class.php
    +++ b/htdocs/core/modules/modVariants.class.php
    @@ -22,9 +22,8 @@
     /**
      * 	\defgroup   produit     Module product variants
      *  \brief      Module to manage product combinations based on product attributes
    - *  \file       htdocs/core/modules/modAttributes.class.php
    + *  \file       htdocs/core/modules/modVariants.class.php
      *  \ingroup    produit
    - *  \brief      File to describe module to manage catalog of predefined products
      */
     include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
    @@ -79,12 +78,10 @@ class modVariants extends DolibarrModules
     
     		// Dependencies
     		$this->hidden = false;			// A condition to hide module
    -		$this->depends = array(
    -			'modProduct'
    -		);		// List of modules id that must be enabled if this module is enabled
    -		$this->requiredby = array();	// List of modules id to disable if this one is disabled
    -		$this->conflictwith = array();	// List of modules id this module is in conflict with
    -		$this->phpmin = array(5,0);					// Minimum version of PHP required by module
    +		$this->depends = array('modProduct');	// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(3,0);	// Minimum version of Dolibarr required by module
     		$this->langfiles = array("products");
     
    @@ -112,4 +109,3 @@ class modVariants extends DolibarrModules
     		$this->rights = array();		// Permission array used by this module
     	}
     }
    -
    diff --git a/htdocs/core/modules/modWebServices.class.php b/htdocs/core/modules/modWebServices.class.php
    index 8963f81813f..a3e9510563f 100644
    --- a/htdocs/core/modules/modWebServices.class.php
    +++ b/htdocs/core/modules/modWebServices.class.php
    @@ -55,30 +55,26 @@ class modWebServices extends DolibarrModules
             $this->dirs = array();
     
             // Config pages
    -        //-------------
             $this->config_page_url = array("index.php@webservices");
     
    -        // Dependancies
    -        //-------------
    -        $this->depends = array();
    -        $this->requiredby = array();
    -        //$this->phpmax = array(7,1);					// Maximum version of PHP required by module
    +        // Dependencies
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->langfiles = array("other");
     
             // Constants
    -        //-----------
             $this->const = array();
     
             // New pages on tabs
    -        // -----------------
             $this->tabs = array();
     
             // Boxes
    -        //------
             $this->boxes = array();
     
             // Permissions
    -        //------------
             $this->rights = array();
             $this->rights_class = 'webservices';
             $r=0;
    diff --git a/htdocs/core/modules/modWebServicesClient.class.php b/htdocs/core/modules/modWebServicesClient.class.php
    index 9b6535143b3..35c4da5b037 100644
    --- a/htdocs/core/modules/modWebServicesClient.class.php
    +++ b/htdocs/core/modules/modWebServicesClient.class.php
    @@ -55,29 +55,26 @@ class modWebServicesClient extends DolibarrModules
             $this->dirs = array();
     
             // Config pages
    -        //-------------
             //$this->config_page_url = array();
     
    -        // Dependancies
    -        //-------------
    -        $this->depends = array();
    -        $this->requiredby = array();
    +        // Dependencies
    +        $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->langfiles = array("other");
     
             // Constants
    -        //-----------
             $this->const = array();
     
             // New pages on tabs
    -        // -----------------
             $this->tabs = array();
     
             // Boxes
    -        //------
             $this->boxes = array();
     
             // Permissions
    -        //------------
             $this->rights = array();
             $this->rights_class = 'syncsupplierwebservices';
             $r=0;
    diff --git a/htdocs/core/modules/modWebsite.class.php b/htdocs/core/modules/modWebsite.class.php
    index fb6e91283db..3402f9ddfdc 100644
    --- a/htdocs/core/modules/modWebsite.class.php
    +++ b/htdocs/core/modules/modWebsite.class.php
    @@ -46,12 +46,12 @@ class modWebsite extends DolibarrModules
     		// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
     		// It is used to group modules in module setup page
             $this->family = "portal";
    -        $this->module_position = 50;
    +        $this->module_position = '50';
             // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
             $this->name = preg_replace('/^mod/i','',get_class($this));
             $this->description = "Enable to build and serve public web sites with CMS features";
     		// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
    -        $this->version = 'experimental';
    +        $this->version = 'dolibarr';
             // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
             $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
             // Name of image file used for this module.
    @@ -61,27 +61,23 @@ class modWebsite extends DolibarrModules
     		$this->dirs = array("/website/temp");
     
             // Config pages
    -        //-------------
             $this->config_page_url = array('website.php');
     
    -        // Dependancies
    -        //-------------
    +        // Dependencies
     		$this->hidden = ! empty($conf->global->MODULE_WEBSITE_DISABLED);	// A condition to disable module
     		$this->depends = array('modFckeditor');		// List of modules id that must be enabled if this module is enabled
             $this->requiredby = array();	// List of modules id to disable if this one is disabled
     		$this->conflictwith = array();	// List of modules id this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->langfiles = array("website");
     
             // Constants
    -        //-----------
            	$this->const = array();
     
             // New pages on tabs
    -        // -----------------
            	//$this->tabs[] = array();  					// To add a new tab identified by code tabname1
     
             // Boxes
    -        //------
             $this->boxes = array();
     
     		// Permissions
    @@ -139,4 +135,46 @@ class modWebsite extends DolibarrModules
             $this->export_sql_end[$r] .=' AND p.entity IN ('.getEntity('website').')';
             $r++;
         }
    +
    +
    +    /**
    +     *		Function called when module is enabled.
    +     *		The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
    +     *		It also creates data directories
    +     *
    +     *      @param      string	$options    Options when enabling module ('', 'noboxes')
    +     *      @return     int             	1 if OK, 0 if KO
    +     */
    +    function init($options='')
    +    {
    +    	global $conf,$langs;
    +
    +    	// Remove permissions and default values
    +    	$this->remove($options);
    +
    +    	// Copy flags and octicons directoru
    +    	$dirarray=array('common/flags', 'common/octicons');
    +    	foreach($dirarray as $dir)
    +    	{
    +	    	$src=DOL_DOCUMENT_ROOT.'/theme/'.$dir;
    +	    	$dest=DOL_DATA_ROOT.'/medias/image/'.$dir;
    +
    +	    	if (is_dir($src))
    +	    	{
    +	    		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    +	    		dol_mkdir($dest);
    +	    		$result=dolCopyDir($src,$dest,0,0);
    +	    		if ($result < 0)
    +	    		{
    +	    			$langs->load("errors");
    +	    			$this->error=$langs->trans('ErrorFailToCopyDirectory',$src,$dest);
    +	    			return 0;
    +	    		}
    +	    	}
    +    	}
    +
    +    	$sql = array();
    +
    +    	return $this->_init($sql, $options);
    +    }
     }
    diff --git a/htdocs/core/modules/modWorkflow.class.php b/htdocs/core/modules/modWorkflow.class.php
    index e721513073a..882e8aebf53 100644
    --- a/htdocs/core/modules/modWorkflow.class.php
    +++ b/htdocs/core/modules/modWorkflow.class.php
    @@ -68,9 +68,11 @@ class modWorkflow extends DolibarrModules
             $this->config_page_url = array('workflow.php');
     
             // Dependencies
    -        $this->depends = array();       // List of modules id that must be enabled if this module is enabled
    -        $this->requiredby = array();    // List of modules id to disable if this one is disabled
    -        $this->phpmin = array(5,2);                 // Minimum version of PHP required by module
    +       $this->hidden = false;			// A condition to hide module
    +		$this->depends = array();		// List of module class names as string that must be enabled if this module is enabled
    +		$this->requiredby = array();	// List of module ids to disable if this one is disabled
    +		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
    +		$this->phpmin = array(5,4);		// Minimum version of PHP required by module
             $this->need_dolibarr_version = array(2,8);  // Minimum version of Dolibarr required by module
             $this->langfiles = array("@workflow");
     
    diff --git a/htdocs/core/modules/payment/mod_payment_ant.php b/htdocs/core/modules/payment/mod_payment_ant.php
    index a09ad2355e4..b7d88464355 100644
    --- a/htdocs/core/modules/payment/mod_payment_ant.php
    +++ b/htdocs/core/modules/payment/mod_payment_ant.php
    @@ -30,9 +30,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/payment/modules_payment.php';
      */
     class mod_payment_ant extends ModeleNumRefPayments
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Ant';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +	 * @var string Error message
    +	 */
    +	public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Ant';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Ant';
     
     
         /**
    @@ -42,7 +61,7 @@ class mod_payment_ant extends ModeleNumRefPayments
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -124,6 +143,7 @@ class mod_payment_ant extends ModeleNumRefPayments
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -133,8 +153,7 @@ class mod_payment_ant extends ModeleNumRefPayments
          */
         function commande_get_num($objsoc,$objforref)
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/payment/mod_payment_cicada.php b/htdocs/core/modules/payment/mod_payment_cicada.php
    index 8fc05b6cdd8..5869032cc5b 100644
    --- a/htdocs/core/modules/payment/mod_payment_cicada.php
    +++ b/htdocs/core/modules/payment/mod_payment_cicada.php
    @@ -29,10 +29,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/payment/modules_payment.php';
      */
     class mod_payment_cicada extends ModeleNumRefPayments
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='PAY';
    -	var $error='';
    -	var $nom='Cicada';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='PAY';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Cicada';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Cicada';
     
     
         /**
    @@ -135,16 +155,17 @@ class mod_payment_cicada extends ModeleNumRefPayments
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
     	 *  @param	Societe		$objsoc     Object third party
    -	 * 	@param	string		$objforref	Object for number to search
    +	 *  @param	string		$objforref	Object for number to search
     	 *  @return string      			Next free value
     	 */
     	function payment_get_num($objsoc,$objforref)
     	{
    +        // phpcs:enable
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/payment/modules_payment.php b/htdocs/core/modules/payment/modules_payment.php
    index c9023a9fc65..d9cf9b1260f 100644
    --- a/htdocs/core/modules/payment/modules_payment.php
    +++ b/htdocs/core/modules/payment/modules_payment.php
    @@ -23,7 +23,10 @@
     
     abstract class ModeleNumRefPayments
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Return if a module can be used or not
    diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php
    index 4a6560b47fa..afd46919598 100644
    --- a/htdocs/core/modules/printing/modules_printing.php
    +++ b/htdocs/core/modules/printing/modules_printing.php
    @@ -1,6 +1,6 @@
     <?php
     /*
    - * Copyright (C) 2014-2015 Frederic France      <frederic.france@free.fr>
    + * Copyright (C) 2014-2018 Frederic France      <frederic.france@netlogic.fr>
      *
      * 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
    @@ -31,8 +31,15 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
      */
     class PrintingDriver
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**
    @@ -81,6 +88,4 @@ class PrintingDriver
             if ($langs->trans($transstring) != $transstring) return $langs->trans($transstring);
             else return $this->desc;
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php
    index 7cda95174c2..089fb95ba69 100644
    --- a/htdocs/core/modules/printing/printgcp.modules.php
    +++ b/htdocs/core/modules/printing/printgcp.modules.php
    @@ -1,6 +1,6 @@
     <?php
     /*
    - * Copyright (C) 2014-2015  Frederic France      <frederic.france@free.fr>
    + * Copyright (C) 2014-2018  Frederic France      <frederic.france@netlogic.fr>
      *
      * 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
    @@ -35,16 +35,28 @@ use OAuth\OAuth2\Service\Google;
      */
     class printing_printgcp extends PrintingDriver
     {
    -    var $name = 'printgcp';
    -    var $desc = 'PrintGCPDesc';
    -    var $picto = 'printer';
    -    var $active = 'PRINTING_PRINTGCP';
    -    var $conf = array();
    -    var $google_id = '';
    -    var $google_secret = '';
    -    var $error;
    -    var $errors = array();
    -    var $db;
    +    public $name = 'printgcp';
    +    public $desc = 'PrintGCPDesc';
    +    public $picto = 'printer';
    +    public $active = 'PRINTING_PRINTGCP';
    +    public $conf = array();
    +    public $google_id = '';
    +    public $google_secret = '';
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +    /**
    +     * @var string[] Error codes (or messages)
    +     */
    +    public $errors = array();
    +
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
         private $OAUTH_SERVICENAME_GOOGLE = 'Google';
     
    @@ -63,8 +75,8 @@ class printing_printgcp extends PrintingDriver
             global $conf, $langs, $dolibarr_main_url_root;
     
             // Define $urlwithroot
    -        $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
    -        $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
    +        $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
    +        $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
             //$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
     
             $this->db = $db;
    @@ -73,7 +85,7 @@ class printing_printgcp extends PrintingDriver
                 $this->conf[] = array(
                     'varname'=>'PRINTGCP_INFO',
                     'info'=>$langs->transnoentitiesnoconv("WarningModuleNotActive", "OAuth"),
    -                'type'=>'info'
    +                'type'=>'info',
                 );
             } else {
     
    @@ -132,7 +144,7 @@ class printing_printgcp extends PrintingDriver
     
                         $refreshtoken = $token->getRefreshToken();
     
    -                    $endoflife=$token->getEndOfLife();
    +                    $endoflife = $token->getEndOfLife();
     
                         if ($endoflife == $token::EOL_NEVER_EXPIRES)
                         {
    @@ -171,9 +183,9 @@ class printing_printgcp extends PrintingDriver
          *
          *  @return  int                     0 if OK, >0 if KO
          */
    -    function listAvailablePrinters()
    +    public function listAvailablePrinters()
         {
    -        global $bc, $conf, $langs;
    +        global $conf, $langs;
             $error = 0;
             $langs->load('printing');
     
    @@ -187,7 +199,7 @@ class printing_printgcp extends PrintingDriver
             $html.= '<td>'.$langs->trans('GCP_Type').'</td>';
             $html.= '<td align="center">'.$langs->trans("Select").'</td>';
             $html.= '</tr>'."\n";
    -        $list = $this->getlist_available_printers();
    +        $list = $this->getlistAvailablePrinters();
             //$html.= '<td><pre>'.print_r($list,true).'</pre></td>';
             foreach ($list['available'] as $printer_det)
             {
    @@ -220,7 +232,7 @@ class printing_printgcp extends PrintingDriver
          *
          *  @return array      list of printers
          */
    -    function getlist_available_printers()
    +    public function getlistAvailablePrinters()
         {
             // Token storage
             $storage = new DoliStorage($this->db, $this->conf);
    @@ -287,15 +299,17 @@ class printing_printgcp extends PrintingDriver
          * @param   string      $subdir     subdir for file
          * @return  int                     0 if OK, >0 if KO
          */
    -    function print_file($file, $module, $subdir='')
    +    public function printFile($file, $module, $subdir='')
         {
             require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
             global $conf, $user;
             $error = 0;
     
    -        $fileprint=$conf->{$module}->dir_output;
    -        if ($subdir!='') $fileprint.='/'.$subdir;
    +        $fileprint = $conf->{$module}->dir_output;
    +        if ($subdir!='') {
    +            $fileprint.='/'.$subdir;
    +        }
             $fileprint.='/'.$file;
             $mimetype = dol_mimetype($fileprint);
             // select printer uri for module order, propal,...
    @@ -326,7 +340,9 @@ class printing_printgcp extends PrintingDriver
     
             $ret = $this->sendPrintToPrinter($printer_id, $file, $fileprint, $mimetype);
             $this->error = 'PRINTGCP: '.$ret['errormessage'];
    -        if ($ret['status']!=1) $error++;
    +        if ($ret['status']!=1) {
    +            $error++;
    +        }
             return $error;
         }
     
    @@ -354,12 +370,13 @@ class printing_printgcp extends PrintingDriver
             $contents = fread($handle, filesize($filepath));
             fclose($handle);
             // Prepare post fields for sending print
    -        $post_fields = array('printerid' => $printerid,
    -                             'title' => $printjobtitle,
    -                             'contentTransferEncoding' => 'base64',
    -                             'content' => base64_encode($contents), // encode file content as base64
    -                             'contentType' => $contenttype
    -                            );
    +        $post_fields = array(
    +            'printerid' => $printerid,
    +            'title' => $printjobtitle,
    +            'contentTransferEncoding' => 'base64',
    +            'content' => base64_encode($contents), // encode file content as base64
    +            'contentType' => $contenttype,
    +        );
             // Dolibarr Token storage
             $storage = new DoliStorage($this->db, $this->conf);
             // Setup the credentials for the requests
    @@ -394,7 +411,7 @@ class printing_printgcp extends PrintingDriver
             // Send a request with api
             $response = json_decode($apiService->request(self::PRINT_URL, 'POST', $post_fields), true);
             //print '<tr><td><pre>'.print_r($response, true).'</pre></td></tr>';
    -        return array('status' =>$response['success'],'errorcode' =>$response['errorCode'],'errormessage'=>$response['message']);
    +        return array('status' => $response['success'], 'errorcode' => $response['errorCode'], 'errormessage' => $response['message']);
         }
     
     
    @@ -403,9 +420,9 @@ class printing_printgcp extends PrintingDriver
          *
          *  @return  int                     0 if OK, >0 if KO
          */
    -    function list_jobs()
    +    public function listJobs()
         {
    -        global $conf, $db, $langs, $bc;
    +        global $conf, $langs;
     
             $error = 0;
             $html = '';
    @@ -471,13 +488,11 @@ class printing_printgcp extends PrintingDriver
     
             $jobs = $responsedata['jobs'];
             //$html .= '<pre>'.print_r($jobs['0'],true).'</pre>';
    -        if (is_array($jobs))
    -        {
    -            foreach ($jobs as $value)
    -            {
    +        if (is_array($jobs)) {
    +            foreach ($jobs as $value) {
                     $html .= '<tr class="oddeven">';
                     $html .= '<td>'.$value['id'].'</td>';
    -                $dates=dol_print_date((int) substr($value['createTime'], 0, 10), 'dayhour');
    +                $dates = dol_print_date((int) substr($value['createTime'], 0, 10), 'dayhour');
                     $html .= '<td>'.$dates.'</td>';
                     $html .= '<td>'.$value['ownerId'].'</td>';
                     $html .= '<td>'.$value['printerName'].'</td>';
    @@ -500,5 +515,4 @@ class printing_printgcp extends PrintingDriver
     
             return $error;
         }
    -
     }
    diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php
    index 94d14426b55..ab65f8fba3d 100644
    --- a/htdocs/core/modules/printing/printipp.modules.php
    +++ b/htdocs/core/modules/printing/printipp.modules.php
    @@ -1,6 +1,6 @@
     <?php
     /*
    - * Copyright (C) 2014-2015  Frederic France      <frederic.france@free.fr>
    + * Copyright (C) 2014-2018  Frederic France      <frederic.france@netlogic.fr>
      *
      * 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
    @@ -19,7 +19,7 @@
     
     /**
      *      \file       htdocs/core/modules/printing/printipp.modules.php
    - *      \ingroup    mailing
    + *      \ingroup    printing
      *      \brief      File to provide printing with PrintIPP
      */
     
    @@ -30,19 +30,31 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php';
      */
     class printing_printipp extends PrintingDriver
     {
    -    var $name='printipp';
    -    var $desc='PrintIPPDesc';
    -    var $picto='printer';
    -    var $active='PRINTING_PRINTIPP';
    -    var $conf=array();
    -    var $host;
    -    var $port;
    -    var $userid;    /* user login */
    -    var $user;
    -    var $password;
    -    var $error;
    -    var $errors = array();
    -    var $db;
    +    public $name = 'printipp';
    +    public $desc = 'PrintIPPDesc';
    +    public $picto = 'printer';
    +    public $active = 'PRINTING_PRINTIPP';
    +    public $conf = array();
    +    public $host;
    +    public $port;
    +    public $userid;    /* user login */
    +    public $user;
    +    public $password;
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error='';
    +
    +    /**
    +     * @var string[] Error codes (or messages)
    +     */
    +    public $errors = array();
    +
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
         /**
    @@ -75,7 +87,7 @@ class printing_printipp extends PrintingDriver
          *
          * @return  int                     0 if OK, >0 if KO
          */
    -    function print_file($file, $module, $subdir='')
    +    public function printFile($file, $module, $subdir='')
         {
             global $conf, $user;
             $error = 0;
    @@ -93,8 +105,7 @@ class printing_printipp extends PrintingDriver
             // select printer uri for module order, propal,...
             $sql = "SELECT rowid,printer_id,copy FROM ".MAIN_DB_PREFIX."printing WHERE module = '".$module."' AND driver = 'printipp' AND userid = ".$user->id;
             $result = $this->db->query($sql);
    -        if ($result)
    -        {
    +        if ($result) {
                 $obj = $this->db->fetch_object($result);
                 if ($obj)
                 {
    @@ -105,18 +116,19 @@ class printing_printipp extends PrintingDriver
                 {
                     if (! empty($conf->global->PRINTIPP_URI_DEFAULT))
                     {
    -					dol_syslog("Will use default printer conf->global->PRINTIPP_URI_DEFAULT = ".$conf->global->PRINTIPP_URI_DEFAULT);
    +                    dol_syslog("Will use default printer conf->global->PRINTIPP_URI_DEFAULT = ".$conf->global->PRINTIPP_URI_DEFAULT);
                         $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT);
                     }
                     else
    -				{
    +                {
                         $this->errors[] = 'NoDefaultPrinterDefined';
                         $error++;
                         return $error;
                     }
                 }
    +        } else {
    +            dol_print_error($this->db);
             }
    -        else dol_print_error($this->db);
     
             // Set number of copy
             $ipp->setCopies($obj->copy);
    @@ -142,7 +154,7 @@ class printing_printipp extends PrintingDriver
          */
         function listAvailablePrinters()
         {
    -        global $bc, $conf, $langs;
    +        global $conf, $langs;
             $error = 0;
     
             $html = '<tr class="liste_titre">';
    @@ -158,11 +170,9 @@ class printing_printipp extends PrintingDriver
             $html.= '<td>'.$langs->trans('IPP_Supported').'</td>';
             $html.= '<td align="center">'.$langs->trans("Select").'</td>';
             $html.= "</tr>\n";
    -        $list = $this->getlist_available_printers();
    -        foreach ($list as $value)
    -        {
    -
    -            $printer_det = $this->get_printer_detail($value);
    +        $list = $this->getlistAvailablePrinters();
    +        foreach ($list as $value) {
    +            $printer_det = $this->getPrinterDetail($value);
                 $html.= '<tr class="oddeven">';
                 $html.= '<td>'.$value.'</td>';
                 //$html.= '<td><pre>'.print_r($printer_det,true).'</pre></td>';
    @@ -177,15 +187,12 @@ class printing_printipp extends PrintingDriver
                 $html.= '<td>'.$langs->trans('MEDIA_IPP_'.$printer_det->media_type_supported->_value1).'</td>';
                 // Defaut
                 $html.= '<td align="center">';
    -            if ($conf->global->PRINTIPP_URI_DEFAULT == $value)
    -            {
    +            if ($conf->global->PRINTIPP_URI_DEFAULT == $value) {
                     $html.= img_picto($langs->trans("Default"),'on');
    +            } else {
    +                $html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&amp;mode=test&amp;varname=PRINTIPP_URI_DEFAULT&amp;driver=printipp&amp;value='.urlencode($value).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
                 }
    -            else
    -			{
    -            	$html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&amp;mode=test&amp;varname=PRINTIPP_URI_DEFAULT&amp;driver=printipp&amp;value='.urlencode($value).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>';
    -          	}
    -			$html.= '</td>';
    +            $html.= '</td>';
                 $html.= '</tr>'."\n";
             }
             $this->resprint = $html;
    @@ -197,16 +204,18 @@ class printing_printipp extends PrintingDriver
          *
          *  @return array                list of printers
          */
    -    function getlist_available_printers()
    +    public function getlistAvailablePrinters()
         {
    -        global $conf,$db;
    +        global $conf, $db;
             include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
             $ipp = new CupsPrintIPP();
             $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose
             $ipp->setHost($this->host);
             $ipp->setPort($this->port);
             $ipp->setUserName($this->userid);
    -        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
    +        if (! empty($this->user)) {
    +            $ipp->setAuthentication($this->user, $this->password);
    +        }
             $ipp->getPrinters();
             return $ipp->available_printers;
         }
    @@ -217,7 +226,7 @@ class printing_printipp extends PrintingDriver
          *  @param  string  $uri    URI
          *  @return array           List of attributes
          */
    -    function get_printer_detail($uri)
    +    private function getPrinterDetail($uri)
         {
             global $conf,$db;
     
    @@ -227,7 +236,9 @@ class printing_printipp extends PrintingDriver
             $ipp->setHost($this->host);
             $ipp->setPort($this->port);
             $ipp->setUserName($this->userid);
    -        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
    +        if (! empty($this->user)) {
    +            $ipp->setAuthentication($this->user, $this->password);
    +        }
             $ipp->setPrinterURI($uri);
             $ipp->getPrinterAttributes();
             return $ipp->printer_attributes;
    @@ -240,9 +251,9 @@ class printing_printipp extends PrintingDriver
          *
          *  @return  int                     0 if OK, >0 if KO
          */
    -    function list_jobs($module)
    +    public function listJobs($module)
         {
    -        global $conf, $db, $bc;
    +        global $conf;
             $error = 0;
             $html = '';
             include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
    @@ -251,19 +262,17 @@ class printing_printipp extends PrintingDriver
             $ipp->setHost($this->host);
             $ipp->setPort($this->port);
             $ipp->setUserName($this->userid);
    -        if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password);
    +        if (! empty($this->user)) {
    +            $ipp->setAuthentication($this->user,$this->password);
    +        }
             // select printer uri for module order, propal,...
             $sql = 'SELECT rowid,printer_uri,printer_name FROM '.MAIN_DB_PREFIX.'printer_ipp WHERE module="'.$module.'"';
             $result = $this->db->query($sql);
    -        if ($result)
    -        {
    +        if ($result) {
                 $obj = $this->db->fetch_object($result);
    -            if ($obj)
    -            {
    +            if ($obj) {
                     $ipp->setPrinterURI($obj->printer_uri);
    -            }
    -            else
    -            {
    +            } else {
                     // All printers
                     $ipp->setPrinterURI("ipp://localhost:631/printers/");
                 }
    @@ -287,8 +296,7 @@ class printing_printipp extends PrintingDriver
             $jobs = $ipp->jobs_attributes;
     
             //$html .= '<pre>'.print_r($jobs,true).'</pre>';
    -        foreach ($jobs as $value )
    -        {
    +        foreach ($jobs as $value ) {
                 $html .= '<tr class="oddeven">';
                 $html .= '<td>'.$value->job_id->_value0.'</td>';
                 $html .= '<td>'.$value->job_originating_user_name->_value0.'</td>';
    @@ -302,5 +310,4 @@ class printing_printipp extends PrintingDriver
             $this->resprint = $html;
             return $error;
         }
    -
     }
    diff --git a/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php b/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php
    index 78898735f0c..0047dda7669 100644
    --- a/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php
    +++ b/htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php
    @@ -1,10 +1,10 @@
     <?php
    -/* Copyright (C) 2003 Steve Dillon
    - * Copyright (C) 2003 Laurent Passebecq
    - * Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2002-2003 Jean-Louis Bergamo	<jlb@j1b.org>
    - * Copyright (C) 2006-2013 Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2015 Francis Appels  <francis.appels@yahoo.com>
    +/* Copyright (C) 2003       Steve Dillon
    + * Copyright (C) 2003       Laurent Passebecq
    + * Copyright (C) 2001-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
    + * Copyright (C) 2006-2013  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2015       Francis Appels          <francis.appels@yahoo.com>
      *
      * 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
    @@ -21,15 +21,15 @@
      */
     
     /**
    - *	\file		htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php
    - *	\ingroup	core
    - *	\brief		Fichier de la classe permettant d'editer au format PDF des etiquettes au format Avery ou personnalise
    + *  \file       htdocs/core/modules/printsheet/doc/pdf_standardlabel.class.php
    + *  \ingroup    core
    + *  \brief      Fichier de la classe permettant d'editer au format PDF des etiquettes au format Avery ou personnalise
      */
     
     require_once DOL_DOCUMENT_ROOT.'/core/class/commonstickergenerator.class.php';
     
     /**
    - *	Class to generate stick sheet with format Avery or other personalised
    + *  Class to generate stick sheet with format Avery or other personalised
      */
     class pdf_standardlabel extends CommonStickerGenerator
     {
    @@ -41,10 +41,12 @@ class pdf_standardlabel extends CommonStickerGenerator
     	 * @param	array		$param			Associative array containing label content and optional parameters
     	 * @return	void
     	 */
    -	function addSticker(&$pdf,$outputlangs,$param) {
    +    function addSticker(&$pdf,$outputlangs,$param)
    +    {
     		// use this method in future refactoring
     	}
    -	
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0)
     	 * - %LOGO% is replace with company logo
    @@ -61,6 +63,7 @@ class pdf_standardlabel extends CommonStickerGenerator
     	 */
     	function Add_PDF_label(&$pdf,$textleft,$header,$footer,$outputlangs,$textright='',$photo='')
     	{
    +        // phpcs:enable
     		global $mysoc, $conf, $langs;
     		global $forceimgscalewidth, $forceimgscaleheight;
     
    @@ -224,6 +227,7 @@ class pdf_standardlabel extends CommonStickerGenerator
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build PDF on disk, then output on HTTP strem.
     	 *
    @@ -236,6 +240,7 @@ class pdf_standardlabel extends CommonStickerGenerator
     	 */
     	function write_file($arrayofrecords,$outputlangs,$srctemplatepath,$outputdir='',$filename='tmp_address_sheet.pdf')
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$mysoc,$_Avery_Labels;
     
     		$this->code=$srctemplatepath;
    @@ -255,10 +260,8 @@ class pdf_standardlabel extends CommonStickerGenerator
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("admin");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "admin"));
     
     		$title=$outputlangs->transnoentities('Labels');
     		$keywords=$title." ".$outputlangs->convToOutputCharset($mysoc->name);
    diff --git a/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php b/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php
    index faa62d45431..de1aa1b5d5e 100644
    --- a/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php
    +++ b/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php
    @@ -50,7 +50,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     					'fontsize' => 8,
     					'stretchtext' => 4
     	);
    -	
    +
     	// set style for 2d barcode
     	private $_style2d = array(
     					'border' => false,
    @@ -61,24 +61,25 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     					'module_width' => 1, // width of a single module in points
     					'module_height' => 1 // height of a single module in points
     	);
    -	
    +
     	private $_align2d = 'N';
    -	
    +
     	private $_xres = 0.4;
    -	
    +
     	/**
     	 * write barcode to pdf
    -	 * 
    +	 *
     	 * @param PDF	  $pdf		  PDF reference
     	 * @param string  $code		   code to print
     	 * @param string  $encoding	   type of barcode
     	 * @param boolean $is2d		   true if 2d barcode
    -	 * @param int	  $x		   x position in user units 
    +	 * @param int	  $x		   x position in user units
     	 * @param int	  $y		   y position in user units
     	 * @param int	  $w		   width in user units
     	 * @param int	  $h		   height in user units
    -	 */	   
    -	private function writeBarcode(&$pdf, $code, $encoding, $is2d, $x, $y, $w, $h) 
    +	 * @return void
    +	 */
    +	private function writeBarcode(&$pdf, $code, $encoding, $is2d, $x, $y, $w, $h)
     	{
     		if ($is2d) {
     			$pdf->write2DBarcode($code, $encoding, $x, $y, $w, $h, $this->_style2d, $this->_align2d);
    @@ -86,7 +87,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     			$pdf->write1DBarcode($code, $encoding, $x, $y, $w, $h, $this->_xres, $this->_style1d);
     		}
     	}
    -	
    +
     	/**
     	 * Output a sticker on page at position _COUNTX, _COUNTY (_COUNTX and _COUNTY start from 0)
     	 *
    @@ -95,10 +96,10 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     	 * @param	array		$param			Associative array containing label content and optional parameters
     	 * @return	void
     	 */
    -	function addSticker(&$pdf,$outputlangs,$param) 
    +	function addSticker(&$pdf,$outputlangs,$param)
     	{
     		global $mysoc,$conf;
    -		
    +
     		$textleft = $param['textleft'];
     		$header = $param['textheader'];
     		$footer = $param['textfooter'];
    @@ -106,8 +107,8 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     		$code = $param['code'];
     		$encoding = $param['encoding'];
     		$is2d = $param['is2d'];
    -		
    -		
    +
    +
     
     		// We are in a new page, then we must add a page
     		if (($this->_COUNTX ==0) && ($this->_COUNTY==0) and (!$this->_First==1)) {
    @@ -132,7 +133,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     			}
     		}
     
    -		$xleft = 2; 
    +		$xleft = 2;
     		$ytop = 2;
     
     		// Top
    @@ -154,7 +155,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     		$heighttouse = $maxheighttouse;
     		$logoHeight = $heighttouse;
     		$logoWidth = $heighttouse;
    -		
    +
     		//var_dump($this->_Width.'x'.$this->_Height.' with border and scale '.$imgscale.' => max '.$maxwidthtouse.'x'.$maxheighttouse.' => We use '.$widthtouse.'x'.$heighttouse);exit;
     
     		// Center
    @@ -162,7 +163,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     		{
     			// Output left area
     			if ($textleft == '%LOGO%' && $logo) $pdf->Image($logo, $_PosX+$xleft, $_PosY+$ytop, 0, $logoHeight);
    -			else if ($code && !empty($encoding)) 
    +			else if ($code && !empty($encoding))
     			{
     				$this->writeBarcode($pdf, $code, $encoding, $is2d, $_PosX+$xleft, $_PosY+$ytop, $widthtouse, $heighttouse);
     			}
    @@ -177,7 +178,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     			if (($textleft == '%LOGO%' || $textleft == '%PHOTO%' || $textleft == '%BARCODE%') && !strstr($textright, '%') )	 // left part logo/barcode right part text
     			{
     				if ($textleft == '%LOGO%' && $logo) $pdf->Image($logo, $_PosX+$xleft, $_PosY+$ytop, $widthtouse/2, 0);
    -				else if ($code && !empty($encoding)) 
    +				else if ($code && !empty($encoding))
     				{
     					$this->writeBarcode($pdf, $code, $encoding, $is2d, $_PosX+$xleft, $_PosY+$ytop, $widthtouse/2, $heighttouse);
     				}
    @@ -187,7 +188,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     			else if (($textright == '%LOGO%' || $textright == '%PHOTO%' || $textright == '%BARCODE%') && !strstr($textleft, '%')) // right part logo/barcode left part text
     			{
     				if ($textright == '%LOGO%' && $logo) $pdf->Image($logo, $_PosX+($widthtouse/2), $_PosY+$ytop, $widthtouse/2, 0);
    -				else if ($code && !empty($encoding)) 
    +				else if ($code && !empty($encoding))
     				{
     					$this->writeBarcode($pdf, $code, $encoding, $is2d, $_PosX+($widthtouse/2), $_PosY+$ytop, $widthtouse/2, $heighttouse);
     				}
    @@ -203,7 +204,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     				} else {
     					$pdf->SetXY($_PosX+$xleft+$logoWidth+1, $_PosY+$ytop);
     					$pdf->MultiCell($widthtouse-$logoWidth1-1, $this->_Line_Height, $outputlangs->convToOutputCharset($textright),0,'R');
    -				}				
    +				}
     			}
     			else if ($textright == '%LOGO%')  // right part logo left part text/barcode
     			{
    @@ -214,7 +215,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     				} else {
     					$pdf->SetXY($_PosX+$xleft, $_PosY+$ytop);
     					$pdf->MultiCell($widthtouse-$logoWidth-1, $this->_Line_Height, $outputlangs->convToOutputCharset($textleft),0,'L');
    -				}				
    +				}
     			}
     			else	// text on halft left and text on half right
     			{
    @@ -228,7 +229,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     		{
     			// Output right area
     			if ($textright == '%LOGO%' && $logo) $pdf->Image($logo, $_PosX+$this->_Width-$widthtouse-$xleft, $_PosY+$ytop, 0, $logoHeight);
    -			else if ($code && !empty($encoding)) 
    +			else if ($code && !empty($encoding))
     			{
     				$this->writeBarcode($pdf, $code, $encoding, $is2d, $_PosX+$this->_Width-$widthtouse-$xleft, $_PosY+$ytop, $widthtouse, $heighttouse);
     			}
    @@ -265,6 +266,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build PDF on disk, then output on HTTP strem.
     	 *
    @@ -277,6 +279,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     	 */
     	function write_file($arrayofrecords,$outputlangs,$srctemplatepath,$outputdir='',$filename='tmp_address_sheet.pdf')
     	{
    +        // phpcs:enable
     		global $user,$conf,$langs,$mysoc,$_Avery_Labels;
     
     		$this->code=$srctemplatepath;
    @@ -296,10 +299,8 @@ class pdf_tcpdflabel extends CommonStickerGenerator
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("admin");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "admin"));
     
     		$title=$outputlangs->transnoentities('Labels');
     		$keywords=$title." ".$outputlangs->convToOutputCharset($mysoc->name);
    diff --git a/htdocs/core/modules/printsheet/modules_labels.php b/htdocs/core/modules/printsheet/modules_labels.php
    index bac32ec45d2..ddf061d95e9 100644
    --- a/htdocs/core/modules/printsheet/modules_labels.php
    +++ b/htdocs/core/modules/printsheet/modules_labels.php
    @@ -30,22 +30,27 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
     
     /**
    - *	Parent class of document generator for address sheet.
    + *  Parent class of document generator for address sheet.
      */
     class ModelePDFLabels
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
    -     *  @param	DoliDB	$db     			Database handler
    +     *  @param  DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
     	 */
     	function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='members_labels';
    @@ -59,6 +64,7 @@ class ModelePDFLabels
     }
     
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *  Create a document onto disk according to template module.
      *
    @@ -73,6 +79,7 @@ class ModelePDFLabels
      */
     function doc_label_pdf_create($db, $arrayofrecords, $modele, $outputlangs, $outputdir='', $template='standardlabel', $filename='tmp_address_sheet.pdf')
     {
    +    // phpcs:enable
     	global $conf,$langs;
     	$langs->load("members");
     
    @@ -111,7 +118,7 @@ function doc_label_pdf_create($db, $arrayofrecords, $modele, $outputlangs, $outp
     	else $srctemplatepath=$code;
     
     	dol_syslog("modele=".$modele." outputdir=".$outputdir." template=".$template." code=".$code." srctemplatepath=".$srctemplatepath." filename=".$filename, LOG_DEBUG);
    -	
    +
     	// Search template files
     	$file=''; $classname=''; $filefound=0;
     	$dirmodels=array('/');
    @@ -161,7 +168,4 @@ function doc_label_pdf_create($db, $arrayofrecords, $modele, $outputlangs, $outp
     		dol_print_error('',$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$file));
     		return -1;
     	}
    -
    -
     }
    -
    diff --git a/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php b/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php
    index c447639cfe1..979b6fbe7fd 100644
    --- a/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php
    +++ b/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php
    @@ -1,7 +1,8 @@
     <?php
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@products.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
    -*
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
     * 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
    @@ -36,10 +37,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_product_odt extends ModelePDFProduct
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -49,10 +63,10 @@ class doc_generic_product_odt extends ModelePDFProduct
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -94,10 +108,10 @@ class doc_generic_product_odt extends ModelePDFProduct
     	 */
     	function info($langs)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -191,6 +205,7 @@ class doc_generic_product_odt extends ModelePDFProduct
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -204,6 +219,7 @@ class doc_generic_product_odt extends ModelePDFProduct
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $product,$langs,$conf,$mysoc,$hookmanager,$user;
     
     		if (empty($srctemplatepath))
    @@ -225,10 +241,9 @@ class doc_generic_product_odt extends ModelePDFProduct
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
    +
     		if ($conf->produit->dir_output)
     		{
     			// If $object is id instead of object
    @@ -344,16 +359,17 @@ class doc_generic_product_odt extends ModelePDFProduct
     					$odfHandler = new odf(
     						$srctemplatepath,
     						array(
    -						'PATH_TO_TMP'	  => $conf->produit->dir_temp,
    -						'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    -						'DELIMITER_LEFT'  => '{',
    -						'DELIMITER_RIGHT' => '}'
    +							'PATH_TO_TMP'	  => $conf->produit->dir_temp,
    +							'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    +							'DELIMITER_LEFT'  => '{',
    +							'DELIMITER_RIGHT' => '}'
     						)
     					);
     				}
    -				catch(Exception $e)
    +				catch (Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -368,8 +384,9 @@ class doc_generic_product_odt extends ModelePDFProduct
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -404,8 +421,9 @@ class doc_generic_product_odt extends ModelePDFProduct
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -426,11 +444,13 @@ class doc_generic_product_odt extends ModelePDFProduct
     								{
     									$listlines->setVars($key, $val, true, 'UTF-8');
     								}
    -								catch(OdfException $e)
    +								catch (OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
    -								catch(SegmentException $e)
    +								catch (SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -438,7 +458,7 @@ class doc_generic_product_odt extends ModelePDFProduct
     					}
     					$odfHandler->mergeSegment($listlines);
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
     					$this->error=$e->getMessage();
     					dol_syslog($this->error, LOG_WARNING);
    @@ -454,6 +474,7 @@ class doc_generic_product_odt extends ModelePDFProduct
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -465,16 +486,18 @@ class doc_generic_product_odt extends ModelePDFProduct
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
    -					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +						$odfHandler->saveToDisk($file);
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -499,6 +522,4 @@ class doc_generic_product_odt extends ModelePDFProduct
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/product/doc/pdf_standard.modules.php b/htdocs/core/modules/product/doc/pdf_standard.modules.php
    index 032f75f0d65..8d30448bf2f 100644
    --- a/htdocs/core/modules/product/doc/pdf_standard.modules.php
    +++ b/htdocs/core/modules/product/doc/pdf_standard.modules.php
    @@ -58,9 +58,9 @@ class pdf_standard extends ModelePDFProduct
     
     	/**
          * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
          */
    -	public $phpmin = array(5, 2);
    +	public $phpmin = array(5, 4);
     
     	/**
          * Dolibarr version of the loaded document
    @@ -68,15 +68,46 @@ class pdf_standard extends ModelePDFProduct
          */
     	public $version = 'dolibarr';
     
    +    /**
    +     * @var int page_largeur
    +     */
         public $page_largeur;
    +
    +    /**
    +     * @var int page_hauteur
    +     */
         public $page_hauteur;
    +
    +    /**
    +     * @var array format
    +     */
         public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
     	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
     	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
     	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
     	public $marge_basse;
     
    -    public $emetteur;	// Objet societe qui emet
    +    /**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -88,8 +119,8 @@ class pdf_standard extends ModelePDFProduct
     	{
     		global $conf,$langs,$mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load traductions files requiredby by page
    +		$langs->loadLangs(array("main", "companies"));
     
     		$this->db = $db;
     		$this->name = "standard";
    @@ -117,6 +148,7 @@ class pdf_standard extends ModelePDFProduct
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -130,19 +162,15 @@ class pdf_standard extends ModelePDFProduct
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    -		$outputlangs->load("orders");
    -		$outputlangs->load("deliveries");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries"));
     
     		$nblignes = count($object->lines);
     
    @@ -688,11 +716,9 @@ class pdf_standard extends ModelePDFProduct
     	{
     	    global $conf,$langs,$hookmanager;
     
    -	    $outputlangs->load("main");
    -	    $outputlangs->load("bills");
    -	    $outputlangs->load("propal");
    -	    $outputlangs->load("companies");
    -	    $outputlangs->load("orders");
    +	    // Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "propal", "companies", "bills", "orders"));
    +
     	    $default_font_size = pdf_getPDFFontSize($outputlangs);
     
     	    if ($object->type == 1) $titlekey='ServiceSheet';
    @@ -841,6 +867,4 @@ class pdf_standard extends ModelePDFProduct
     	    $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     	    return pdf_pagefoot($pdf,$outputlangs,'PRODUCT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/product/mod_codeproduct_elephant.php b/htdocs/core/modules/product/mod_codeproduct_elephant.php
    index 32941ca1ec9..f051fab7f8e 100644
    --- a/htdocs/core/modules/product/mod_codeproduct_elephant.php
    +++ b/htdocs/core/modules/product/mod_codeproduct_elephant.php
    @@ -34,18 +34,39 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/product/modules_product.class.php'
      */
     class mod_codeproduct_elephant extends ModeleProductCode
     {
    -	var $nom='Elephant';				// Nom du modele
    -	var $name='Elephant';				// Nom du modele
    -	var $code_modifiable;				// Code modifiable
    -	var $code_modifiable_invalide;		// Code modifiable si il est invalide
    -	var $code_modifiable_null;			// Code modifiables si il est null
    -	var $code_null;						// Code facultatif
    -	var $version='dolibarr';    		// 'development', 'experimental', 'dolibarr'
    -	var $code_auto;                     // Numerotation automatique
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Elephant';
     
    -	var $searchcode; // String de recherche
    -	var $numbitcounter; // Nombre de chiffres du compteur
    -	var $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre}
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Elephant';
    +
    +	public $code_modifiable;				// Code modifiable
    +
    +	public $code_modifiable_invalide;		// Code modifiable si il est invalide
    +
    +	public $code_modifiable_null;			// Code modifiables si il est null
    +
    +	public $code_null;						// Code facultatif
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';    		// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto;                     // Numerotation automatique
    +
    +	public $searchcode; // String de recherche
    +
    +	public $numbitcounter; // Nombre de chiffres du compteur
    +
    +	public $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre}
     
     
     	/**
    @@ -198,6 +219,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Check if mask/numbering use prefix
     	 *
    @@ -205,6 +227,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
     	 */
     	function verif_prefixIsUsed()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$mask = $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT;
    @@ -273,6 +296,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Renvoi si un code est pris ou non (par autre tiers)
     	 *
    @@ -283,6 +307,7 @@ class mod_codeproduct_elephant extends ModeleProductCode
     	 */
     	function verif_dispo($db, $code, $product)
     	{
    +        // phpcs:enable
     		$sql = "SELECT ref FROM ".MAIN_DB_PREFIX."product";
     		$sql.= " WHERE ref = '".$code."'";
     		if ($product->id > 0) $sql.= " AND rowid <> ".$product->id;
    @@ -303,8 +328,5 @@ class mod_codeproduct_elephant extends ModeleProductCode
     		{
     			return -2;
     		}
    -
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/product/mod_codeproduct_leopard.php b/htdocs/core/modules/product/mod_codeproduct_leopard.php
    index 3b850e1ba91..815e383d900 100644
    --- a/htdocs/core/modules/product/mod_codeproduct_leopard.php
    +++ b/htdocs/core/modules/product/mod_codeproduct_leopard.php
    @@ -39,14 +39,33 @@ class mod_codeproduct_leopard extends ModeleProductCode
     	 * Le fonctionnement de celui-ci doit donc rester le plus ouvert possible
     	 */
     
    -	var $nom='Leopard';					// Nom du modele
    -	var $name='Leopard';					// Nom du modele
    -	var $code_modifiable;				// Code modifiable
    -	var $code_modifiable_invalide;		// Code modifiable si il est invalide
    -	var $code_modifiable_null;			// Code modifiables si il est null
    -	var $code_null;						// Code facultatif
    -	var $version='dolibarr';    		// 'development', 'experimental', 'dolibarr'
    -	var $code_auto; 	                // Numerotation automatique
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Leopard';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Leopard';
    +
    +	public $code_modifiable;				// Code modifiable
    +
    +	public $code_modifiable_invalide;		// Code modifiable si il est invalide
    +
    +	public $code_modifiable_null;			// Code modifiables si il est null
    +
    +	public $code_null;						// Code facultatif
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';    		// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto; 	                // Numerotation automatique
     
     
     	/**
    diff --git a/htdocs/core/modules/product/modules_product.class.php b/htdocs/core/modules/product/modules_product.class.php
    index 83fc444f258..b632f387d05 100644
    --- a/htdocs/core/modules/product/modules_product.class.php
    +++ b/htdocs/core/modules/product/modules_product.class.php
    @@ -33,18 +33,23 @@
      */
     abstract class ModelePDFProduct extends CommonDocGenerator
     {
    -	var $error='';
    -
    -
     	/**
    -	 *	Return list of active generation modules
    -	 *
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Return list of active generation modules
    +     *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
    -	 */
    +     */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='product';
    @@ -58,7 +63,10 @@ abstract class ModelePDFProduct extends CommonDocGenerator
     
     abstract class ModeleProductCode
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
         /**     Renvoi la description par defaut du modele de numerotation
          *
    @@ -133,6 +141,7 @@ abstract class ModeleProductCode
             return $langs->trans("NotAvailable");
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Renvoi la liste des modeles de numérotation
          *
    @@ -142,6 +151,7 @@ abstract class ModeleProductCode
          */
         static function liste_modeles($db,$maxfilenamelength=0)
         {
    +        // phpcs:enable
             $liste=array();
             $sql ="";
     
    @@ -194,7 +204,7 @@ abstract class ModeleProductCode
                 if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='</strike> '.yn(1,1,2).' ('.$langs->trans("ForcedToByAModule",$langs->transnoentities("yes")).')';
                 $s.='<br>';
             }
    -        if ($type == 1)
    +        elseif ($type == 1)
             {
                 $s.=$langs->trans("RequiredIfService").': ';
                 if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='<strike>';
    @@ -202,7 +212,7 @@ abstract class ModeleProductCode
                 if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='</strike> '.yn(1,1,2).' ('.$langs->trans("ForcedToByAModule",$langs->transnoentities("yes")).')';
                 $s.='<br>';
             }
    -        if ($type == -1)
    +        elseif ($type == -1)
             {
                 $s.=$langs->trans("Required").': ';
                 if (! empty($conf->global->MAIN_COMPANY_CODE_ALWAYS_REQUIRED) && ! empty($this->code_null)) $s.='<strike>';
    @@ -231,15 +241,15 @@ abstract class ModeleProductCode
             return $s;
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
     	 *   Check if mask/numbering use prefix
     	 *
     	 *   @return	int		0=no, 1=yes
     	 */
         function verif_prefixIsUsed()
         {
    +        // phpcs:enable
             return 0;
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/product_batch/modules_product_batch.class.php b/htdocs/core/modules/product_batch/modules_product_batch.class.php
    index 94818d17531..31e0ec676b2 100644
    --- a/htdocs/core/modules/product_batch/modules_product_batch.class.php
    +++ b/htdocs/core/modules/product_batch/modules_product_batch.class.php
    @@ -21,10 +21,10 @@
     
     
     /**
    - *	    \class      ModeleProductCode
    - *		\brief  	Parent class for product code generators
    + *      \class      ModeleProductCode
    + *      \brief      Parent class for product code generators
      */
    - 
    +
     /**
      *  \file       htdocs/core/modules/contract/modules_contract.php
      *  \ingroup    contract
    @@ -32,32 +32,36 @@
      */
     
      require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
    - 
    +
     /**
      *	Parent class to manage intervention document templates
      */
     abstract class ModelePDFProductBatch extends CommonDocGenerator
     {
    -	var $error='';
    -
    -
     	/**
    -	 *	Return list of active generation modules
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +	 *  Return list of active generation modules
     	 *
    -     *  @param	DoliDB	$db     			Database handler
    +     *  @param  DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
    -	 */
    -	static function liste_modeles($db,$maxfilenamelength=0)
    +     */
    +    static function liste_modeles($db, $maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='product_batch';
    -		$liste=array();
    +		$list = array();
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -		$liste=getListOfModels($db,$type,$maxfilenamelength);
    -		return $liste;
    +		$list = getListOfModels($db, $type, $maxfilenamelength);
    +		return $list;
     	}
     }
    -
    diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
    index 6a07ca1d760..d2fa94ceb1e 100644
    --- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
    +++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2013		Florian Henry		<florian.henry@ope-concept.pro>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -53,10 +54,23 @@ if (! empty($conf->agenda->enabled))      require_once DOL_DOCUMENT_ROOT.'/comm/
      */
     class doc_generic_project_odt extends ModelePDFProjects
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -66,7 +80,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
     		// Load traductions files requiredby by page
     		$langs->loadLangs(array("companies", "main"));
    @@ -103,6 +117,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Define array with couple substitution key => substitution value
     	 *
    @@ -113,6 +128,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_object($object,$outputlangs,$array_key='object')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$resarray=array(
    @@ -140,6 +156,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		return $resarray;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -149,6 +166,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_tasks($task,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$resarray = array(
    @@ -177,9 +195,9 @@ class doc_generic_project_odt extends ModelePDFProjects
     		$resarray = $this->fill_substitutionarray_with_extrafields($task,$resarray,$extrafields,'task',$outputlangs);
     
     		return $resarray;
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -189,6 +207,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_project_contacts($contact,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		$pc='projcontacts_'; // prefix to avoid typos
     
    @@ -214,7 +233,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     			$ret[$pc.'phone_mobile'] = $ct->phone_mobile;
     
     			// fetch external user extrafields
    -			require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
    +			require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     			$extrafields=new ExtraFields($this->db);
     			$extralabels=$extrafields->fetch_name_optionals_label($ct->table_element, true);
     			$extrafields_num = $ct->fetch_optionals();
    @@ -236,6 +255,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -245,6 +265,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_project_file($file,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -254,6 +275,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -263,6 +285,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_project_reference($refdetail,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -276,6 +299,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -285,6 +309,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_tasksressource($taskressource,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		//dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
     		return array(
    @@ -298,6 +323,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -307,6 +333,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_taskstime($tasktime,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -325,6 +352,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -334,6 +362,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function get_substitutionarray_task_file($file,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -354,8 +383,8 @@ class doc_generic_project_odt extends ModelePDFProjects
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("companies","errors"));
     
     		$form = new Form($this->db);
     
    @@ -433,6 +462,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -443,6 +473,7 @@ class doc_generic_project_odt extends ModelePDFProjects
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -566,10 +597,9 @@ class doc_generic_project_odt extends ModelePDFProjects
     						'DELIMITER_RIGHT' => '}'
     						)
     					);
    -				}
    -				catch(Exception $e)
    -				{
    +				} catch (Exception $e) {
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -611,8 +641,9 @@ class doc_generic_project_odt extends ModelePDFProjects
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -642,9 +673,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     							}
     							catch(OdfException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     							catch(SegmentException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     						}
     
    @@ -691,9 +724,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     									}
     									catch(OdfException $e)
     									{
    +										dol_syslog($e->getMessage(), LOG_INFO);
     									}
     									catch(SegmentException $e)
     									{
    +										dol_syslog($e->getMessage(), LOG_INFO);
     									}
     								}
     								$listlinestaskres->merge();
    @@ -738,9 +773,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     									}
     									catch(OdfException $e)
     									{
    +										dol_syslog($e->getMessage(), LOG_INFO);
     									}
     									catch(SegmentException $e)
     									{
    +										dol_syslog($e->getMessage(), LOG_INFO);
     									}
     								}
     								$listlinestasktime->merge();
    @@ -776,9 +813,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     									}
     									catch(OdfException $e)
     									{
    +										dol_syslog($e->getMessage(), LOG_INFO);
     									}
     									catch(SegmentException $e)
     									{
    +										dol_syslog($e->getMessage(), LOG_INFO);
     									}
     								}
     								$listlinestasktime->merge();
    @@ -805,11 +844,13 @@ class doc_generic_project_odt extends ModelePDFProjects
     								{
     									$listtasksfiles->setVars($key, $val, true, 'UTF-8');
     								}
    -								catch(OdfException $e)
    +								catch (OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
    -								catch(SegmentException $e)
    +								catch (SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listtasksfiles->merge();
    @@ -851,9 +892,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     							}
     							catch(OdfException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     							catch(SegmentException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     						}
     						$listlines->merge();
    @@ -908,9 +951,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -928,113 +973,113 @@ class doc_generic_project_odt extends ModelePDFProjects
     				//List of referent
     
     				$listofreferent = array(
    -						'propal' => array(
    -								'title' => "ListProposalsAssociatedProject",
    -								'class' => 'Propal',
    -								'table' => 'propal',
    -								'test' => $conf->propal->enabled && $user->rights->propale->lire 
    -						),
    -						'order' => array(
    -								'title' => "ListOrdersAssociatedProject",
    -								'class' => 'Commande',
    -								'table' => 'commande',
    -								'test' => $conf->commande->enabled && $user->rights->commande->lire 
    -						),
    -						'invoice' => array(
    -								'title' => "ListInvoicesAssociatedProject",
    -								'class' => 'Facture',
    -								'table' => 'facture',
    -								'test' => $conf->facture->enabled && $user->rights->facture->lire 
    -						),
    -						'invoice_predefined' => array(
    -								'title' => "ListPredefinedInvoicesAssociatedProject",
    -								'class' => 'FactureRec',
    -								'table' => 'facture_rec',
    -								'test' => $conf->facture->enabled && $user->rights->facture->lire 
    -						),
    -						'proposal_supplier' => array(
    -								'title' => "ListSupplierProposalsAssociatedProject",
    -								'class' => 'SupplierProposal',
    -								'table' => 'supplier_proposal',
    -								'test' => $conf->supplier_proposal->enabled && $user->rights->supplier_proposal->lire 
    -						),
    -						'order_supplier' => array(
    -								'title' => "ListSupplierOrdersAssociatedProject",
    -								'table' => 'commande_fournisseur',
    -								'class' => 'CommandeFournisseur',
    -								'test' => $conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire 
    -						),
    -						'invoice_supplier' => array(
    -								'title' => "ListSupplierInvoicesAssociatedProject",
    -								'table' => 'facture_fourn',
    -								'class' => 'FactureFournisseur',
    -								'test' => $conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire 
    -						),
    -						'contract' => array(
    -								'title' => "ListContractAssociatedProject",
    -								'class' => 'Contrat',
    -								'table' => 'contrat',
    -								'test' => $conf->contrat->enabled && $user->rights->contrat->lire 
    -						),
    -						'intervention' => array(
    -								'title' => "ListFichinterAssociatedProject",
    -								'class' => 'Fichinter',
    -								'table' => 'fichinter',
    -								'disableamount' => 1,
    -								'test' => $conf->ficheinter->enabled && $user->rights->ficheinter->lire 
    -						),
    -						'shipping' => array(
    -								'title' => "ListShippingAssociatedProject",
    -								'class' => 'Expedition',
    -								'table' => 'expedition',
    -								'disableamount' => 1,
    -								'test' => $conf->expedition->enabled && $user->rights->expedition->lire 
    -						),
    -						'trip' => array(
    -								'title' => "ListTripAssociatedProject",
    -								'class' => 'Deplacement',
    -								'table' => 'deplacement',
    -								'disableamount' => 1,
    -								'test' => $conf->deplacement->enabled && $user->rights->deplacement->lire 
    -						),
    -						'expensereport' => array(
    -								'title' => "ListExpenseReportsAssociatedProject",
    -								'class' => 'ExpenseReportLine',
    -								'table' => 'expensereport_det',
    -								'test' => $conf->expensereport->enabled && $user->rights->expensereport->lire 
    -						),
    -						'donation' => array(
    -								'title' => "ListDonationsAssociatedProject",
    -								'class' => 'Don',
    -								'table' => 'don',
    -								'test' => $conf->don->enabled && $user->rights->don->lire 
    -						),
    -						'loan' => array(
    -								'title' => "ListLoanAssociatedProject",
    -								'class' => 'Loan',
    -								'table' => 'loan',
    -								'test' => $conf->loan->enabled && $user->rights->loan->read 
    -						),
    -						'chargesociales' => array(
    -								'title' => "ListSocialContributionAssociatedProject",
    -								'class' => 'ChargeSociales',
    -								'table' => 'chargesociales',
    -								'urlnew' => DOL_URL_ROOT . '/compta/sociales/card.php?action=create&projectid=' . $id,
    -								'test' => $conf->tax->enabled && $user->rights->tax->charges->lire 
    -						),
    -						'stock_mouvement' => array(
    -								'title' => "ListMouvementStockProject",
    -								'class' => 'MouvementStock',
    -								'table' => 'stock_mouvement',
    -								'test' => ($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW)) 
    -						),
    -						'agenda' => array(
    -								'title' => "ListActionsAssociatedProject",
    -								'class' => 'ActionComm',
    -								'table' => 'actioncomm',
    -								'disableamount' => 1,
    -								'test' => $conf->agenda->enabled && $user->rights->agenda->allactions->lire 
    -						) 
    +					'propal' => array(
    +						'title' => "ListProposalsAssociatedProject",
    +						'class' => 'Propal',
    +						'table' => 'propal',
    +						'test' => $conf->propal->enabled && $user->rights->propale->lire
    +					),
    +					'order' => array(
    +						'title' => "ListOrdersAssociatedProject",
    +						'class' => 'Commande',
    +						'table' => 'commande',
    +						'test' => $conf->commande->enabled && $user->rights->commande->lire
    +					),
    +					'invoice' => array(
    +						'title' => "ListInvoicesAssociatedProject",
    +						'class' => 'Facture',
    +						'table' => 'facture',
    +						'test' => $conf->facture->enabled && $user->rights->facture->lire
    +					),
    +					'invoice_predefined' => array(
    +						'title' => "ListPredefinedInvoicesAssociatedProject",
    +						'class' => 'FactureRec',
    +						'table' => 'facture_rec',
    +						'test' => $conf->facture->enabled && $user->rights->facture->lire
    +					),
    +					'proposal_supplier' => array(
    +						'title' => "ListSupplierProposalsAssociatedProject",
    +						'class' => 'SupplierProposal',
    +						'table' => 'supplier_proposal',
    +						'test' => $conf->supplier_proposal->enabled && $user->rights->supplier_proposal->lire
    +					),
    +					'order_supplier' => array(
    +						'title' => "ListSupplierOrdersAssociatedProject",
    +						'table' => 'commande_fournisseur',
    +						'class' => 'CommandeFournisseur',
    +						'test' => $conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire
    +					),
    +					'invoice_supplier' => array(
    +						'title' => "ListSupplierInvoicesAssociatedProject",
    +						'table' => 'facture_fourn',
    +						'class' => 'FactureFournisseur',
    +						'test' => $conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire
    +					),
    +					'contract' => array(
    +						'title' => "ListContractAssociatedProject",
    +						'class' => 'Contrat',
    +						'table' => 'contrat',
    +						'test' => $conf->contrat->enabled && $user->rights->contrat->lire
    +					),
    +					'intervention' => array(
    +						'title' => "ListFichinterAssociatedProject",
    +						'class' => 'Fichinter',
    +						'table' => 'fichinter',
    +						'disableamount' => 1,
    +						'test' => $conf->ficheinter->enabled && $user->rights->ficheinter->lire
    +					),
    +					'shipping' => array(
    +						'title' => "ListShippingAssociatedProject",
    +						'class' => 'Expedition',
    +						'table' => 'expedition',
    +						'disableamount' => 1,
    +						'test' => $conf->expedition->enabled && $user->rights->expedition->lire
    +					),
    +					'trip' => array(
    +						'title' => "ListTripAssociatedProject",
    +						'class' => 'Deplacement',
    +						'table' => 'deplacement',
    +						'disableamount' => 1,
    +						'test' => $conf->deplacement->enabled && $user->rights->deplacement->lire
    +					),
    +					'expensereport' => array(
    +						'title' => "ListExpenseReportsAssociatedProject",
    +						'class' => 'ExpenseReportLine',
    +						'table' => 'expensereport_det',
    +						'test' => $conf->expensereport->enabled && $user->rights->expensereport->lire
    +					),
    +					'donation' => array(
    +						'title' => "ListDonationsAssociatedProject",
    +						'class' => 'Don',
    +						'table' => 'don',
    +						'test' => $conf->don->enabled && $user->rights->don->lire
    +					),
    +					'loan' => array(
    +						'title' => "ListLoanAssociatedProject",
    +						'class' => 'Loan',
    +						'table' => 'loan',
    +						'test' => $conf->loan->enabled && $user->rights->loan->read
    +					),
    +					'chargesociales' => array(
    +						'title' => "ListSocialContributionAssociatedProject",
    +						'class' => 'ChargeSociales',
    +						'table' => 'chargesociales',
    +						'urlnew' => DOL_URL_ROOT . '/compta/sociales/card.php?action=create&projectid=' . $id,
    +						'test' => $conf->tax->enabled && $user->rights->tax->charges->lire
    +					),
    +					'stock_mouvement' => array(
    +						'title' => "ListMouvementStockProject",
    +						'class' => 'MouvementStock',
    +						'table' => 'stock_mouvement',
    +						'test' => ($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))
    +					),
    +					'agenda' => array(
    +						'title' => "ListActionsAssociatedProject",
    +						'class' => 'ActionComm',
    +						'table' => 'actioncomm',
    +						'disableamount' => 1,
    +						'test' => $conf->agenda->enabled && $user->rights->agenda->allactions->lire
    +					),
     				);
     
     				//Insert reference
    @@ -1086,11 +1131,11 @@ class doc_generic_project_odt extends ModelePDFProjects
     										if (!empty($element->total_ht)) {
     											$ref_array['amountht']=$element->total_ht;
     											$ref_array['amountttc']=$element->total_ttc;
    -										}else {
    +										} else {
     											$ref_array['amountht']=0;
     											$ref_array['amountttc']=0;
     										}
    -									}else {
    +									} else {
     										$ref_array['amountht']='';
     										$ref_array['amountttc']='';
     									}
    @@ -1107,21 +1152,20 @@ class doc_generic_project_odt extends ModelePDFProjects
     										}
     										catch(OdfException $e)
     										{
    +											dol_syslog($e->getMessage(), LOG_INFO);
     										}
     										catch(SegmentException $e)
     										{
    +											dol_syslog($e->getMessage(), LOG_INFO);
     										}
     									}
     									$listlines->merge();
     								}
    -
     							}
     						}
     						$odfHandler->mergeSegment($listlines);
     					}
    -				}
    -				catch(OdfException $e)
    -				{
    +				} catch(OdfException $e) {
     					$this->error=$e->getMessage();
     					dol_syslog($this->error, LOG_WARNING);
     					return -1;
    @@ -1133,9 +1177,8 @@ class doc_generic_project_odt extends ModelePDFProjects
     				{
     					try {
     						$odfHandler->setVars($key, $value, true, 'UTF-8');
    -					}
    -					catch(OdfException $e)
    -					{
    +					} catch (OdfException $e) {
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -1148,16 +1191,16 @@ class doc_generic_project_odt extends ModelePDFProjects
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
     						return -1;
     					}
    -				}
    -				else {
    +				} else {
     					try {
    -					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +						$odfHandler->saveToDisk($file);
    +					} catch (Exception $e){
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -1182,5 +1225,4 @@ class doc_generic_project_odt extends ModelePDFProjects
     
     		return -1;
     	}
    -
     }
    diff --git a/htdocs/core/modules/project/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php
    index baa38e8ad2d..d7d6c154881 100644
    --- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php
    +++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php
    @@ -38,7 +38,78 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     class pdf_baleine extends ModelePDFProjects
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
    +
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
    +
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     	/**
     	 *	Constructor
    @@ -48,7 +119,7 @@ class pdf_baleine extends ModelePDFProjects
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "projects", "companies"));
     
    @@ -94,8 +165,9 @@ class pdf_baleine extends ModelePDFProjects
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *	Fonction generant le projet sur le disque
    +	 *  Fonction generant le projet sur le disque
     	 *
     	 *	@param	Project		$object   		Object project a generer
     	 *	@param	Translate	$outputlangs	Lang output object
    @@ -103,16 +175,15 @@ class pdf_baleine extends ModelePDFProjects
     	 */
     	function write_file($object,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf, $hookmanager, $langs, $user;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("projects");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
     
     		if ($conf->projet->dir_output)
     		{
    @@ -602,5 +673,4 @@ class pdf_baleine extends ModelePDFProjects
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'PROJECT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php
    index 4f1d9179aa1..fe33d093083 100644
    --- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php
    +++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php
    @@ -54,7 +54,11 @@ if (! empty($conf->agenda->enabled))        require_once DOL_DOCUMENT_ROOT.'/com
     
     class pdf_beluga extends ModelePDFProjects
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     	/**
     	 *	Constructor
    @@ -64,7 +68,7 @@ class pdf_beluga extends ModelePDFProjects
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "projects", "companies"));
     
    @@ -110,6 +114,7 @@ class pdf_beluga extends ModelePDFProjects
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Fonction generant le projet sur le disque
     	 *
    @@ -119,6 +124,7 @@ class pdf_beluga extends ModelePDFProjects
     	 */
     	function write_file($object,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf, $hookmanager, $langs, $user;
     
             $formproject=new FormProjets($this->db);
    @@ -127,10 +133,8 @@ class pdf_beluga extends ModelePDFProjects
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("projects");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
     
     		if ($conf->projet->dir_output)
     		{
    @@ -255,7 +259,7 @@ class pdf_beluga extends ModelePDFProjects
     				$iniY = $tab_top + $heightoftitleline + 1;
     				$curY = $tab_top + $heightoftitleline + 1;
     				$nexY = $tab_top + $heightoftitleline + 1;
    -				
    +
                     $listofreferent=array(
                         'propal'=>array(
                         	'name'=>"Proposals",
    @@ -370,8 +374,8 @@ class pdf_beluga extends ModelePDFProjects
     
                         //var_dump("$key, $tablename, $datefieldname, $dates, $datee");
                         $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee);
    -                    
    -                    if ($key == 'agenda') 
    +
    +                    if ($key == 'agenda')
                         {
     //                    	var_dump($elementarray);
                         }
    @@ -380,11 +384,11 @@ class pdf_beluga extends ModelePDFProjects
                         if ($num >= 0)
                         {
                             $nexY = $pdf->GetY() + 5;
    -                        
    +
                             $curY = $nexY;
                             $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
                             $pdf->SetTextColor(0,0,0);
    -                          
    +
                             $pdf->SetXY($this->posxref, $curY);
                             $pdf->MultiCell($this->posxstatut - $this->posxref, 3, $outputlangs->transnoentities($title), 0, 'L');
     
    @@ -420,7 +424,7 @@ class pdf_beluga extends ModelePDFProjects
                                 $num = count($elementarray);
     
     				// Loop on each lines
    -				for ($i = 0; $i < $num; $i ++) 
    +				for ($i = 0; $i < $num; $i ++)
     				{
     					$curY = $nexY;
     					$pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
    @@ -498,10 +502,10 @@ class pdf_beluga extends ModelePDFProjects
     								$pdf->SetFont('','',  $default_font_size - 1);   // On repositionne la police par defaut
     								$pdf->MultiCell(0, 3, '');		// Set interline to 3
     								$pdf->SetTextColor(0,0,0);
    -								
    +
     								$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
     								$curY = $tab_top_newpage + $heightoftitleline + 1;
    -								
    +
     								// Label
     								$pdf->SetXY($this->posxref, $curY);
     								$posybefore=$pdf->GetY();
    @@ -559,7 +563,7 @@ class pdf_beluga extends ModelePDFProjects
     					{
     						$pdf->MultiCell($this->posxamountht - $this->posxsociety, 3, (is_object($element->thirdparty)?$element->thirdparty->name:''), 1, 'L');
     					}
    -					
    +
                                     // Amount without tax
                                     if (empty($value['disableamount'])) {
                                         $pdf->SetXY($this->posxamountht, $curY);
    @@ -612,7 +616,7 @@ class pdf_beluga extends ModelePDFProjects
                                 $curY = $nexY;
                             }
                         }
    -                
    +
     					$nexY+=2;    // Passe espace entre les lignes
     
     					// Detect if some page were added automatically and output _tableau for past pages
    @@ -777,7 +781,7 @@ class pdf_beluga extends ModelePDFProjects
     			$pdf->SetXY($posx,$posy);
     			$pdf->MultiCell(100, 4, $outputlangs->transnoentities("ThirdParty")." : " . $object->thirdparty->getFullName($outputlangs), '', 'R');
     		}
    -		
    +
     		$pdf->SetTextColor(0,0,60);
     	}
     
    @@ -796,5 +800,4 @@ class pdf_beluga extends ModelePDFProjects
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'PROJECT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php
    index c7f23df52e3..718e618b16d 100644
    --- a/htdocs/core/modules/project/doc/pdf_timespent.modules.php
    +++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php
    @@ -37,7 +37,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     class pdf_timespent extends ModelePDFProjects
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     	/**
     	 *	Constructor
    @@ -47,7 +51,7 @@ class pdf_timespent extends ModelePDFProjects
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "projects", "companies"));
     
    @@ -93,6 +97,7 @@ class pdf_timespent extends ModelePDFProjects
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Fonction generant le projet sur le disque
     	 *
    @@ -102,16 +107,15 @@ class pdf_timespent extends ModelePDFProjects
     	 */
     	function write_file($object,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf, $hookmanager, $langs, $user;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("projects");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
     
     		if ($conf->projet->dir_output)
     		{
    @@ -584,7 +588,6 @@ class pdf_timespent extends ModelePDFProjects
     	    	}
     	    }
             */
    -
     	}
     
     	/**
    @@ -602,6 +605,4 @@ class pdf_timespent extends ModelePDFProjects
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'PROJECT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/project/mod_project_simple.php b/htdocs/core/modules/project/mod_project_simple.php
    index 05256a3e61f..94f2db957a3 100644
    --- a/htdocs/core/modules/project/mod_project_simple.php
    +++ b/htdocs/core/modules/project/mod_project_simple.php
    @@ -31,11 +31,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/project/modules_project.php';
      */
     class mod_project_simple extends ModeleNumRefProjects
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='PJ';
    -    var $error='';
    -	var $nom = "Simple";
    -	var $name = "Simple";
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='PJ';
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Simple';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Simple';
     
     
         /**
    @@ -140,8 +159,9 @@ class mod_project_simple extends ModeleNumRefProjects
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     * 	Return next reference not yet used as a reference
    +     *  Return next reference not yet used as a reference
          *
          *  @param	Societe	$objsoc     Object third party
          *  @param  Project	$project	Object project
    @@ -149,7 +169,7 @@ class mod_project_simple extends ModeleNumRefProjects
          */
         function project_get_num($objsoc=0,$project='')
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$project);
         }
     }
    -
    diff --git a/htdocs/core/modules/project/mod_project_universal.php b/htdocs/core/modules/project/mod_project_universal.php
    index e76ed349b46..0d11ac820c0 100644
    --- a/htdocs/core/modules/project/mod_project_universal.php
    +++ b/htdocs/core/modules/project/mod_project_universal.php
    @@ -30,10 +30,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/project/modules_project.php';
      */
     class mod_project_universal extends ModeleNumRefProjects
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Universal';
    -	var $name = 'Universal';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Universal';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Universal';
     
     
         /**
    @@ -43,10 +61,10 @@ class mod_project_universal extends ModeleNumRefProjects
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
    -		$langs->load("projects");
    -		$langs->load("admin");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("projects","admin"));
     
     		$form = new Form($this->db);
     
    @@ -127,6 +145,7 @@ class mod_project_universal extends ModeleNumRefProjects
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return next reference not yet used as a reference
          *
    @@ -136,7 +155,7 @@ class mod_project_universal extends ModeleNumRefProjects
          */
         function project_get_num($objsoc=0,$project='')
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$project);
         }
     }
    -
    diff --git a/htdocs/core/modules/project/modules_project.php b/htdocs/core/modules/project/modules_project.php
    index 5f7ef3d5756..e6a688e97e8 100644
    --- a/htdocs/core/modules/project/modules_project.php
    +++ b/htdocs/core/modules/project/modules_project.php
    @@ -31,18 +31,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFProjects extends CommonDocGenerator
     {
    -	var $error='';
    -
    -
     	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
     	 *  Return list of active generation modules
     	 *
    -     *  @param	DoliDB	$db     			Database handler
    +     *  @param  DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
    -	 */
    +     */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='project';
    @@ -62,7 +67,10 @@ abstract class ModelePDFProjects extends CommonDocGenerator
      */
     abstract class ModeleNumRefProjects
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *  Return if a module can be used or not
    diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
    index 5f7ff754a65..c8c588d1f4f 100644
    --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
    +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2013		Florian Henry		<florian.henry@ope-concept.pro>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -54,10 +55,23 @@ if (! empty($conf->agenda->enabled))      require_once DOL_DOCUMENT_ROOT.'/comm/
      */
     class doc_generic_task_odt extends ModelePDFTask
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -67,10 +81,10 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -104,6 +118,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Define array with couple substitution key => substitution value
     	 *
    @@ -114,6 +129,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_object($object,$outputlangs,$array_key='object')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$resarray=array(
    @@ -147,6 +163,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		return $resarray;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -156,6 +173,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_tasks($task,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -176,6 +194,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -185,6 +204,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_project_contacts($contact,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -199,6 +219,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -208,6 +229,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_project_file($file,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -217,6 +239,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -226,6 +249,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_project_reference($refdetail,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -239,6 +263,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -248,6 +273,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_tasksressource($taskressource,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		//dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
     		return array(
    @@ -261,6 +287,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -270,6 +297,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_taskstime($tasktime,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -284,6 +312,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define array with couple substitution key => substitution value
     	 *
    @@ -293,6 +322,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function get_substitutionarray_task_file($file,$outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		return array(
    @@ -313,8 +343,8 @@ class doc_generic_task_odt extends ModelePDFTask
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -392,6 +422,7 @@ class doc_generic_task_odt extends ModelePDFTask
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -402,6 +433,7 @@ class doc_generic_task_odt extends ModelePDFTask
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -414,10 +446,8 @@ class doc_generic_task_odt extends ModelePDFTask
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("projects");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
     
     		if ($conf->projet->dir_output)
     		{
    @@ -531,9 +561,8 @@ class doc_generic_task_odt extends ModelePDFTask
     						{
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
    -					}
    -					catch(OdfException $e)
    -					{
    +					} catch (OdfException $e) {
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -548,15 +577,12 @@ class doc_generic_task_odt extends ModelePDFTask
     					complete_substitutions_array($tmparray, $outputlangs, $object);
     					foreach($tmparray as $key => $val)
     					{
    -						try
    -						{
    +						try {
     							$odfHandler->setVars($key, $val, true, 'UTF-8');
    -						}
    -						catch(OdfException $e)
    -						{
    -						}
    -						catch(SegmentException $e)
    -						{
    +						} catch (OdfException $e) {
    +							dol_syslog($e->getMessage(), LOG_INFO);
    +						} catch(SegmentException $e) {
    +							dol_syslog($e->getMessage(), LOG_INFO);
     						}
     					}
     
    @@ -594,15 +620,13 @@ class doc_generic_task_odt extends ModelePDFTask
     
     							foreach($tmparray as $key => $val)
     							{
    -								try
    -								{
    +								try {
     									$listlinestaskres->setVars($key, $val, true, 'UTF-8');
    +								} catch (OdfException $e) {
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
    -								catch(OdfException $e)
    -								{
    -								}
    -								catch(SegmentException $e)
    -								{
    +								catch (SegmentException $e) {
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlinestaskres->merge();
    @@ -648,9 +672,11 @@ class doc_generic_task_odt extends ModelePDFTask
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlinestasktime->merge();
    @@ -681,9 +707,11 @@ class doc_generic_task_odt extends ModelePDFTask
     							}
     							catch(OdfException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     							catch(SegmentException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     						}
     						$listtasksfiles->merge();
    @@ -691,7 +719,6 @@ class doc_generic_task_odt extends ModelePDFTask
     					//$listlines->merge();
     
     					$odfHandler->mergeSegment($listtasksfiles);
    -
     				}
     				catch(OdfException $e)
     				{
    @@ -724,9 +751,11 @@ class doc_generic_task_odt extends ModelePDFTask
     							}
     							catch(OdfException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     							catch(SegmentException $e)
     							{
    +								dol_syslog($e->getMessage(), LOG_INFO);
     							}
     						}
     						$listlines->merge();
    @@ -782,9 +811,11 @@ class doc_generic_task_odt extends ModelePDFTask
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -809,16 +840,18 @@ class doc_generic_task_odt extends ModelePDFTask
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
     						$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -843,5 +876,4 @@ class doc_generic_task_odt extends ModelePDFTask
     
     		return -1;
     	}
    -
     }
    diff --git a/htdocs/core/modules/project/task/mod_task_simple.php b/htdocs/core/modules/project/task/mod_task_simple.php
    index 1a0aa3e3445..48e9cfe557e 100644
    --- a/htdocs/core/modules/project/task/mod_task_simple.php
    +++ b/htdocs/core/modules/project/task/mod_task_simple.php
    @@ -31,11 +31,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/project/task/modules_task.php';
      */
     class mod_task_simple extends ModeleNumRefTask
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='TK';
    -    var $error='';
    -	var $nom = "Simple";
    -	var $name = "Simple";
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='TK';
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Simple';
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name='Simple';
     
     
         /**
    @@ -140,16 +159,16 @@ class mod_task_simple extends ModeleNumRefTask
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     * 	Return next reference not yet used as a reference
    +     *  Return next reference not yet used as a reference
          *
    -     *  @param	Societe	$objsoc     Object third party
    -     *  @param  Task	$object		Object task
    -     *  @return string      		Next not used reference
    +     *  @param  Societe	$objsoc     Object third party
    +     *  @param  Task	$object     Object task
    +     *  @return string              Next not used reference
          */
         function task_get_num($objsoc=0,$object='')
         {
             return $this->getNextValue($objsoc,$object);
         }
     }
    -
    diff --git a/htdocs/core/modules/project/task/mod_task_universal.php b/htdocs/core/modules/project/task/mod_task_universal.php
    index d89acb22b06..6f46f914b07 100644
    --- a/htdocs/core/modules/project/task/mod_task_universal.php
    +++ b/htdocs/core/modules/project/task/mod_task_universal.php
    @@ -30,10 +30,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/project/task/modules_task.php';
      */
     class mod_task_universal extends ModeleNumRefTask
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Universal';
    -	var $name = 'Universal';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Universal';
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name='Universal';
     
     
         /**
    @@ -45,8 +63,8 @@ class mod_task_universal extends ModeleNumRefTask
         {
         	global $conf,$langs;
     
    -		$langs->load("projects");
    -		$langs->load("admin");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("projects","admin"));
     
     		$form = new Form($this->db);
     
    @@ -127,6 +145,7 @@ class mod_task_universal extends ModeleNumRefTask
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return next reference not yet used as a reference
          *
    @@ -136,7 +155,7 @@ class mod_task_universal extends ModeleNumRefTask
          */
         function project_get_num($objsoc=0,$object='')
         {
    -        return $this->getNextValue($objsoc,$object);
    +        // phpcs:enable
    +        return $this->getNextValue($objsoc, $object);
         }
     }
    -
    diff --git a/htdocs/core/modules/project/task/modules_task.php b/htdocs/core/modules/project/task/modules_task.php
    index 7d14ae12a3e..c9d7aa52bf4 100644
    --- a/htdocs/core/modules/project/task/modules_task.php
    +++ b/htdocs/core/modules/project/task/modules_task.php
    @@ -32,18 +32,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFTask extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
    -	 */
    -	static function liste_modeles($db,$maxfilenamelength=0)
    +     */
    +    static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='project_task';
    @@ -63,7 +68,10 @@ abstract class ModelePDFTask extends CommonDocGenerator
      */
     abstract class ModeleNumRefTask
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *  Return if a module can be used or not
    diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
    index 24477a67cc5..5b87f744466 100644
    --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
    +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php
    @@ -2,7 +2,8 @@
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    -*
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
     * 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
    @@ -37,10 +38,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_proposal_odt extends ModelePDFPropales
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -50,10 +64,10 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -97,8 +111,8 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -207,6 +221,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -220,6 +235,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -241,10 +257,8 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
     
     		if ($conf->propal->multidir_output[$conf->entity])
     		{
    @@ -368,6 +382,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -382,8 +397,9 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -420,6 +436,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -452,9 +469,11 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -476,8 +495,9 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     					try {
     						$odfHandler->setVars($key, $value, true, 'UTF-8');
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -489,16 +509,18 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
     					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -523,6 +545,4 @@ class doc_generic_proposal_odt extends ModelePDFPropales
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
    index 88331761d8a..8c2dfd21a89 100644
    --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
    @@ -2,8 +2,8 @@
     /* Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2008      Raphael Bertrand     <raphael.bertrand@resultic.fr>
    - * Copyright (C) 2010-2015 Juanjo Menent	    <jmenent@2byte.es>
    - * Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
    + * Copyright (C) 2010-2015 Juanjo Menent        <jmenent@2byte.es>
    + * Copyright (C) 2012      Christophe Battarel  <christophe.battarel@altairis.fr>
      * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2017-2018 Ferran Marcet        <fmarcet@2byte.es>
    @@ -41,24 +41,83 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
      */
     class pdf_azur extends ModelePDFPropales
     {
    -	var $db;
    -	var $name;
    -	var $description;
    -	var $update_main_doc_field;	// Save the name of generated file as the main doc when generating a doc with this template
    -	var $type;
    +	/**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -	var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -	var $page_largeur;
    -	var $page_hauteur;
    -	var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
     
    -	var $emetteur;	// Objet societe qui emet
    +    /**
    +     * @var string Save the name of generated file as the main doc when generating a doc with this template
    +     */
    +	public $update_main_doc_field;
    +
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -143,6 +202,7 @@ class pdf_azur extends ModelePDFPropales
     		$this->atleastonediscount=0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *  Function to build pdf onto disk
          *
    @@ -156,18 +216,15 @@ class pdf_azur extends ModelePDFPropales
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("propal");
    -		$outputlangs->load("products");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "propal", "products"));
     
     		$nblignes = count($object->lines);
     
    @@ -774,6 +831,7 @@ class pdf_azur extends ModelePDFPropales
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show payments table
     	 *
    @@ -785,10 +843,11 @@ class pdf_azur extends ModelePDFPropales
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    -
    +        // phpcs:enable
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -800,6 +859,7 @@ class pdf_azur extends ModelePDFPropales
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -968,6 +1028,7 @@ class pdf_azur extends ModelePDFPropales
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -980,6 +1041,7 @@ class pdf_azur extends ModelePDFPropales
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -1084,7 +1146,6 @@ class pdf_azur extends ModelePDFPropales
     
     								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
     								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    -
     							}
     						}
     					}
    @@ -1379,10 +1440,8 @@ class pdf_azur extends ModelePDFPropales
     	{
     		global $conf,$langs;
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("propal");
    -		$outputlangs->load("companies");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "propal", "companies", "bills"));
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -1403,27 +1462,30 @@ class pdf_azur extends ModelePDFPropales
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -			    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B',$default_font_size - 2);
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B',$default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    @@ -1604,6 +1666,7 @@ class pdf_azur extends ModelePDFPropales
     		return pdf_pagefoot($pdf,$outputlangs,'PROPOSAL_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show area for the customer to sign
     	 *
    @@ -1615,6 +1678,7 @@ class pdf_azur extends ModelePDFPropales
     	 */
     	function _signature_area(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     		$tab_top = $posy + 4;
    diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    new file mode 100644
    index 00000000000..464bef3da96
    --- /dev/null
    +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    @@ -0,0 +1,1888 @@
    +<?php
    +/* Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    + * Copyright (C) 2008      Raphael Bertrand     <raphael.bertrand@resultic.fr>
    + * Copyright (C) 2010-2015 Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2012      Christophe Battarel   <christophe.battarel@altairis.fr>
    + * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
    + * Copyright (C) 2017      Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *	\file       htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    + *	\ingroup    propale
    + *	\brief      Fichier de la classe permettant de generer les propales au modele Cyan
    + */
    +require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php';
    +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
    +
    +
    +/**
    + *	Class to generate PDF proposal Cyan
    + */
    +class pdf_cyan extends ModelePDFPropales
    +{
    +	public $db;
    +	public $name;
    +	public $description;
    +	public $update_main_doc_field;	// Save the name of generated file as the main doc when generating a doc with this template
    +	public $type;
    +
    +	public $phpmin = array(4,3,0); // Minimum version of PHP required by module
    +	public $version = 'development';
    +
    +	public $page_largeur;
    +	public $page_hauteur;
    +	public $format;
    +	public $marge_gauche;
    +	public	$marge_droite;
    +	public	$marge_haute;
    +	public	$marge_basse;
    +
    +	public $emetteur;	// Objet societe qui emet
    +
    +
    +	/**
    +	 *	Constructor
    +	 *
    +	 *  @param		DoliDB		$db      Database handler
    +	 */
    +	public function __construct($db)
    +	{
    +		global $conf,$langs,$mysoc;
    +
    +		// Translations
    +		$langs->loadLangs(array("main", "bills"));
    +
    +		$this->db = $db;
    +		$this->name = "cyan";
    +		$this->description = $langs->trans('DocModelCyanDescription');
    +		$this->update_main_doc_field = 1;		// Save the name of generated file as the main doc when generating a doc with this template
    +
    +		// Dimension page
    +		$this->type = 'pdf';
    +		$formatarray=pdf_getFormat();
    +		$this->page_largeur = $formatarray['width'];
    +		$this->page_hauteur = $formatarray['height'];
    +		$this->format = array($this->page_largeur,$this->page_hauteur);
    +		$this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10;
    +		$this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10;
    +		$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
    +		$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
    +
    +		$this->option_logo = 1;                    // Affiche logo
    +		$this->option_tva = 1;                     // Gere option tva FACTURE_TVAOPTION
    +		$this->option_modereg = 1;                 // Affiche mode reglement
    +		$this->option_condreg = 1;                 // Affiche conditions reglement
    +		$this->option_codeproduitservice = 1;      // Affiche code produit-service
    +		$this->option_multilang = 1;               // Dispo en plusieurs langues
    +		$this->option_escompte = 0;                // Affiche si il y a eu escompte
    +		$this->option_credit_note = 0;             // Support credit notes
    +		$this->option_freetext = 1;				   // Support add of a personalised text
    +		$this->option_draft_watermark = 1;		   //Support add of a watermark on drafts
    +
    +		$this->franchise=!$mysoc->tva_assuj;
    +
    +		// Get source company
    +		$this->emetteur=$mysoc;
    +		if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default, if was not defined
    +
    +		// Define position of columns
    +		$this->posxdesc=$this->marge_gauche+1;
    +
    +
    +
    +		$this->tva=array();
    +		$this->localtax1=array();
    +		$this->localtax2=array();
    +		$this->atleastoneratenotnull=0;
    +		$this->atleastonediscount=0;
    +	}
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
    +	/**
    +     *  Function to build pdf onto disk
    +     *
    +     *  @param		Object		$object				Object to generate
    +     *  @param		Translate	$outputlangs		Lang output object
    +     *  @param		string		$srctemplatepath	Full path of source filename for generator using a template file
    +     *  @param		int			$hidedetails		Do not show line details
    +     *  @param		int			$hidedesc			Do not show desc
    +     *  @param		int			$hideref			Do not show ref
    +     *  @return     int             				1=OK, 0=KO
    +	 */
    +	public function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
    +	{
    +	  // phpcs:enable
    +		global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
    +
    +		if (! is_object($outputlangs)) $outputlangs=$langs;
    +		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
    +		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    +
    +		$outputlangs->load("main");
    +		$outputlangs->load("dict");
    +		$outputlangs->load("companies");
    +		$outputlangs->load("bills");
    +		$outputlangs->load("propal");
    +		$outputlangs->load("products");
    +
    +		$nblignes = count($object->lines);
    +
    +		// Loop on each lines to detect if there is at least one image to show
    +		$realpatharray=array();
    +		$this->atleastonephoto = false;
    +		if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE))
    +		{
    +			$objphoto = new Product($this->db);
    +
    +			for ($i = 0 ; $i < $nblignes ; $i++)
    +			{
    +				if (empty($object->lines[$i]->fk_product)) continue;
    +
    +				$objphoto->fetch($object->lines[$i]->fk_product);
    +                //var_dump($objphoto->ref);exit;
    +				if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
    +				{
    +					$pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";
    +					$pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';
    +				}
    +				else
    +				{
    +					$pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';				// default
    +					$pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";	// alternative
    +				}
    +
    +				$arephoto = false;
    +				foreach ($pdir as $midir)
    +				{
    +					if (! $arephoto)
    +					{
    +						$dir = $conf->product->dir_output.'/'.$midir;
    +
    +						foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
    +						{
    +							if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES))		// If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
    +							{
    +								if ($obj['photo_vignette'])
    +								{
    +									$filename= $obj['photo_vignette'];
    +								}
    +								else
    +								{
    +									$filename=$obj['photo'];
    +								}
    +							}
    +							else
    +							{
    +								$filename=$obj['photo'];
    +							}
    +
    +							$realpath = $dir.$filename;
    +							$arephoto = true;
    +							$this->atleastonephoto = true;
    +						}
    +					}
    +				}
    +
    +				if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
    +			}
    +		}
    +
    +		if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
    +
    +		if ($conf->propal->multidir_output[$conf->entity])
    +		{
    +			$object->fetch_thirdparty();
    +
    +			$deja_regle = 0;
    +
    +			// Definition of $dir and $file
    +			if ($object->specimen)
    +			{
    +				$dir = $conf->propal->multidir_output[$conf->entity];
    +				$file = $dir . "/SPECIMEN.pdf";
    +			}
    +			else
    +			{
    +				$objectref = dol_sanitizeFileName($object->ref);
    +				$dir = $conf->propal->multidir_output[$object->entity] . "/" . $objectref;
    +				$file = $dir . "/" . $objectref . ".pdf";
    +			}
    +
    +			if (! file_exists($dir))
    +			{
    +				if (dol_mkdir($dir) < 0)
    +				{
    +					$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
    +					return 0;
    +				}
    +			}
    +
    +			if (file_exists($dir))
    +			{
    +				// Add pdfgeneration hook
    +				if (! is_object($hookmanager))
    +				{
    +					include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    +					$hookmanager=new HookManager($this->db);
    +				}
    +				$hookmanager->initHooks(array('pdfgeneration'));
    +				$parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
    +				global $action;
    +				$reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    +
    +				// Create pdf instance
    +                $pdf=pdf_getInstance($this->format);
    +                $default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
    +	            $pdf->SetAutoPageBreak(1,0);
    +
    +                if (class_exists('TCPDF'))
    +                {
    +                    $pdf->setPrintHeader(false);
    +                    $pdf->setPrintFooter(false);
    +                }
    +                $pdf->SetFont(pdf_getPDFFont($outputlangs));
    +                // Set path to the background PDF File
    +                if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
    +                {
    +                    $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
    +                    $tplidx = $pdf->importPage(1);
    +                }
    +
    +				$pdf->Open();
    +				$pagenb=0;
    +				$pdf->SetDrawColor(128,128,128);
    +
    +				$pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
    +				$pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle"));
    +				$pdf->SetCreator("Dolibarr ".DOL_VERSION);
    +				$pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
    +				$pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
    +				if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
    +
    +				$pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
    +
    +				// Does we have at least one line with discount $this->atleastonediscount
    +				foreach ($object->lines as $line) {
    +				    if ($line->remise_percent){
    +				        $this->atleastonediscount = true;
    +				        break;
    +				    }
    +				}
    +
    +
    +
    +				// New page
    +				$pdf->AddPage();
    +				if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +				$pagenb++;
    +
    +                $heightforinfotot = 40;	// Height reserved to output the info and total part
    +                $heightforsignature = empty($conf->global->PROPAL_DISABLE_SIGNATURE)?(pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature"))+10):0;
    +                $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5);	// Height reserved to output the free text on last page
    +                $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22);	// Height reserved to output the footer (value include bottom margin)
    +                //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit;
    +
    +				$top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
    +				$pdf->SetFont('','', $default_font_size - 1);
    +				$pdf->MultiCell(0, 3, '');		// Set interline to 3
    +				$pdf->SetTextColor(0,0,0);
    +
    +
    +	            $tab_top = 90+$top_shift;
    +				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
    +
    +
    +				// Incoterm
    +				$height_incoterms = 0;
    +				if ($conf->incoterm->enabled)
    +				{
    +					$desc_incoterms = $object->getIncotermsForPDF();
    +					if ($desc_incoterms)
    +					{
    +						$tab_top -= 2;
    +
    +						$pdf->SetFont('','', $default_font_size - 1);
    +						$pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
    +						$nexY = $pdf->GetY();
    +						$height_incoterms=$nexY-$tab_top;
    +
    +						// Rect prend une longueur en 3eme param
    +						$pdf->SetDrawColor(192,192,192);
    +						$pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
    +
    +						$tab_top = $nexY+6;
    +					}
    +				}
    +
    +				// Affiche notes
    +				$notetoshow=empty($object->note_public)?'':$object->note_public;
    +				if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
    +				{
    +					// Get first sale rep
    +					if (is_object($object->thirdparty))
    +					{
    +						$salereparray=$object->thirdparty->getSalesRepresentatives($user);
    +						$salerepobj=new User($this->db);
    +						$salerepobj->fetch($salereparray[0]['id']);
    +						if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
    +					}
    +				}
    +				if (! empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0)
    +				{
    +				    $tmpuser=new User($this->db);
    +				    $tmpuser->fetch($object->user_author_id);
    +				    $notetoshow.='Affaire suivi par '.$tmpuser->getFullName($langs);
    +				    if ($tmpuser->email) $notetoshow.=',  Mail: '.$tmpuser->email;
    +				    if ($tmpuser->office_phone) $notetoshow.=', Tel: '.$tmpuser->office_phone;
    +				}
    +
    +				$pagenb = $pdf->getPage();
    +				if ($notetoshow)
    +				{
    +					$tab_top -= 2;
    +
    +				    $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
    +				    $pageposbeforenote = $pagenb;
    +
    +					$substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
    +					complete_substitutions_array($substitutionarray, $outputlangs, $object);
    +					$notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    +
    +
    +					$pdf->startTransaction();
    +
    +					$pdf->SetFont('','', $default_font_size - 1);
    +					$pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
    +					// Description
    +					$pageposafternote=$pdf->getPage();
    +					$posyafter = $pdf->GetY();
    +
    +					if($pageposafternote>$pageposbeforenote )
    +					{
    +					    $pdf->rollbackTransaction(true);
    +
    +					    // prepar pages to receive notes
    +					    while ($pagenb < $pageposafternote) {
    +					        $pdf->AddPage();
    +					        $pagenb++;
    +					        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +					        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +					        // $this->_pagefoot($pdf,$object,$outputlangs,1);
    +					        $pdf->setTopMargin($tab_top_newpage);
    +					        // The only function to edit the bottom margin of current page to set it.
    +					        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +					    }
    +
    +					    // back to start
    +					    $pdf->setPage($pageposbeforenote);
    +					    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +					    $pdf->SetFont('','', $default_font_size - 1);
    +					    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
    +					    $pageposafternote=$pdf->getPage();
    +
    +					    $posyafter = $pdf->GetY();
    +
    +					    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
    +					    {
    +					        $pdf->AddPage('','',true);
    +					        $pagenb++;
    +					        $pageposafternote++;
    +					        $pdf->setPage($pageposafternote);
    +					        $pdf->setTopMargin($tab_top_newpage);
    +					        // The only function to edit the bottom margin of current page to set it.
    +					        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
    +					        //$posyafter = $tab_top_newpage;
    +					    }
    +
    +
    +					    // apply note frame to previus pages
    +					    $i = $pageposbeforenote;
    +					    while ($i < $pageposafternote) {
    +					        $pdf->setPage($i);
    +
    +
    +					        $pdf->SetDrawColor(128,128,128);
    +					        // Draw note frame
    +					        if($i>$pageposbeforenote){
    +					            $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter);
    +					            $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1);
    +					        }
    +					        else{
    +					            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
    +					            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
    +					        }
    +
    +					        // Add footer
    +					        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +					        $this->_pagefoot($pdf,$object,$outputlangs,1);
    +
    +					        $i++;
    +					    }
    +
    +					    // apply note frame to last page
    +					    $pdf->setPage($pageposafternote);
    +					    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +					    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +					    $height_note=$posyafter-$tab_top_newpage;
    +					    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    +					}
    +					else // No pagebreak
    +					{
    +					    $pdf->commitTransaction();
    +					    $posyafter = $pdf->GetY();
    +					    $height_note=$posyafter-$tab_top;
    +					    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    +
    +
    +					    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
    +					    {
    +					        // not enough space, need to add page
    +					        $pdf->AddPage('','',true);
    +					        $pagenb++;
    +					        $pageposafternote++;
    +					        $pdf->setPage($pageposafternote);
    +					        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +					        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +
    +					        $posyafter = $tab_top_newpage;
    +					    }
    +					}
    +
    +					$tab_height = $tab_height - $height_note;
    +					$tab_top = $posyafter +6;
    +				}
    +				else
    +				{
    +					$height_note=0;
    +				}
    +
    +				$iniY = $tab_top + 7;
    +				$curY = $tab_top + 7;
    +				$nexY = $tab_top + 7;
    +
    +				// Use new auto collum system
    +				$this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    +
    +				// Loop on each lines
    +				$pageposbeforeprintlines=$pdf->getPage();
    +				$pagenb = $pageposbeforeprintlines;
    +				for ($i = 0; $i < $nblignes; $i++)
    +				{
    +					$curY = $nexY;
    +					$pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
    +					$pdf->SetTextColor(0,0,0);
    +
    +					// Define size of image if we need it
    +					$imglinesize=array();
    +					if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
    +
    +					$pdf->setTopMargin($tab_top_newpage);
    +					$pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
    +					$pageposbefore=$pdf->getPage();
    +
    +					$showpricebeforepagebreak=1;
    +					$posYAfterImage=0;
    +					$posYAfterDescription=0;
    +
    +					if($this->getColumnStatus('photo'))
    +					{
    +    					// We start with Photo of product line
    +    					if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot)))	// If photo too high, we moved completely on new page
    +    					{
    +    						$pdf->AddPage('','',true);
    +    						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +    						//if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +    						$pdf->setPage($pageposbefore+1);
    +
    +    						$curY = $tab_top_newpage;
    +    						$showpricebeforepagebreak=0;
    +    					}
    +
    +
    +    					if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
    +    					{
    +    						$pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
    +    						// $pdf->Image does not increase value return by getY, so we save it manually
    +    						$posYAfterImage=$curY+$imglinesize['height'];
    +    					}
    +					}
    +
    +					// Description of product line
    +					if($this->getColumnStatus('desc'))
    +					{
    +    					$pdf->startTransaction();
    +    					pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    +    					$pageposafter=$pdf->getPage();
    +    					if ($pageposafter > $pageposbefore)	// There is a pagebreak
    +    					{
    +    						$pdf->rollbackTransaction(true);
    +    						$pageposafter=$pageposbefore;
    +    						//print $pageposafter.'-'.$pageposbefore;exit;
    +    						$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
    +    						pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    +
    +    						$pageposafter=$pdf->getPage();
    +    						$posyafter=$pdf->GetY();
    +    						//var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
    +    						if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot)))	// There is no space left for total+free text
    +    						{
    +    							if ($i == ($nblignes-1))	// No more lines, and no space left to show total, so we create a new page
    +    							{
    +    								$pdf->AddPage('','',true);
    +    								if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +    								//if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +    								$pdf->setPage($pageposafter+1);
    +    							}
    +    						}
    +    						else
    +    						{
    +    							// We found a page break
    +    							$showpricebeforepagebreak=0;
    +    						}
    +    					}
    +    					else	// No pagebreak
    +    					{
    +    						$pdf->commitTransaction();
    +    					}
    +    					$posYAfterDescription=$pdf->GetY();
    +					}
    +
    +					$nexY = $pdf->GetY();
    +					$pageposafter=$pdf->getPage();
    +
    +					$pdf->setPage($pageposbefore);
    +					$pdf->setTopMargin($this->marge_haute);
    +					$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +
    +					// We suppose that a too long description or photo were moved completely on next page
    +					if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
    +						$pdf->setPage($pageposafter); $curY = $tab_top_newpage;
    +					}
    +
    +					$pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
    +
    +					// VAT Rate
    +					if ($this->getColumnStatus('vat'))
    +					{
    +					    $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Unit price before discount
    +					if ($this->getColumnStatus('subprice'))
    +					{
    +					    $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Quantity
    +					// Enough for 6 chars
    +					if ($this->getColumnStatus('qty'))
    +					{
    +					    $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +
    +					// Unit
    +					if ($this->getColumnStatus('unit'))
    +					{
    +					    $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager);
    +					    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Discount on line
    +					if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
    +					{
    +					    $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +					// Total HT line
    +					if ($this->getColumnStatus('totalexcltax'))
    +					{
    +					    $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails);
    +					    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
    +					    $nexY = max($pdf->GetY(),$nexY);
    +					}
    +
    +
    +					$parameters=array(
    +					    'object' => $object,
    +					    'i' => $i,
    +					    'pdf' =>& $pdf,
    +					    'curY' =>& $curY,
    +					    'nexY' =>& $nexY,
    +					    'outputlangs' => $outputlangs,
    +					    'hidedetails' => $hidedetails
    +					);
    +					$reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    +
    +
    +
    +					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
    +					if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
    +					else $tvaligne=$object->lines[$i]->total_tva;
    +
    +					$localtax1ligne=$object->lines[$i]->total_localtax1;
    +					$localtax2ligne=$object->lines[$i]->total_localtax2;
    +					$localtax1_rate=$object->lines[$i]->localtax1_tx;
    +					$localtax2_rate=$object->lines[$i]->localtax2_tx;
    +					$localtax1_type=$object->lines[$i]->localtax1_type;
    +					$localtax2_type=$object->lines[$i]->localtax2_type;
    +
    +					if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
    +					if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
    +					if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
    +
    +					$vatrate=(string) $object->lines[$i]->tva_tx;
    +
    +					// Retrieve type from database for backward compatibility with old records
    +					if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
    +					&& (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
    +					{
    +						$localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc);
    +						$localtax1_type = $localtaxtmp_array[0];
    +						$localtax2_type = $localtaxtmp_array[2];
    +					}
    +
    +				    // retrieve global local tax
    +					if ($localtax1_type && $localtax1ligne != 0)
    +						$this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
    +					if ($localtax2_type && $localtax2ligne != 0)
    +						$this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
    +
    +					if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
    +					if (! isset($this->tva[$vatrate]))				$this->tva[$vatrate]=0;
    +					$this->tva[$vatrate] += $tvaligne;
    +
    +					if ($posYAfterImage > $posYAfterDescription) $nexY=$posYAfterImage;
    +
    +					// Add line
    +					if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
    +					{
    +						$pdf->setPage($pageposafter);
    +						$pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80)));
    +						//$pdf->SetDrawColor(190,190,200);
    +						$pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
    +						$pdf->SetLineStyle(array('dash'=>0));
    +					}
    +
    +					$nexY+=2;    // Passe espace entre les lignes
    +
    +					// Detect if some page were added automatically and output _tableau for past pages
    +					while ($pagenb < $pageposafter)
    +					{
    +						$pdf->setPage($pagenb);
    +						if ($pagenb == $pageposbeforeprintlines)
    +						{
    +							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
    +						}
    +						else
    +						{
    +							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
    +						}
    +						$this->_pagefoot($pdf,$object,$outputlangs,1);
    +						$pagenb++;
    +						$pdf->setPage($pagenb);
    +						$pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    +						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +					}
    +					if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
    +					{
    +					    if ($pagenb == $pageposafter)
    +						{
    +							$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code);
    +						}
    +						else
    +						{
    +							$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code);
    +						}
    +						$this->_pagefoot($pdf,$object,$outputlangs,1);
    +						// New page
    +						$pdf->AddPage();
    +						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
    +						$pagenb++;
    +						if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    +					}
    +				}
    +
    +				// Show square
    +				if ($pagenb == $pageposbeforeprintlines)
    +				{
    +					$this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code);
    +					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
    +				}
    +				else
    +				{
    +					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
    +					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1;
    +				}
    +
    +				// Affiche zone infos
    +				$posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
    +
    +				// Affiche zone totaux
    +				$posy=$this->drawTotalTable($pdf, $object, 0, $bottomlasttab, $outputlangs);
    +
    +				// Affiche zone versements
    +				/*
    +				if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
    +				{
    +					$posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
    +				}
    +				*/
    +
    +				// Customer signature area
    +				if (empty($conf->global->PROPAL_DISABLE_SIGNATURE))
    +				{
    +				    $posy=$this->drawSignatureArea($pdf, $object, $posy, $outputlangs);
    +				}
    +
    +				// Pied de page
    +				$this->_pagefoot($pdf,$object,$outputlangs);
    +				if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
    +
    +				//If propal merge product PDF is active
    +				if (!empty($conf->global->PRODUIT_PDF_MERGE_PROPAL))
    +				{
    +					require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php';
    +
    +					$already_merged = array ();
    +					foreach ( $object->lines as $line ) {
    +						if (! empty($line->fk_product) && ! (in_array($line->fk_product, $already_merged))) {
    +							// Find the desire PDF
    +							$filetomerge = new Propalmergepdfproduct($this->db);
    +
    +							if ($conf->global->MAIN_MULTILANGS) {
    +								$filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang);
    +							} else {
    +								$filetomerge->fetch_by_product($line->fk_product);
    +							}
    +
    +							$already_merged[] = $line->fk_product;
    +
    +							$product = new Product($this->db);
    +							$product->fetch($line->fk_product);
    +
    +							if ($product->entity!=$conf->entity) {
    +								$entity_product_file=$product->entity;
    +							} else {
    +								$entity_product_file=$conf->entity;
    +							}
    +
    +							// If PDF is selected and file is not empty
    +							if (count($filetomerge->lines) > 0) {
    +								foreach ( $filetomerge->lines as $linefile ) {
    +									if (! empty($linefile->id) && ! empty($linefile->file_name)) {
    +
    +
    +										if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
    +										{
    +											if (! empty($conf->product->enabled)) {
    +												$filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos";
    +											} elseif (! empty($conf->service->enabled)) {
    +												$filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos";
    +											}
    +										}
    +										else
    +										{
    +											if (! empty($conf->product->enabled)) {
    +												$filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref);
    +											} elseif (! empty($conf->service->enabled)) {
    +												$filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref);
    +											}
    +										}
    +
    +										dol_syslog(get_class($this) . ':: upload_dir=' . $filetomerge_dir, LOG_DEBUG);
    +
    +										$infile = $filetomerge_dir . '/' . $linefile->file_name;
    +										if (file_exists($infile) && is_readable($infile)) {
    +											$pagecount = $pdf->setSourceFile($infile);
    +											for($i = 1; $i <= $pagecount; $i ++) {
    +												$tplIdx = $pdf->importPage($i);
    +												if ($tplIdx!==false) {
    +													$s = $pdf->getTemplatesize($tplIdx);
    +													$pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L');
    +													$pdf->useTemplate($tplIdx);
    +												} else {
    +													setEventMessages(null, array($infile.' cannot be added, probably protected PDF'),'warnings');
    +												}
    +											}
    +										}
    +									}
    +								}
    +							}
    +						}
    +					}
    +				}
    +
    +				$pdf->Close();
    +
    +				$pdf->Output($file,'F');
    +
    +				//Add pdfgeneration hook
    +				$hookmanager->initHooks(array('pdfgeneration'));
    +				$parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
    +				global $action;
    +				$reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +
    +				if (! empty($conf->global->MAIN_UMASK))
    +				@chmod($file, octdec($conf->global->MAIN_UMASK));
    +
    +				$this->result = array('fullpath'=>$file);
    +
    +				return 1;   // Pas d'erreur
    +			}
    +			else
    +			{
    +				$this->error=$langs->trans("ErrorCanNotCreateDir",$dir);
    +				return 0;
    +			}
    +		}
    +		else
    +		{
    +			$this->error=$langs->trans("ErrorConstantNotDefined","PROP_OUTPUTDIR");
    +			return 0;
    +		}
    +	}
    +
    +	/**
    +	 *  Show payments table
    +	 *
    +     *  @param	TCPDF		$pdf           Object PDF
    +     *  @param  Object		$object         Object proposal
    +     *  @param  int			$posy           Position y in PDF
    +     *  @param  Translate	$outputlangs    Object langs for output
    +     *  @return int             			<0 if KO, >0 if OK
    +	 */
    +	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
    +	{
    +	}
    +
    +	/**
    +	 *   Show miscellaneous information (payment mode, payment term, ...)
    +	 *
    +	 *   @param		TCPDF		$pdf     		Object PDF
    +	 *   @param		Object		$object			Object to show
    +	 *   @param		int			$posy			Y
    +	 *   @param		Translate	$outputlangs	Langs object
    +	 *   @return	void
    +	 */
    +	function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
    +	{
    +		global $conf;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// If France, show VAT mention if not applicable
    +		if ($this->emetteur->country_code == 'FR' && $this->franchise == 1)
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0);
    +
    +			$posy=$pdf->GetY()+4;
    +		}
    +
    +		$posxval=52;
    +
    +        // Show shipping date
    +        if (! empty($object->date_livraison))
    +		{
    +            $outputlangs->load("sendings");
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("DateDeliveryPlanned").':';
    +			$pdf->MultiCell(80, 4, $titre, 0, 'L');
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true);
    +			$pdf->MultiCell(80, 4, $dlp, 0, 'L');
    +
    +            $posy=$pdf->GetY()+1;
    +		}
    +        elseif ($object->availability_code || $object->availability)    // Show availability conditions
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("AvailabilityPeriod").':';
    +			$pdf->MultiCell(80, 4, $titre, 0, 'L');
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset($object->availability);
    +			$lib_availability=str_replace('\n',"\n",$lib_availability);
    +			$pdf->MultiCell(80, 4, $lib_availability, 0, 'L');
    +
    +			$posy=$pdf->GetY()+1;
    +		}
    +
    +		// Show payments conditions
    +		if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMCOND) && ($object->cond_reglement_code || $object->cond_reglement))
    +		{
    +			$pdf->SetFont('','B', $default_font_size - 2);
    +			$pdf->SetXY($this->marge_gauche, $posy);
    +			$titre = $outputlangs->transnoentities("PaymentConditions").':';
    +			$pdf->MultiCell(43, 4, $titre, 0, 'L');
    +
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posxval, $posy);
    +			$lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc);
    +			$lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement);
    +			$pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L');
    +
    +			$posy=$pdf->GetY()+3;
    +		}
    +
    +		if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMMODE))
    +		{
    +			// Check a payment mode is defined
    +			/* Not required on a proposal
    +			if (empty($object->mode_reglement_code)
    +			&& ! $conf->global->FACTURE_CHQ_NUMBER
    +			&& ! $conf->global->FACTURE_RIB_NUMBER)
    +			{
    +				$pdf->SetXY($this->marge_gauche, $posy);
    +				$pdf->SetTextColor(200,0,0);
    +				$pdf->SetFont('','B', $default_font_size - 2);
    +				$pdf->MultiCell(90, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0);
    +				$pdf->SetTextColor(0,0,0);
    +
    +				$posy=$pdf->GetY()+1;
    +			}
    +			*/
    +
    +			// Show payment mode
    +			if ($object->mode_reglement_code
    +			&& $object->mode_reglement_code != 'CHQ'
    +			&& $object->mode_reglement_code != 'VIR')
    +			{
    +				$pdf->SetFont('','B', $default_font_size - 2);
    +				$pdf->SetXY($this->marge_gauche, $posy);
    +				$titre = $outputlangs->transnoentities("PaymentMode").':';
    +				$pdf->MultiCell(80, 5, $titre, 0, 'L');
    +				$pdf->SetFont('','', $default_font_size - 2);
    +				$pdf->SetXY($posxval, $posy);
    +				$lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement);
    +				$pdf->MultiCell(80, 5, $lib_mode_reg,0,'L');
    +
    +				$posy=$pdf->GetY()+2;
    +			}
    +
    +			// Show payment mode CHQ
    +			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ')
    +			{
    +				// Si mode reglement non force ou si force a CHQ
    +				if (! empty($conf->global->FACTURE_CHQ_NUMBER))
    +				{
    +					$diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE);
    +
    +					if ($conf->global->FACTURE_CHQ_NUMBER > 0)
    +					{
    +						$account = new Account($this->db);
    +						$account->fetch($conf->global->FACTURE_CHQ_NUMBER);
    +
    +						$pdf->SetXY($this->marge_gauche, $posy);
    +						$pdf->SetFont('','B', $default_font_size - $diffsizetitle);
    +						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0);
    +						$posy=$pdf->GetY()+1;
    +
    +			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
    +			            {
    +							$pdf->SetXY($this->marge_gauche, $posy);
    +							$pdf->SetFont('','', $default_font_size - $diffsizetitle);
    +							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0);
    +							$posy=$pdf->GetY()+2;
    +			            }
    +					}
    +					if ($conf->global->FACTURE_CHQ_NUMBER == -1)
    +					{
    +						$pdf->SetXY($this->marge_gauche, $posy);
    +						$pdf->SetFont('','B', $default_font_size - $diffsizetitle);
    +						$pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0);
    +						$posy=$pdf->GetY()+1;
    +
    +			            if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS))
    +			            {
    +							$pdf->SetXY($this->marge_gauche, $posy);
    +							$pdf->SetFont('','', $default_font_size - $diffsizetitle);
    +							$pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0);
    +							$posy=$pdf->GetY()+2;
    +			            }
    +					}
    +				}
    +			}
    +
    +			// If payment mode not forced or forced to VIR, show payment with BAN
    +			if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR')
    +			{
    +				if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER))
    +				{
    +					$bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account);
    +					if (! empty($object->fk_bank)) $bankid=$object->fk_bank;   // For backward compatibility when object->fk_account is forced with object->fk_bank
    +					$account = new Account($this->db);
    +					$account->fetch($bankid);
    +
    +					$curx=$this->marge_gauche;
    +					$cury=$posy;
    +
    +					$posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size);
    +
    +					$posy+=2;
    +				}
    +			}
    +		}
    +
    +		return $posy;
    +	}
    +
    +
    +	/**
    +	 *	Show total to pay
    +	 *
    +	 *	@param	PDF			$pdf            Object PDF
    +	 *	@param  Facture		$object         Object invoice
    +	 *	@param  int			$deja_regle     Montant deja regle
    +	 *	@param	int			$posy			Position depart
    +	 *	@param	Translate	$outputlangs	Objet langs
    +	 *	@return int							Position pour suite
    +	 */
    +	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
    +	{
    +		global $conf,$mysoc;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		$tab2_top = $posy;
    +		$tab2_hl = 4;
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// Tableau total
    +		$col1x = 120; $col2x = 170;
    +		if ($this->page_largeur < 210) // To work with US executive format
    +		{
    +			$col2x-=20;
    +		}
    +		$largcol2 = ($this->page_largeur - $this->marge_droite - $col2x);
    +
    +		$useborder=0;
    +		$index = 0;
    +
    +		// Total HT
    +		$pdf->SetFillColor(255,255,255);
    +		$pdf->SetXY($col1x, $tab2_top + 0);
    +		$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1);
    +
    +		$total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht);
    +		$pdf->SetXY($col2x, $tab2_top + 0);
    +		$pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1);
    +
    +		// Show VAT by rates and total
    +		$pdf->SetFillColor(248,248,248);
    +
    +		$total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc;
    +
    +		$this->atleastoneratenotnull=0;
    +		if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT))
    +		{
    +			$tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false);
    +			if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull)
    +			{
    +				// Nothing to do
    +			}
    +			else
    +			{
    +				//Local tax 1 before VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
    +				//{
    +					foreach( $this->localtax1 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey!=0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +	      		//}
    +				//Local tax 2 before VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
    +				//{
    +					foreach( $this->localtax2 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('1','3','5'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey!=0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' ';
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +				//}
    +				// VAT
    +				foreach($this->tva as $tvakey => $tvaval)
    +				{
    +					if ($tvakey != 0)    // On affiche pas taux 0
    +					{
    +						$this->atleastoneratenotnull++;
    +
    +						$index++;
    +						$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +						$tvacompl='';
    +						if (preg_match('/\*/',$tvakey))
    +						{
    +							$tvakey=str_replace('*','',$tvakey);
    +							$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +						}
    +						$totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' ';
    +						$totalvat.=vatrate($tvakey,1).$tvacompl;
    +						$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +						$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +						$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +					}
    +				}
    +
    +				//Local tax 1 after VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
    +				//{
    +					foreach( $this->localtax1 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +							if ($tvakey != 0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' ';
    +
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +	      		//}
    +				//Local tax 2 after VAT
    +				//if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on')
    +				//{
    +					foreach( $this->localtax2 as $localtax_type => $localtax_rate )
    +					{
    +						if (in_array((string) $localtax_type, array('2','4','6'))) continue;
    +
    +						foreach( $localtax_rate as $tvakey => $tvaval )
    +						{
    +						    // retrieve global local tax
    +							if ($tvakey != 0)    // On affiche pas taux 0
    +							{
    +								//$this->atleastoneratenotnull++;
    +
    +								$index++;
    +								$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +
    +								$tvacompl='';
    +								if (preg_match('/\*/',$tvakey))
    +								{
    +									$tvakey=str_replace('*','',$tvakey);
    +									$tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")";
    +								}
    +								$totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' ';
    +
    +								$totalvat.=vatrate(abs($tvakey),1).$tvacompl;
    +								$pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1);
    +
    +								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    +							}
    +						}
    +					}
    +				//}
    +
    +				// Total TTC
    +				$index++;
    +				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +				$pdf->SetTextColor(0,0,60);
    +				$pdf->SetFillColor(224,224,224);
    +				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1);
    +
    +				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1);
    +			}
    +		}
    +
    +		$pdf->SetTextColor(0,0,0);
    +
    +		/*
    +		$resteapayer = $object->total_ttc - $deja_regle;
    +		if (! empty($object->paye)) $resteapayer=0;
    +		*/
    +
    +		if ($deja_regle > 0)
    +		{
    +			$index++;
    +
    +			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0);
    +
    +			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0);
    +
    +			/*
    +			if ($object->close_code == 'discount_vat')
    +			{
    +				$index++;
    +				$pdf->SetFillColor(255,255,255);
    +
    +				$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1);
    +
    +				$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +				$pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1);
    +
    +				$resteapayer=0;
    +			}
    +			*/
    +
    +			$index++;
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->SetFillColor(224,224,224);
    +			$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1);
    +
    +			$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
    +			$pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1);
    +
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->SetTextColor(0,0,0);
    +		}
    +
    +		$index++;
    +		return ($tab2_top + ($tab2_hl * $index));
    +	}
    +
    +	/**
    +	 *   Show table for lines
    +	 *
    +	 *   @param		PDF			$pdf     		Object PDF
    +	 *   @param		string		$tab_top		Top position of table
    +	 *   @param		string		$tab_height		Height of table (rectangle)
    +	 *   @param		int			$nexY			Y (not used)
    +	 *   @param		Translate	$outputlangs	Langs object
    +	 *   @param		int			$hidetop		1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title
    +	 *   @param		int			$hidebottom		Hide bottom bar of array
    +	 *   @param		string		$currency		Currency code
    +	 *   @return	void
    +	 */
    +	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
    +	{
    +		global $conf;
    +
    +		// Force to disable hidetop and hidebottom
    +		$hidebottom=0;
    +		if ($hidetop) $hidetop=-1;
    +
    +		$currency = !empty($currency) ? $currency : $conf->currency;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		// Amount in (at tab_top - 1)
    +		$pdf->SetTextColor(0,0,0);
    +		$pdf->SetFont('','', $default_font_size - 2);
    +
    +		if (empty($hidetop))
    +		{
    +			$titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency));
    +			$pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4);
    +			$pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);
    +
    +			//$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230';
    +			if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR));
    +		}
    +
    +		$pdf->SetDrawColor(128,128,128);
    +		$pdf->SetFont('','', $default_font_size - 1);
    +
    +		// Output Rect
    +		$this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
    +
    +
    +		foreach ($this->cols as $colKey => $colDef)
    +		{
    +		    if(!$this->getColumnStatus($colKey)) continue;
    +
    +		    // get title label
    +		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    +
    +		    // Add column separator
    +		    if(!empty($colDef['border-left'])){
    +		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
    +		    }
    +
    +		    if (empty($hidetop))
    +		    {
    +		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    +
    +		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
    +		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
    +		    }
    +		}
    +
    +		if (empty($hidetop)){
    +			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
    +		}
    +	}
    +
    +	/**
    +	 *  Show top header of page.
    +	 *
    +	 *  @param	PDF			$pdf     		Object PDF
    +	 *  @param  Object		$object     	Object to show
    +	 *  @param  int	    	$showaddress    0=no, 1=yes
    +	 *  @param  Translate	$outputlangs	Object lang for output
    +	 *  @return	void
    +	 */
    +	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
    +	{
    +		global $conf,$langs;
    +
    +		$outputlangs->load("main");
    +		$outputlangs->load("bills");
    +		$outputlangs->load("propal");
    +		$outputlangs->load("companies");
    +
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +
    +		pdf_pagehead($pdf,$outputlangs,$this->page_hauteur);
    +
    +		//  Show Draft Watermark
    +		if($object->statut==0 && (! empty($conf->global->PROPALE_DRAFT_WATERMARK)) )
    +		{
    +            pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->PROPALE_DRAFT_WATERMARK);
    +		}
    +
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->SetFont('','B', $default_font_size + 3);
    +
    +		$posy=$this->marge_haute;
    +		$posx=$this->page_largeur-$this->marge_droite-100;
    +
    +		$pdf->SetXY($this->marge_gauche,$posy);
    +
    +		// Logo
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
    +		{
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
    +			{
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
    +			}
    +			else
    +			{
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    +			}
    +		}
    +
    +		$pdf->SetFont('','B',$default_font_size + 3);
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$title=$outputlangs->transnoentities("PdfCommercialProposalTitle");
    +		$pdf->MultiCell(100, 4, $title, '', 'R');
    +
    +		$pdf->SetFont('','B',$default_font_size);
    +
    +		$posy+=5;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R');
    +
    +		$posy+=1;
    +		$pdf->SetFont('','', $default_font_size - 2);
    +
    +		if ($object->ref_client)
    +		{
    +			$posy+=4;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R');
    +		}
    +
    +		$posy+=4;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R');
    +
    +		$posy+=4;
    +		$pdf->SetXY($posx,$posy);
    +		$pdf->SetTextColor(0,0,60);
    +		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateEndPropal")." : " . dol_print_date($object->fin_validite,"day",false,$outputlangs,true), '', 'R');
    +
    +		if ($object->thirdparty->code_client)
    +		{
    +			$posy+=4;
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetTextColor(0,0,60);
    +			$pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R');
    +		}
    +
    +		// Get contact
    +		if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP))
    +		{
    +		    $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
    +		    if (count($arrayidcontact) > 0)
    +		    {
    +		        $usertmp=new User($this->db);
    +		        $usertmp->fetch($arrayidcontact[0]);
    +                $posy+=4;
    +                $pdf->SetXY($posx,$posy);
    +		        $pdf->SetTextColor(0,0,60);
    +		        $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R');
    +		    }
    +		}
    +
    +		$posy+=2;
    +
    +		$top_shift = 0;
    +		// Show list of linked objects
    +		$current_y = $pdf->getY();
    +		$posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size);
    +		if ($current_y < $pdf->getY())
    +		{
    +			$top_shift = $pdf->getY() - $current_y;
    +		}
    +
    +		if ($showaddress)
    +		{
    +			// Sender properties
    +			$carac_emetteur='';
    +		 	// Add internal contact of proposal if defined
    +			$arrayidcontact=$object->getIdContact('internal','SALESREPFOLL');
    +		 	if (count($arrayidcontact) > 0)
    +		 	{
    +		 		$object->fetch_user($arrayidcontact[0]);
    +		 		$labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name"));
    +		 		$carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n";
    +		 	}
    +
    +		 	$carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object);
    +
    +			// Show sender
    +			$posy=42+$top_shift;
    +		 	$posx=$this->marge_gauche;
    +			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80;
    +			$hautcadre=40;
    +
    +			// Show sender frame
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posx,$posy-5);
    +			$pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L');
    +			$pdf->SetXY($posx,$posy);
    +			$pdf->SetFillColor(230,230,230);
    +			$pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1);
    +			$pdf->SetTextColor(0,0,60);
    +
    +			// Show sender name
    +			$pdf->SetXY($posx+2,$posy+3);
    +			$pdf->SetFont('','B', $default_font_size);
    +			$pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L');
    +			$posy=$pdf->getY();
    +
    +			// Show sender information
    +			$pdf->SetXY($posx+2,$posy);
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L');
    +
    +
    +			// If CUSTOMER contact defined, we use it
    +			$usecontact=false;
    +			$arrayidcontact=$object->getIdContact('external','CUSTOMER');
    +			if (count($arrayidcontact) > 0)
    +			{
    +				$usecontact=true;
    +				$result=$object->fetch_contact($arrayidcontact[0]);
    +			}
    +
    +			//Recipient name
    +			// On peut utiliser le nom de la societe du contact
    +			if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) {
    +				$thirdparty = $object->contact;
    +			} else {
    +				$thirdparty = $object->thirdparty;
    +			}
    +
    +			$carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs);
    +
    +			$carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object);
    +
    +			// Show recipient
    +			$widthrecbox=100;
    +			if ($this->page_largeur < 210) $widthrecbox=84;	// To work with US executive format
    +			$posy=42+$top_shift;
    +			$posx=$this->page_largeur-$this->marge_droite-$widthrecbox;
    +			if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche;
    +
    +			// Show recipient frame
    +			$pdf->SetTextColor(0,0,0);
    +			$pdf->SetFont('','', $default_font_size - 2);
    +			$pdf->SetXY($posx+2,$posy-5);
    +			$pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L');
    +			$pdf->Rect($posx, $posy, $widthrecbox, $hautcadre);
    +
    +			// Show recipient name
    +			$pdf->SetXY($posx+2,$posy+3);
    +			$pdf->SetFont('','B', $default_font_size);
    +			$pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L');
    +
    +			$posy = $pdf->getY();
    +
    +			// Show recipient information
    +			$pdf->SetFont('','', $default_font_size - 1);
    +			$pdf->SetXY($posx+2,$posy);
    +			$pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L');
    +		}
    +
    +		$pdf->SetTextColor(0,0,0);
    +		return $top_shift;
    +	}
    +
    +	/**
    +	 *   	Show footer of page. Need this->emetteur object
    +     *
    +	 *   	@param	PDF			$pdf     			PDF
    +	 * 		@param	Object		$object				Object to show
    +	 *      @param	Translate	$outputlangs		Object lang for output
    +	 *      @param	int			$hidefreetext		1=Hide free text
    +	 *      @return	int								Return height of bottom margin including footer text
    +	 */
    +	function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
    +	{
    +		global $conf;
    +		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
    +		return pdf_pagefoot($pdf,$outputlangs,'PROPOSAL_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
    +	}
    +
    +	/**
    +	 *	Show area for the customer to sign
    +	 *
    +	 *	@param	PDF			$pdf            Object PDF
    +	 *	@param  Facture		$object         Object invoice
    +	 *	@param	int			$posy			Position depart
    +	 *	@param	Translate	$outputlangs	Objet langs
    +	 *	@return int							Position pour suite
    +	 */
    +	private function drawSignatureArea(&$pdf, $object, $posy, $outputlangs)
    +	{
    +		global $conf;
    +		$default_font_size = pdf_getPDFFontSize($outputlangs);
    +		$tab_top = $posy + 4;
    +		$tab_hl = 4;
    +
    +		$posx = 120;
    +		$largcol = ($this->page_largeur - $this->marge_droite - $posx);
    +		$useborder=0;
    +		$index = 0;
    +		// Total HT
    +		$pdf->SetFillColor(255,255,255);
    +		$pdf->SetXY($posx, $tab_top + 0);
    +		$pdf->SetFont('','', $default_font_size - 2);
    +		$pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', 1);
    +
    +		$pdf->SetXY($posx, $tab_top + $tab_hl);
    +		$pdf->MultiCell($largcol, $tab_hl*3, '', 1, 'R');
    +		if (! empty($conf->global->MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING)) {
    +			$pdf->addEmptySignatureAppearance($posx, $tab_top + $tab_hl, $largcol, $tab_hl*3);
    +		}
    +
    +		return ($tab_hl*7);
    +	}
    +
    +
    +	/**
    +	 *   	Define Array Column Field
    +	 *
    +	 *   	@param	object			$object    		common object
    +	 *   	@param	outputlangs		$outputlangs    langs
    +	 *      @param	int			   $hidedetails		Do not show line details
    +	 *      @param	int			   $hidedesc		Do not show desc
    +	 *      @param	int			   $hideref			Do not show ref
    +	 *      @return	null
    +	 */
    +    function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
    +	    global $conf, $hookmanager;
    +
    +	    // Default field style for content
    +	    $this->defaultContentsFieldsStyle = array(
    +	        'align' => 'R', // R,C,L
    +	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	    );
    +
    +	    // Default field style for content
    +	    $this->defaultTitlesFieldsStyle = array(
    +	        'align' => 'C', // R,C,L
    +	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	    );
    +
    +	    /*
    +	     * For exemple
    +	     $this->cols['theColKey'] = array(
    +	     'rank' => $rank, // int : use for ordering columns
    +	     'width' => 20, // the column width in mm
    +	     'title' => array(
    +	     'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
    +	     'label' => ' ', // the final label : used fore final generated text
    +	     'align' => 'L', // text alignement :  R,C,L
    +	     'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	     ),
    +	     'content' => array(
    +	     'align' => 'L', // text alignement :  R,C,L
    +	     'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	     ),
    +	     );
    +	     */
    +
    +	    $rank=0; // do not use negative rank
    +	    $this->cols['desc'] = array(
    +	        'rank' => $rank,
    +	        'width' => false, // only for desc
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'Designation', // use lang key is usefull in somme case with module
    +	            'align' => 'L',
    +	            // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
    +	            // 'label' => ' ', // the final label
    +	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	        'content' => array(
    +	            'align' => 'L',
    +	        ),
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['photo'] = array(
    +	        'rank' => $rank,
    +	        'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Photo',
    +	            'label' => ' '
    +	        ),
    +	        'content' => array(
    +	            'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
    +	        ),
    +	        'border-left' => false, // remove left line separator
    +	    );
    +
    +	    if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto))
    +	    {
    +	        $this->cols['photo']['status'] = true;
    +	    }
    +
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['vat'] = array(
    +	        'rank' => $rank,
    +	        'status' => false,
    +	        'width' => 16, // in mm
    +	        'title' => array(
    +	            'textkey' => 'VAT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
    +	    {
    +	        $this->cols['vat']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['subprice'] = array(
    +	        'rank' => $rank,
    +	        'width' => 19, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'PriceUHT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['qty'] = array(
    +	        'rank' => $rank,
    +	        'width' => 16, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'Qty'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['progress'] = array(
    +	        'rank' => $rank,
    +	        'width' => 19, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Progress'
    +	        ),
    +	        'border-left' => false, // add left line separator
    +	    );
    +
    +	    if($this->situationinvoice)
    +	    {
    +	        $this->cols['progress']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['unit'] = array(
    +	        'rank' => $rank,
    +	        'width' => 11, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'Unit'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +	    if($conf->global->PRODUCT_USE_UNITS){
    +	        $this->cols['unit']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['discount'] = array(
    +	        'rank' => $rank,
    +	        'width' => 13, // in mm
    +	        'status' => false,
    +	        'title' => array(
    +	            'textkey' => 'ReductionShort'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +	    if ($this->atleastonediscount){
    +	        $this->cols['discount']['status'] = true;
    +	    }
    +
    +	    $rank = $rank + 10;
    +	    $this->cols['totalexcltax'] = array(
    +	        'rank' => $rank,
    +	        'width' => 26, // in mm
    +	        'status' => true,
    +	        'title' => array(
    +	            'textkey' => 'TotalHT'
    +	        ),
    +	        'border-left' => true, // add left line separator
    +	    );
    +
    +
    +	    $parameters=array(
    +	        'object' => $object,
    +	        'outputlangs' => $outputlangs,
    +	        'hidedetails' => $hidedetails,
    +	        'hidedesc' => $hidedesc,
    +	        'hideref' => $hideref
    +	    );
    +
    +	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
    +	    if ($reshook < 0)
    +	    {
    +	        setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
    +	    }
    +	    elseif (empty($reshook))
    +	    {
    +	        $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys
    +	    }
    +	    else
    +	    {
    +	        $this->cols = $hookmanager->resArray;
    +	    }
    +	}
    +}
    diff --git a/htdocs/core/modules/propale/mod_propale_marbre.php b/htdocs/core/modules/propale/mod_propale_marbre.php
    index 0e1700da500..427d4596636 100644
    --- a/htdocs/core/modules/propale/mod_propale_marbre.php
    +++ b/htdocs/core/modules/propale/mod_propale_marbre.php
    @@ -31,10 +31,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/propale/modules_propale.php';
      */
     class mod_propale_marbre extends ModeleNumRefPropales
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='PR';
    -	var $error='';
    -	var $nom = "Marbre";
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='PR';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Marbre';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Marbre';
     
     
         /**
    @@ -152,5 +172,4 @@ class mod_propale_marbre extends ModeleNumRefPropales
     	{
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/propale/mod_propale_saphir.php b/htdocs/core/modules/propale/mod_propale_saphir.php
    index 54d894c20b5..913743eb93d 100644
    --- a/htdocs/core/modules/propale/mod_propale_saphir.php
    +++ b/htdocs/core/modules/propale/mod_propale_saphir.php
    @@ -33,9 +33,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/propale/modules_propale.php';
      */
     class mod_propale_saphir extends ModeleNumRefPropales
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Saphir';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Saphir';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Saphir';
     
     
         /**
    @@ -45,7 +64,7 @@ class mod_propale_saphir extends ModeleNumRefPropales
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -139,5 +158,4 @@ class mod_propale_saphir extends ModeleNumRefPropales
     
     		return  $numFinal;
     	}
    -
     }
    diff --git a/htdocs/core/modules/propale/modules_propale.php b/htdocs/core/modules/propale/modules_propale.php
    index c2d52923e4f..c7514ab973c 100644
    --- a/htdocs/core/modules/propale/modules_propale.php
    +++ b/htdocs/core/modules/propale/modules_propale.php
    @@ -36,9 +36,13 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';   // Requ
      */
     abstract class ModelePDFPropales extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation modules
     	 *
    @@ -48,6 +52,7 @@ abstract class ModelePDFPropales extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='propal';
    @@ -66,7 +71,10 @@ abstract class ModelePDFPropales extends CommonDocGenerator
      */
     abstract class ModeleNumRefPropales
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 * Return if a module can be used or not
    diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php
    index a645b105610..9bd93777df1 100644
    --- a/htdocs/core/modules/rapport/pdf_paiement.class.php
    +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php
    @@ -40,9 +40,9 @@ class pdf_paiement
     	function __construct($db)
     	{
     		global $langs,$conf;
    -		$langs->load("bills");
    -		$langs->load("compta");
    -		$langs->load("main");
    +
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("bills","compta","main"));
     
     		$this->db = $db;
     		$this->description = $langs->transnoentities("ListOfCustomerPayments");
    @@ -80,10 +80,10 @@ class pdf_paiement
     		}
     		// which type of document will be generated: clients (client) or providers (fourn) invoices
     		$this->doc_type = "client";
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Fonction generant la rapport sur le disque
     	 *
    @@ -95,6 +95,7 @@ class pdf_paiement
     	 */
     	function write_file($_dir, $month, $year, $outputlangs)
     	{
    +        // phpcs:enable
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     		global $conf, $hookmanager, $langs, $user;
    @@ -406,6 +407,7 @@ class pdf_paiement
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Output body
     	 *
    @@ -417,6 +419,7 @@ class pdf_paiement
     	 */
     	function Body(&$pdf, $page, $lines, $outputlangs)
     	{
    +        // phpcs:enable
     		global $langs;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -495,4 +498,3 @@ class pdf_paiement
     		$pdf->MultiCell($this->page_largeur - $this->marge_droite - $this->posxpaymentamount, $this->line_height, $langs->transnoentities('Total')." : ".price($total), 0, 'R', 0);
     	}
     }
    -
    diff --git a/htdocs/core/modules/security/generate/modGeneratePassNone.class.php b/htdocs/core/modules/security/generate/modGeneratePassNone.class.php
    index 79cbd1ff629..d0e8c617217 100644
    --- a/htdocs/core/modules/security/generate/modGeneratePassNone.class.php
    +++ b/htdocs/core/modules/security/generate/modGeneratePassNone.class.php
    @@ -31,13 +31,21 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/security/generate/modules_genpass
      */
     class modGeneratePassNone extends ModeleGenPassword
     {
    -	var $id;
    -	var $length;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $db;
    -	var $conf;
    -	var $lang;
    -	var $user;
    +	public $length;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	public $conf;
    +	public $lang;
    +	public $user;
     
     
     	/**
    @@ -100,6 +108,5 @@ class modGeneratePassNone extends ModeleGenPassword
     	{
     		return 1;
     	}
    -
     }
     
    diff --git a/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php b/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php
    index 96041bcac2c..a95a48d20b2 100644
    --- a/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php
    +++ b/htdocs/core/modules/security/generate/modGeneratePassPerso.class.php
    @@ -33,26 +33,34 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/security/generate/modules_genpass
      */
     class modGeneratePassPerso extends ModeleGenPassword
     {
    -	var $id;
    -	var $length;
    -	var $length2; // didn't overright display
    -	var $NbMaj;
    -	var $NbNum;
    -	var $NbSpe;
    -	var $NbRepeat;
    -	var $WithoutAmbi;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $db;
    -	var $conf;
    -	var $lang;
    -	var $user;
    +	public $length;
    +	public $length2; // didn't overright display
    +	public $NbMaj;
    +	public $NbNum;
    +	public $NbSpe;
    +	public $NbRepeat;
    +	public $WithoutAmbi;
     
    -	var $Maj;
    -	var $Min;
    -	var $Nb;
    -	var $Spe;
    -	var $Ambi;
    -	var $All;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	public $conf;
    +	public $lang;
    +	public $user;
    +
    +	public $Maj;
    +	public $Min;
    +	public $Nb;
    +	public $Spe;
    +	public $Ambi;
    +	public $All;
     
     	/**
     	 *	Constructor
    @@ -72,7 +80,7 @@ class modGeneratePassPerso extends ModeleGenPassword
     		$this->langs=$langs;
     		$this->user=$user;
     
    -		if(empty($conf->global->USER_PASSWORD_PATTERN)){
    +		if (empty($conf->global->USER_PASSWORD_PATTERN)) {
     			// default value (8carac, 1maj, 1digit, 1spe,  3 repeat, no ambi at auto generation.
     			dolibarr_set_const($db, "USER_PASSWORD_PATTERN", '8;1;1;1;3;1','chaine',0,'',$conf->entity);
     		}
    @@ -105,7 +113,6 @@ class modGeneratePassPerso extends ModeleGenPassword
     		//$this->All = str_shuffle($this->Maj. $this->Min. $this->Nb. $this->Spe);
     		//$this->All = $this->Maj. $this->Min. $this->Nb. $this->Spe;
     		//$this->All =  $this->Spe;
    -
     	}
     
     	/**
    @@ -201,7 +208,8 @@ class modGeneratePassPerso extends ModeleGenPassword
     	 *		@param		string	$password	Password to check
     	 *      @return     int					0 if KO, >0 if OK
     	 */
    -	function consecutiveInterationSameCharacter($password){
    +    function consecutiveInterationSameCharacter($password)
    +    {
     		$last = "";
     		$count = 0;
     		$char = str_split($password);
    @@ -220,4 +228,3 @@ class modGeneratePassPerso extends ModeleGenPassword
     		return 1;
     	}
     }
    -
    diff --git a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php
    index acb44256537..0ecf7d7ef38 100644
    --- a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php
    +++ b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php
    @@ -31,13 +31,21 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/security/generate/modules_genpass
      */
     class modGeneratePassStandard extends ModeleGenPassword
     {
    -	var $id;
    -	var $length;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $db;
    -	var $conf;
    -	var $lang;
    -	var $user;
    +	public $length;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	public $conf;
    +	public $lang;
    +	public $user;
     
     
     	/**
    @@ -109,7 +117,6 @@ class modGeneratePassStandard extends ModeleGenPassword
     				$password .= $char;
     				$i++;
     			}
    -
     		}
     
     		// done!
    diff --git a/htdocs/core/modules/security/generate/modules_genpassword.php b/htdocs/core/modules/security/generate/modules_genpassword.php
    index 3129a341926..e1f73b134be 100644
    --- a/htdocs/core/modules/security/generate/modules_genpassword.php
    +++ b/htdocs/core/modules/security/generate/modules_genpassword.php
    @@ -30,7 +30,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
      */
     abstract class ModeleGenPassword
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
         /**
          * 		Return if a module can be used or not
    @@ -86,6 +89,5 @@ abstract class ModeleGenPassword
         {
             return 1;
         }
    -
     }
     
    diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
    index 6aa4267d827..3650af12b24 100644
    --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
    +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php
    @@ -1,6 +1,8 @@
     <?php
     /* Copyright (C) 2010-2011 Laurent Destailleur <ely@users.sourceforge.net>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
      * 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
    @@ -34,9 +36,17 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_odt extends ModeleThirdPartyDoc
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    +	/**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
     
     
     	/**
    @@ -46,10 +56,10 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -83,7 +93,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     	function info($langs)
     	{
     		global $conf,$langs;
    -        
    +
     		// Load traductions files requiredby by page
     		$langs->loadLangs(array("companies", "errors"));
     
    @@ -164,6 +174,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -177,6 +188,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager;
     
     		if (empty($srctemplatepath))
    @@ -197,7 +209,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
    -        
    +
     		// Load translation files required by the page
     		$outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
     
    @@ -266,6 +278,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				//print $odfHandler->__toString()."\n";
    @@ -313,9 +326,11 @@ class doc_generic_odt extends ModeleThirdPartyDoc
                     				}
                     				catch(OdfException $e)
                     				{
    +									dol_syslog($e->getMessage(), LOG_INFO);
                     				}
                     				catch(SegmentException $e)
                     				{
    +									dol_syslog($e->getMessage(), LOG_INFO);
                     				}
                     			}
                     			$listlines->merge();
    @@ -357,9 +372,10 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
     						// setVars failed, probably because key not found
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -370,8 +386,9 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     					try {
     						$odfHandler->setVars($key, $value, true, 'UTF-8');
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -383,8 +400,9 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -403,6 +421,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     					   $odfHandler->saveToDisk($file);
     					}catch (Exception $e){
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -428,6 +447,4 @@ class doc_generic_odt extends ModeleThirdPartyDoc
     		$this->error='UnknownError';
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/societe/mod_codeclient_elephant.php b/htdocs/core/modules/societe/mod_codeclient_elephant.php
    index 993bb2ed2b3..621bbd08d3e 100644
    --- a/htdocs/core/modules/societe/mod_codeclient_elephant.php
    +++ b/htdocs/core/modules/societe/mod_codeclient_elephant.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2006-2009 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2007-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2011      Juanjo Menent	    <jmenent@2byte.es>
    - * Copyright (C) 2013 	   Philippe Grand      	<philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018 Philippe Grand      	<philippe.grand@atoo-net.com>
      *
      * 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
    @@ -34,18 +34,39 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php'
      */
     class mod_codeclient_elephant extends ModeleThirdPartyCode
     {
    -	var $nom='Elephant';				// Nom du modele
    -	var $name='Elephant';				// Nom du modele
    -	var $code_modifiable;				// Code modifiable
    -	var $code_modifiable_invalide;		// Code modifiable si il est invalide
    -	var $code_modifiable_null;			// Code modifiables si il est null
    -	var $code_null;						// Code facultatif
    -	var $version='dolibarr';    		// 'development', 'experimental', 'dolibarr'
    -	var $code_auto;                     // Numerotation automatique
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Elephant';
     
    -	var $searchcode; // String de recherche
    -	var $numbitcounter; // Nombre de chiffres du compteur
    -	var $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre}
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Elephant';
    +
    +	public $code_modifiable;				// Code modifiable
    +
    +	public $code_modifiable_invalide;		// Code modifiable si il est invalide
    +
    +	public $code_modifiable_null;			// Code modifiables si il est null
    +
    +	public $code_null;						// Code facultatif
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';    		// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto;                     // Numerotation automatique
    +
    +	public $searchcode; // String de recherche
    +
    +	public $numbitcounter; // Nombre de chiffres du compteur
    +
    +	public $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre}
     
     
     	/**
    @@ -216,6 +237,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Check if mask/numbering use prefix
     	 *
    @@ -223,6 +245,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode
     	 */
     	function verif_prefixIsUsed()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$mask = $conf->global->COMPANY_ELEPHANT_MASK_CUSTOMER;
    @@ -291,6 +314,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Renvoi si un code est pris ou non (par autre tiers)
     	 *
    @@ -302,6 +326,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode
     	 */
     	function verif_dispo($db, $code, $soc, $type=0)
     	{
    +        // phpcs:enable
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe";
     		if ($type == 1) $sql.= " WHERE code_fournisseur = '".$code."'";
     		else $sql.= " WHERE code_client = '".$code."'";
    @@ -323,8 +348,5 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode
     		{
     			return -2;
     		}
    -
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/societe/mod_codeclient_leopard.php b/htdocs/core/modules/societe/mod_codeclient_leopard.php
    index 94c9c04d2e2..9bdd27d5bee 100644
    --- a/htdocs/core/modules/societe/mod_codeclient_leopard.php
    +++ b/htdocs/core/modules/societe/mod_codeclient_leopard.php
    @@ -38,14 +38,33 @@ class mod_codeclient_leopard extends ModeleThirdPartyCode
     	 * Le fonctionnement de celui-ci doit donc rester le plus ouvert possible
     	 */
     
    -	var $nom='Leopard';					// Nom du modele
    -	var $name='Leopard';				// Nom du modele
    -	var $code_modifiable;				// Code modifiable
    -	var $code_modifiable_invalide;		// Code modifiable si il est invalide
    -	var $code_modifiable_null;			// Code modifiables si il est null
    -	var $code_null;						// Code facultatif
    -	var $version='dolibarr';    		// 'development', 'experimental', 'dolibarr'
    -	var $code_auto; 	                // Numerotation automatique
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Leopard';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Leopard';
    +
    +	public $code_modifiable;				// Code modifiable
    +
    +	public $code_modifiable_invalide;		// Code modifiable si il est invalide
    +
    +	public $code_modifiable_null;			// Code modifiables si il est null
    +
    +	public $code_null;						// Code facultatif
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';    		// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto; 	                // Numerotation automatique
     
     
     	/**
    diff --git a/htdocs/core/modules/societe/mod_codeclient_monkey.php b/htdocs/core/modules/societe/mod_codeclient_monkey.php
    index f4d9e5b4b33..c18950a87d1 100644
    --- a/htdocs/core/modules/societe/mod_codeclient_monkey.php
    +++ b/htdocs/core/modules/societe/mod_codeclient_monkey.php
    @@ -32,18 +32,39 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php'
      */
     class mod_codeclient_monkey extends ModeleThirdPartyCode
     {
    -	var $nom='Monkey';					// Nom du modele
    -	var $name='Monkey';					// Nom du modele
    -	var $code_modifiable;				// Code modifiable
    -	var $code_modifiable_invalide;		// Code modifiable si il est invalide
    -	var $code_modifiable_null;			// Code modifiables si il est null
    -	var $code_null;						// Code facultatif
    -	var $version='dolibarr';	    	// 'development', 'experimental', 'dolibarr'
    -	var $code_auto;                     // Numerotation automatique
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Monkey';
     
    -	var $prefixcustomer='CU';
    -	var $prefixsupplier='SU';
    -	var $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre}
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Monkey';
    +
    +	public $code_modifiable;				// Code modifiable
    +
    +	public $code_modifiable_invalide;		// Code modifiable si il est invalide
    +
    +	public $code_modifiable_null;			// Code modifiables si il est null
    +
    +	public $code_null;						// Code facultatif
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';	    	// 'development', 'experimental', 'dolibarr'
    +
    +	public $code_auto;                     // Numerotation automatique
    +
    +	public $prefixcustomer='CU';
    +
    +	public $prefixsupplier='SU';
    +
    +	public $prefixIsRequired; // Le champ prefix du tiers doit etre renseigne quand on utilise {pre}
     
     
     	/**
    @@ -101,24 +122,22 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode
     
     		$return='000001';
     
    -		$field='';$where='';
    -		if ($type == 0)
    -		{
    +		$field='';
    +        $where='';
    +        $prefix = '';
    +		if ($type == 0) {
     			$field = 'code_client';
    +            $prefix = $this->prefixcustomer;
     			//$where = ' AND client in (1,2)';
    -		}
    -		else if ($type == 1)
    -		{
    +		} elseif ($type == 1) {
     			$field = 'code_fournisseur';
    +            $prefix = $this->prefixsupplier;
     			//$where = ' AND fournisseur = 1';
    -		}
    -		else return -1;
    +		} else {
    +            return -1;
    +        }
     
    -
    -		if ($type == 0) $prefix=$this->prefixcustomer;
    -		if ($type == 1) $prefix=$this->prefixsupplier;
    -
    -		// D'abord on recupere la valeur max (reponse immediate car champ indexe)
    +        // D'abord on recupere la valeur max (reponse immediate car champ indexe)
     		$posindice=8;
             $sql = "SELECT MAX(CAST(SUBSTRING(".$field." FROM ".$posindice.") AS SIGNED)) as max";   // This is standard SQL
     		$sql.= " FROM ".MAIN_DB_PREFIX."societe";
    @@ -210,6 +229,7 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *		Renvoi si un code est pris ou non (par autre tiers)
     	 *
    @@ -221,6 +241,7 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode
     	 */
     	function verif_dispo($db, $code, $soc, $type=0)
     	{
    +        // phpcs:enable
     		global $conf, $mc;
     
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe";
    @@ -249,6 +270,7 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoi si un code respecte la syntaxe
     	 *
    @@ -257,6 +279,7 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode
     	 */
     	function verif_syntax($code)
     	{
    +        // phpcs:enable
     		$res = 0;
     
     		if (dol_strlen($code) < 11)
    @@ -269,6 +292,4 @@ class mod_codeclient_monkey extends ModeleThirdPartyCode
     		}
     		return $res;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/societe/mod_codecompta_aquarium.php b/htdocs/core/modules/societe/mod_codecompta_aquarium.php
    index c237be0f91c..772b28f3d6c 100644
    --- a/htdocs/core/modules/societe/mod_codecompta_aquarium.php
    +++ b/htdocs/core/modules/societe/mod_codecompta_aquarium.php
    @@ -31,12 +31,27 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php'
      */
     class mod_codecompta_aquarium extends ModeleAccountancyCode
     {
    -	var $nom='Aquarium';
    -	var $name='Aquarium';
    -	var $version='dolibarr';        // 'development', 'experimental', 'dolibarr'
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Aquarium';
     
    -	var	$prefixcustomeraccountancycode;
    -	var	$prefixsupplieraccountancycode;
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Aquarium';
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';        // 'development', 'experimental', 'dolibarr'
    +
    +	public	$prefixcustomeraccountancycode;
    +
    +	public	$prefixsupplieraccountancycode;
     
     
     	/**
    @@ -107,6 +122,7 @@ class mod_codecompta_aquarium extends ModeleAccountancyCode
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Set accountancy account code for a third party into this->code
     	 *
    @@ -117,6 +133,7 @@ class mod_codecompta_aquarium extends ModeleAccountancyCode
     	 */
     	function get_code($db, $societe, $type='')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$i = 0;
    @@ -212,4 +229,3 @@ class mod_codecompta_aquarium extends ModeleAccountancyCode
     		}
     	}
     }
    -
    diff --git a/htdocs/core/modules/societe/mod_codecompta_panicum.php b/htdocs/core/modules/societe/mod_codecompta_panicum.php
    index 15099eb0538..c1e83b75db4 100644
    --- a/htdocs/core/modules/societe/mod_codecompta_panicum.php
    +++ b/htdocs/core/modules/societe/mod_codecompta_panicum.php
    @@ -30,9 +30,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/societe/modules_societe.class.php'
      */
     class mod_codecompta_panicum extends ModeleAccountancyCode
     {
    -	var $nom='Panicum';
    -	var $name='Panicum';
    -	var $version='dolibarr';        // 'development', 'experimental', 'dolibarr'
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Panicum';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Panicum';
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';        // 'development', 'experimental', 'dolibarr'
     
     
     	/**
    @@ -67,6 +81,7 @@ class mod_codecompta_panicum extends ModeleAccountancyCode
     		return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Set accountancy account code for a third party into this->code
     	 *
    @@ -77,6 +92,7 @@ class mod_codecompta_panicum extends ModeleAccountancyCode
     	 */
     	function get_code($db, $societe, $type='')
     	{
    +        // phpcs:enable
     		$this->code='';
     
     		if (is_object($societe)) {
    @@ -87,4 +103,3 @@ class mod_codecompta_panicum extends ModeleAccountancyCode
     		return 0; // return ok
     	}
     }
    -
    diff --git a/htdocs/core/modules/societe/modules_societe.class.php b/htdocs/core/modules/societe/modules_societe.class.php
    index 0ed5eace2e2..692dcbf185c 100644
    --- a/htdocs/core/modules/societe/modules_societe.class.php
    +++ b/htdocs/core/modules/societe/modules_societe.class.php
    @@ -33,28 +33,32 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModeleThirdPartyDoc extends CommonDocGenerator
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return list of active generation modules
          *
    -	 * 	@param	DoliDB		$db					Database handler
    +     * 	@param	DoliDB		$db					Database handler
          *  @param	integer		$maxfilenamelength  Max length of value to show
          * 	@return	array							List of templates
          */
         static function liste_modeles($db,$maxfilenamelength=0)
         {
    +        // phpcs:enable
             global $conf;
     
             $type='company';
             $liste=array();
     
             include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -        $liste=getListOfModels($db,$type,$maxfilenamelength);
    +        $liste = getListOfModels($db,$type,$maxfilenamelength);
     
             return $liste;
         }
    -
     }
     
     /**
    @@ -63,7 +67,10 @@ abstract class ModeleThirdPartyDoc extends CommonDocGenerator
      */
     abstract class ModeleThirdPartyCode
     {
    -    var $error='';
    +    /**
    +     * @var string Error code (or message)
    +	 */
    +	public $error='';
     
         /**     Renvoi la description par defaut du modele de numerotation
          *
    @@ -138,8 +145,9 @@ abstract class ModeleThirdPartyCode
             return $langs->trans("NotAvailable");
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *  Renvoi la liste des modeles de numéroation
    +     *  Renvoie la liste des modeles de numérotation
          *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
    @@ -147,6 +155,7 @@ abstract class ModeleThirdPartyCode
          */
         static function liste_modeles($db,$maxfilenamelength=0)
         {
    +        // phpcs:enable
             $liste=array();
             $sql ="";
     
    @@ -170,12 +179,12 @@ abstract class ModeleThirdPartyCode
         }
     
         /**
    -     *      Return description of module parameters
    +     *  Return description of module parameters
          *
    -     *      @param	Translate	$langs      Output language
    -     *		@param	Societe		$soc		Third party object
    -     *		@param	int			$type		-1=Nothing, 0=Customer, 1=Supplier
    -     *		@return	string					HTML translated description
    +     *  @param	Translate	$langs      Output language
    +     *  @param	Societe		$soc		Third party object
    +     *  @param	int			$type		-1=Nothing, 0=Customer, 1=Supplier
    +     *  @return	string					HTML translated description
          */
         function getToolTip($langs,$soc,$type)
         {
    @@ -236,16 +245,17 @@ abstract class ModeleThirdPartyCode
             return $s;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Check if mask/numbering use prefix
     	 *
    -	 *   @return	int		0=no, 1=yes
    -	 */
    +	 *   @return    int	    0=no, 1=yes
    +     */
         function verif_prefixIsUsed()
         {
    +        // phpcs:enable
             return 0;
         }
    -
     }
     
     
    @@ -255,7 +265,10 @@ abstract class ModeleThirdPartyCode
      */
     abstract class ModeleAccountancyCode
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
         /**		Return description of module
    @@ -345,6 +358,7 @@ abstract class ModeleAccountancyCode
             return $s;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Set accountancy account code for a third party into this->code
          *
    @@ -355,7 +369,8 @@ abstract class ModeleAccountancyCode
          */
         function get_code($db, $societe, $type='')
         {
    -	    global $langs;
    +        // phpcs:enable
    +        global $langs;
     
             return $langs->trans("NotAvailable");
         }
    @@ -363,6 +378,7 @@ abstract class ModeleAccountancyCode
     
     
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *  Create a document onto disk according to template module.
      *
    @@ -380,6 +396,7 @@ abstract class ModeleAccountancyCode
      */
     function thirdparty_doc_create(DoliDB $db, Societe $object, $message, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
     {
    +    // phpcs:enable
     	dol_syslog(__METHOD__ . " is deprecated", LOG_WARNING);
     
     	return $object->generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
    diff --git a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
    index 4b4a902cb96..c9c4350e050 100644
    --- a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
    +++ b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@stocks.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
     *
     * 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
    @@ -36,10 +37,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_stock_odt extends ModelePDFStock
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -49,10 +63,10 @@ class doc_generic_stock_odt extends ModelePDFStock
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -94,10 +108,10 @@ class doc_generic_stock_odt extends ModelePDFStock
     	 */
     	function info($langs)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -191,6 +205,7 @@ class doc_generic_stock_odt extends ModelePDFStock
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -204,6 +219,7 @@ class doc_generic_stock_odt extends ModelePDFStock
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $stock,$langs,$conf,$mysoc,$hookmanager,$user;
     
     		if (empty($srctemplatepath))
    @@ -225,10 +241,9 @@ class doc_generic_stock_odt extends ModelePDFStock
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills"));
    +
     		if ($conf->produit->dir_output)
     		{
     			// If $object is id instead of object
    @@ -354,6 +369,7 @@ class doc_generic_stock_odt extends ModelePDFStock
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -368,8 +384,9 @@ class doc_generic_stock_odt extends ModelePDFStock
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -404,8 +421,9 @@ class doc_generic_stock_odt extends ModelePDFStock
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -428,9 +446,11 @@ class doc_generic_stock_odt extends ModelePDFStock
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -454,6 +474,7 @@ class doc_generic_stock_odt extends ModelePDFStock
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -465,16 +486,18 @@ class doc_generic_stock_odt extends ModelePDFStock
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
     					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -499,6 +522,4 @@ class doc_generic_stock_odt extends ModelePDFStock
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/stock/doc/pdf_standard.modules.php b/htdocs/core/modules/stock/doc/pdf_standard.modules.php
    index 5825bd693f5..ce01124211a 100644
    --- a/htdocs/core/modules/stock/doc/pdf_standard.modules.php
    +++ b/htdocs/core/modules/stock/doc/pdf_standard.modules.php
    @@ -58,9 +58,9 @@ class pdf_standard extends ModelePDFStock
     
     	/**
          * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
          */
    -	public $phpmin = array(5, 2);
    +	public $phpmin = array(5, 4);
     
     	/**
          * Dolibarr version of the loaded document
    @@ -68,15 +68,46 @@ class pdf_standard extends ModelePDFStock
          */
     	public $version = 'dolibarr';
     
    +    /**
    +     * @var int page_largeur
    +     */
         public $page_largeur;
    +
    +    /**
    +     * @var int page_hauteur
    +     */
         public $page_hauteur;
    +
    +    /**
    +     * @var array format
    +     */
         public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
     	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
     	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
     	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
     	public $marge_basse;
     
    -    public $emetteur;	// Objet societe qui emet
    +    /**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -88,8 +119,8 @@ class pdf_standard extends ModelePDFStock
     	{
     		global $conf,$langs,$mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load traductions files requiredby by page
    +		$langs->loadLangs(array("main", "companies"));
     
     		$this->db = $db;
     		$this->name = "standard";
    @@ -114,12 +145,12 @@ class pdf_standard extends ModelePDFStock
     		// Recupere emetteur
     		$this->emetteur=$mysoc;
     		if (! $this->emetteur->country_code) $this->emetteur->country_code=substr($langs->defaultlang,-2);    // By default if not defined
    -		
    +
     		// Define position of columns
     		$this->wref = 15;
     		$this->posxdesc=$this->marge_gauche+1;
     		$this->posxlabel=$this->posxdesc+$this->wref;
    -		$this->posxtva=80;		
    +		$this->posxtva=80;
     		$this->posxqty=95;
     		$this->posxup=115;
     		$this->posxunit=135;
    @@ -146,6 +177,7 @@ class pdf_standard extends ModelePDFStock
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -159,19 +191,15 @@ class pdf_standard extends ModelePDFStock
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("stocks");
    -		$outputlangs->load("orders");
    -		$outputlangs->load("deliveries");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "stocks", "orders", "deliveries"));
     
     		$nblignes = count($object->lines);
     
    @@ -193,7 +221,7 @@ class pdf_standard extends ModelePDFStock
     			$stockFournisseur = new ProductFournisseur($this->db);
     			$supplierprices = $stockFournisseur->list_product_fournisseur_price($object->id);
     			$object->supplierprices = $supplierprices;
    -			
    +
     			$productstatic=new Product($db);
     
     			if (! file_exists($dir))
    @@ -273,8 +301,8 @@ class pdf_standard extends ModelePDFStock
     				/* Affichage de la liste des produits de l'entrepot                           */
     				/*                                                                            */
     				/* ************************************************************************** */
    -				
    -				$nexY+=5;				
    +
    +				$nexY+=5;
     				$nexY = $pdf->GetY();
     				$nexY+=10;
     
    @@ -316,7 +344,7 @@ class pdf_standard extends ModelePDFStock
     								if ($objtp->label != '') $objp->produit = $objtp->label;
     							}
     						}
    -						
    +
     						$curY = $nexY;
     						$pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
     						$pdf->SetTextColor(0,0,0);
    @@ -324,7 +352,7 @@ class pdf_standard extends ModelePDFStock
     						$pdf->setTopMargin($tab_top_newpage);
     						$pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
     						$pageposbefore=$pdf->getPage();
    -						
    +
     						// Description of product line
     						$curX = $this->posxdesc-1;
     
    @@ -377,13 +405,13 @@ class pdf_standard extends ModelePDFStock
     						}
     
     						$pdf->SetFont('','',  $default_font_size - 1);   // On repositionne la police par defaut
    -						
    +
     						$productstatic->id=$objp->rowid;
     						$productstatic->ref = $objp->ref;
     						$productstatic->label = $objp->produit;
     						$productstatic->type=$objp->type;
     						$productstatic->entity=$objp->entity;
    -						$productstatic->status_batch=$objp->tobatch;	
    +						$productstatic->status_batch=$objp->tobatch;
     
     						// Ref.
     						$pdf->SetXY($this->posxdesc, $curY);
    @@ -396,12 +424,12 @@ class pdf_standard extends ModelePDFStock
     						// Quantity
     						$valtoshow=price2num($objp->value, 'MS');
     						$towrite = (empty($valtoshow)?'0':$valtoshow);
    -						
    +
     						$pdf->SetXY($this->posxqty, $curY);
    -						$pdf->MultiCell($this->posxup-$this->posxqty-0.8, 3, $towrite, 0, 'R');				
    -						
    +						$pdf->MultiCell($this->posxup-$this->posxqty-0.8, 3, $towrite, 0, 'R');
    +
     						$totalunit+=$objp->value;
    -							
    +
     						$pdf->SetXY($this->posxup, $curY);
     						$pdf->MultiCell($this->posxunit-$this->posxup-0.8, 3, price(price2num($objp->ppmp,'MU'), 0, $outputlangs), 0, 'R');
     
    @@ -434,7 +462,7 @@ class pdf_standard extends ModelePDFStock
     						}
     
     						$nexY+=2;    // Passe espace entre les lignes
    -						
    +
     						// Detect if some page were added automatically and output _tableau for past pages
     						while ($pagenb < $pageposafter)
     						{
    @@ -471,20 +499,20 @@ class pdf_standard extends ModelePDFStock
     							if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     						}
     					}
    -					
    +
     					$db->free($resql);
    -					
    +
     					/**
     					 * footer table
     					 */
     					$nexY = $pdf->GetY();
     					$nexY+=2;
    -					$curY = $nexY;					
    -					
    -					$pdf->SetLineStyle(array('dash'=>'0','color'=>array(220,26,26)));					
    +					$curY = $nexY;
    +
    +					$pdf->SetLineStyle(array('dash'=>'0','color'=>array(220,26,26)));
     					$pdf->line($this->marge_gauche, $curY-1, $this->page_largeur-$this->marge_droite, $curY-1);
     					$pdf->SetLineStyle(array('dash'=>0));
    -					
    +
     					$pdf->SetFont('','B',$default_font_size-1);
     					$pdf->SetTextColor(0,0,120);
     
    @@ -492,7 +520,7 @@ class pdf_standard extends ModelePDFStock
     					$pdf->SetXY($this->posxdesc, $curY);
     					$pdf->MultiCell($this->wref, 3, $langs->trans("Total"), 0, 'L');
     
    -					// Quantity				
    +					// Quantity
     					$valtoshow=price2num($totalunit, 'MS');
     					$towrite = empty($valtoshow)?'0':$valtoshow;
     
    @@ -741,8 +769,8 @@ class pdf_standard extends ModelePDFStock
     					}
     				}
     				*/
    -				$tab_top = $tab_top_newpage+21;               
    -				
    +				$tab_top = $tab_top_newpage+21;
    +
     				// Show square
     				if ($pagenb == 1)
     				{
    @@ -754,7 +782,7 @@ class pdf_standard extends ModelePDFStock
     					$this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
     					$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
     				}
    -				
    +
     				$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
     
     				// Affiche zone infos
    @@ -841,21 +869,21 @@ class pdf_standard extends ModelePDFStock
     
     	    // Output Rect
     	    //$this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
    -		
    +
     		$pdf->SetLineStyle(array('dash'=>'0','color'=>array(220,26,26)));
    -		$pdf->SetDrawColor(220,26,26);	
    +		$pdf->SetDrawColor(220,26,26);
     		$pdf->line($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite, $tab_top);
     		$pdf->SetLineStyle(array('dash'=>0));
     		$pdf->SetDrawColor(128,128,128);
     		$pdf->SetTextColor(0,0,120);
    -		
    +
     	    if (empty($hidetop))
     	    {
     	        //$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     	        $pdf->SetXY($this->posxdesc-1, $tab_top+1);
     	        $pdf->MultiCell($this->wref,3, $outputlangs->transnoentities("Ref"),'','L');
     	    }
    -	        
    +
     		//$pdf->line($this->posxlabel-1, $tab_top, $this->posxlabel-1, $tab_top + $tab_height);
     		if (empty($hidetop))
     		{
    @@ -865,7 +893,7 @@ class pdf_standard extends ModelePDFStock
     
     	    //$pdf->line($this->posxqty-1, $tab_top, $this->posxqty-1, $tab_top + $tab_height);
     	    if (empty($hidetop))
    -	    {	
    +	    {
     	        $pdf->SetXY($this->posxqty-1, $tab_top+1);
     	        $pdf->MultiCell($this->posxup-$this->posxqty-1,2, $outputlangs->transnoentities("Units"),'','C');
     	    }
    @@ -878,7 +906,7 @@ class pdf_standard extends ModelePDFStock
     	    }
     
     		//$pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
    -		if (empty($hidetop)) 
    +		if (empty($hidetop))
     		{
     			$pdf->SetXY($this->posxunit - 1, $tab_top + 1);
     			$pdf->MultiCell($this->posxdiscount - $this->posxunit - 1, 2, $outputlangs->transnoentities("EstimatedStockValueShort"), '',
    @@ -892,18 +920,17 @@ class pdf_standard extends ModelePDFStock
     			$pdf->MultiCell($this->postotalht-$this->posxdiscount+1,2, $outputlangs->transnoentities("SellPriceMin"),'','C');
     	    }
     
    -	    //$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);	   
    +	    //$pdf->line($this->postotalht, $tab_top, $this->postotalht, $tab_top + $tab_height);
     	    if (empty($hidetop))
     	    {
     	        $pdf->SetXY($this->postotalht-1, $tab_top+1);
     	        $pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht,2, $outputlangs->transnoentities("EstimatedStockValueSellShort"),'','C');
     	    }
    -		
    -		$pdf->SetDrawColor(220,26,26);	
    +
    +		$pdf->SetDrawColor(220,26,26);
     		$pdf->SetLineStyle(array('dash'=>'0','color'=>array(220,26,26)));
    -		$pdf->line($this->marge_gauche, $tab_top+11, $this->page_largeur-$this->marge_droite, $tab_top+11);	 
    +		$pdf->line($this->marge_gauche, $tab_top+11, $this->page_largeur-$this->marge_droite, $tab_top+11);
     		$pdf->SetLineStyle(array('dash'=>0));
    -		
     	}
     
     	/**
    @@ -920,12 +947,9 @@ class pdf_standard extends ModelePDFStock
     	{
     	    global $conf,$langs,$db,$hookmanager;
     
    -	    $outputlangs->load("main");
    -	    $outputlangs->load("bills");
    -	    $outputlangs->load("propal");
    -	    $outputlangs->load("companies");
    -	    $outputlangs->load("orders");
    -	    $outputlangs->load("stocks");
    +	    // Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "propal", "companies", "bills", "orders", "stocks"));
    +
     	    $default_font_size = pdf_getPDFFontSize($outputlangs);
     
     	    if ($object->type == 1) $titlekey='ServiceSheet';
    @@ -969,7 +993,7 @@ class pdf_standard extends ModelePDFStock
     	        $text=$this->emetteur->name;
     	        $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     	    }
    -		
    +
     	    $pdf->SetFont('','B', $default_font_size + 3);
     	    $pdf->SetXY($posx,$posy);
     	    $pdf->SetTextColor(0,0,60);
    @@ -989,22 +1013,22 @@ class pdf_standard extends ModelePDFStock
     		$pdf->SetXY($posx,$posy);
     	    $pdf->SetTextColor(0,0,60);
     	    $pdf->MultiCell(100, 3, $outputlangs->transnoentities("LocationSummary").' :', '', 'R');
    -		
    +
     		$posy+=4;
     		$pdf->SetXY($posx-50,$posy);
     		$pdf->MultiCell(150, 3, $object->lieu, '', 'R');
    -		
    -		
    +
    +
     		// Parent entrepot
     		$posy+=4;
     		$pdf->SetXY($posx,$posy);
     		$pdf->SetTextColor(0,0,60);
     		$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ParentWarehouse").' :', '', 'R');
    -		
    +
     		$posy+=4;
     		$pdf->SetXY($posx-50,$posy);
     		$e = new Entrepot($db);
    -		if(!empty($object->fk_parent) && $e->fetch($object->fk_parent) > 0) 
    +		if(!empty($object->fk_parent) && $e->fetch($object->fk_parent) > 0)
     		{
     			$pdf->MultiCell(150, 3, $e->libelle, '', 'R');
     		}
    @@ -1012,14 +1036,14 @@ class pdf_standard extends ModelePDFStock
     		{
     			$pdf->MultiCell(150, 3, $outputlangs->transnoentities("None"), '', 'R');
     		}
    -		
    +
     		// Description
     		$nexY = $pdf->GetY();
     		$nexY+=5;
     		$pdf->SetXY($posx,$posy);
     		$pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("Description").' : </b>'.nl2br($object->description), 0, 1);
     		$nexY = $pdf->GetY();
    -		
    +
     		$calcproductsunique=$object->nb_different_products();
     		$calcproducts=$object->nb_products();
     
    @@ -1031,12 +1055,12 @@ class pdf_standard extends ModelePDFStock
     		$valtoshow=price2num($calcproducts['nb'], 'MS');
     		$pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("NumberOfProducts").' : </b>'.(empty($valtoshow)?'0':$valtoshow), 0, 1);
     		$nexY = $pdf->GetY();
    -		
    +
     		// Value
     		$pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("EstimatedStockValueShort").' : </b>'. price((empty($calcproducts['value'])?'0':price2num($calcproducts['value'],'MT')), 0, $langs, 0, -1, -1, $conf->currency), 0, 1);
     		$nexY = $pdf->GetY();
    -		
    -		
    +
    +
     		// Last movement
     		$sql = "SELECT max(m.datem) as datem";
     		$sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
    @@ -1064,7 +1088,7 @@ class pdf_standard extends ModelePDFStock
     		$pdf->writeHTMLCell(190, 2, $this->marge_gauche, $nexY, '<b>'.$outputlangs->transnoentities("LastMovement").' : </b>'.$toWrite, 0, 1);
     		$nexY = $pdf->GetY();
     
    -		
    +
     	    /*if ($object->ref_client)
     	    {
     	        $posy+=5;
    @@ -1153,6 +1177,4 @@ class pdf_standard extends ModelePDFStock
     	    $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     	    return pdf_pagefoot($pdf,$outputlangs,'PRODUCT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
    index f8844a275e5..3c0d62be848 100644
    --- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
    +++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php
    @@ -59,9 +59,9 @@ class pdf_stdmovement extends ModelePDFMovement
     
     	/**
          * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
          */
    -	public $phpmin = array(5, 2);
    +	public $phpmin = array(5, 4);
     
     	/**
          * Dolibarr version of the loaded document
    @@ -69,15 +69,46 @@ class pdf_stdmovement extends ModelePDFMovement
          */
     	public $version = 'dolibarr';
     
    +    /**
    +     * @var int page_largeur
    +     */
         public $page_largeur;
    +
    +    /**
    +     * @var int page_hauteur
    +     */
         public $page_hauteur;
    +
    +    /**
    +     * @var array format
    +     */
         public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
     	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
     	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
     	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
     	public $marge_basse;
     
    -    public $emetteur;	// Objet societe qui emet
    +    /**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -89,8 +120,8 @@ class pdf_stdmovement extends ModelePDFMovement
     	{
     		global $conf,$langs,$mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load traductions files requiredby by page
    +		$langs->loadLangs(array("main", "companies"));
     
     		$this->db = $db;
     		$this->name = "stdmouvement";
    @@ -149,6 +180,7 @@ class pdf_stdmovement extends ModelePDFMovement
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -162,19 +194,15 @@ class pdf_stdmovement extends ModelePDFMovement
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("stocks");
    -		$outputlangs->load("orders");
    -		$outputlangs->load("deliveries");
    +		// Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "stocks", "orders", "deliveries"));
     
     	/**
     	 * TODO: get from object
    @@ -685,7 +713,6 @@ class pdf_stdmovement extends ModelePDFMovement
     					// Total Qty
     					$pdf->SetXY($this->postotalht, $curY);
     					$pdf->MultiCell($this->page_largeur-$this->marge_droite-$this->postotalht, 3, $totalunit, 0, 'R', 0);
    -
     				}
     				else
     				{
    @@ -905,7 +932,6 @@ class pdf_stdmovement extends ModelePDFMovement
     		$pdf->SetLineStyle(array('dash'=>'0','color'=>array(220,26,26)));
     		$pdf->line($this->marge_gauche, $tab_top+11, $this->page_largeur-$this->marge_droite, $tab_top+11);
     		$pdf->SetLineStyle(array('dash'=>0));
    -
     	}
     
     	/**
    @@ -922,12 +948,9 @@ class pdf_stdmovement extends ModelePDFMovement
     	{
     	    global $conf,$langs,$db,$hookmanager;
     
    -	    $outputlangs->load("main");
    -	    $outputlangs->load("bills");
    -	    $outputlangs->load("propal");
    -	    $outputlangs->load("companies");
    -	    $outputlangs->load("orders");
    -	    $outputlangs->load("stocks");
    +	    // Load traductions files requiredby by page
    +		$outputlangs->loadLangs(array("main", "propal", "companies", "bills", "orders", "stocks"));
    +
     	    $default_font_size = pdf_getPDFFontSize($outputlangs);
     
     	    if ($object->type == 1) $titlekey='ServiceSheet';
    @@ -1155,6 +1178,4 @@ class pdf_stdmovement extends ModelePDFMovement
     	    $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     	    return pdf_pagefoot($pdf,$outputlangs,'PRODUCT_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/stock/modules_movement.php b/htdocs/core/modules/stock/modules_movement.php
    index 806f500dab7..33672e415ea 100644
    --- a/htdocs/core/modules/stock/modules_movement.php
    +++ b/htdocs/core/modules/stock/modules_movement.php
    @@ -30,9 +30,13 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFMovement extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of active generation modules
     	 *
    @@ -42,6 +46,7 @@ abstract class ModelePDFMovement extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='mouvement';
    @@ -50,4 +55,4 @@ abstract class ModelePDFMovement extends CommonDocGenerator
     		$liste=getListOfModels($db,$type,$maxfilenamelength);
     		return $liste;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/core/modules/stock/modules_stock.php b/htdocs/core/modules/stock/modules_stock.php
    index a0740b50f54..a74df6198ce 100644
    --- a/htdocs/core/modules/stock/modules_stock.php
    +++ b/htdocs/core/modules/stock/modules_stock.php
    @@ -23,18 +23,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFStock extends CommonDocGenerator
     {
    -    var $error='';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return list of active generation modules
          *
    -	 * 	@param	DoliDB		$db					Database handler
    +     * 	@param	DoliDB		$db					Database handler
          *  @param	integer		$maxfilenamelength  Max length of value to show
          * 	@return	array							List of templates
          */
         static function liste_modeles($db,$maxfilenamelength=0)
         {
    +        // phpcs:enable
             global $conf;
     
             $type='stock';
    diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php
    index 2eaa85261d0..28474f094f1 100644
    --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php
    +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php
    @@ -1,7 +1,7 @@
     <?php
     /* Copyright (C) 2005-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013      Philippe Grand       <philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018 Philippe Grand       <philippe.grand@atoo-net.com>
      * Copyright (C) 2016      Alexandre Spangaro   <aspangaro@zendsi.com>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -33,12 +33,34 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_invoice/modules_facturef
      */
     class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Cactus';
    -	var $prefixinvoice='SI';
    -	var $prefixcreditnote='SA';
    -	var $prefixdeposit='SD';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Cactus';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Cactus';
    +
    +	public $prefixinvoice='SI';
    +
    +	public $prefixcreditnote='SA';
    +
    +	public $prefixdeposit='SD';
     
     
         /**
    diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
    index 7c595fe4e9d..8e6dddeebd5 100644
    --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
    +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
    @@ -2,7 +2,7 @@
     /* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013      Philippe Grand       <philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018 Philippe Grand       <philippe.grand@atoo-net.com>
      * Copyright (C) 2013      Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2016      Alexandre Spangaro   <aspangaro@zendsi.com>
      *
    @@ -36,9 +36,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_invoice/modules_facturef
     */
     class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Tulip';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Tulip';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Tulip';
     
     
         /**
    @@ -48,10 +67,10 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
    -		$langs->load("bills");
    -		$langs->load("admin");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("bills","admin"));
     
     		$form = new Form($this->db);
     
    diff --git a/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php b/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php
    index 7762d8ce6a5..064be2e1f41 100644
    --- a/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php
    +++ b/htdocs/core/modules/supplier_invoice/modules_facturefournisseur.php
    @@ -1,8 +1,8 @@
     <?php
    -/* Copyright (C) 2010	Juanjo Menent	<jmenent@2byte.es>
    - * Copyright (C) 2012	Regis Houssin	<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013-2016   Philippe Grand  <philippe.grand@atoo-net.com>
    - * Copyright (C) 2014   Marcos García   <marcosgdf@gmail.com>
    +/* Copyright (C) 2010       Juanjo Menent       <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin       <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013-2016  Philippe Grand      <philippe.grand@atoo-net.com>
    + * Copyright (C) 2014       Marcos García       <marcosgdf@gmail.com>
      *
      * 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
    @@ -34,9 +34,13 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';	// requir
      */
     abstract class ModelePDFSuppliersInvoices extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation models
     	 *
    @@ -44,19 +48,19 @@ abstract class ModelePDFSuppliersInvoices extends CommonDocGenerator
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of numbers
     	 */
    -	static function liste_modeles($db,$maxfilenamelength=0)
    +	static function liste_modeles($db, $maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
    -		$type='invoice_supplier';
    -		$liste=array();
    +		$type = 'invoice_supplier';
    +		$list = array();
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -		$liste=getListOfModels($db,$type,$maxfilenamelength);
    +		$list = getListOfModels($db, $type, $maxfilenamelength);
     
    -		return $liste;
    +		return $list;
     	}
    -
     }
     
     /**
    @@ -64,7 +68,10 @@ abstract class ModelePDFSuppliersInvoices extends CommonDocGenerator
      */
     abstract class ModeleNumRefSuppliersInvoices
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**  Return if a model can be used or not
     	 *
    diff --git a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
    index 874e776d2e0..dec36d5adbd 100644
    --- a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
    +++ b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php
    @@ -37,23 +37,79 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
      */
     class pdf_canelle extends ModelePDFSuppliersInvoices
     {
    -    var $db;
    -    var $name;
    -    var $description;
    -    var $type;
    +    /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -    var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -    var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -    var $page_largeur;
    -    var $page_hauteur;
    -    var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
    +
    +    /**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
    -	var $emetteur;	// Objet societe qui emet
     
     
     	/**
    @@ -63,9 +119,9 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		// Translations
    +		// Load translation files required by the page
     		$langs->loadLangs(array("main", "bills"));
     
     		$this->db = $db;
    @@ -127,6 +183,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *  Function to build pdf onto disk
          *
    @@ -137,9 +194,10 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
          *  @param		int					$hidedesc			Do not show desc
          *  @param		int					$hideref			Do not show ref
          *  @return		int										1=OK, 0=KO
    -	 */
    +     */
     	function write_file($object, $outputlangs='', $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$hookmanager,$nblignes;
     
     		// Get source company
    @@ -152,11 +210,8 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products"));
     
     		if ($conf->fournisseur->facture->dir_output)
     		{
    @@ -188,7 +243,6 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     					$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
     					return 0;
     				}
    -
     			}
     
     			if (file_exists($dir))
    @@ -550,6 +604,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -562,6 +617,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     
             $default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -868,9 +924,9 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     			$pdf->SetXY($this->postotalht-1, $tab_top+1);
     			$pdf->MultiCell(30,2, $outputlangs->transnoentities("TotalHTShort"),'','C');
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show payments table
     	 *
    @@ -882,6 +938,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sign=1;
    @@ -960,7 +1017,6 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     			$this->error=$this->db->lasterror();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -974,12 +1030,11 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     	 */
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
    -		global $langs,$conf,$mysoc;
    +		global $langs, $conf, $mysoc;
    +
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "orders", "companies", "bills"));
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("orders");
    -		$outputlangs->load("companies");
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
     		// Do not add the BACKGROUND as this is for suppliers
    @@ -1192,5 +1247,4 @@ class pdf_canelle extends ModelePDFSuppliersInvoices
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'SUPPLIER_INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php
    index a39e7d004be..8448c61f62b 100644
    --- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php
    +++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php
    @@ -31,10 +31,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_order/modules_commandefo
      */
     class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Muguet';
    -	var $prefix='CF';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Muguet';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Muguet';
    +
    +	public $prefix='CF';
     
     
     	/**
    @@ -143,6 +163,7 @@ class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Renvoie la reference de commande suivante non utilisee
          *
    @@ -152,7 +173,7 @@ class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders
          */
         function commande_get_num($objsoc=0,$object='')
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$object);
         }
     }
    -
    diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
    index 37b8adab22e..1645ce796b2 100644
    --- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
    +++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php
    @@ -32,9 +32,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_order/modules_commandefo
      */
     class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Orchidee';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Orchidee';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Orchidee';
     
     
         /**
    @@ -44,10 +63,10 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
    -		$langs->load("bills");
    -		$langs->load("admin");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("bills","admin"));
     
     		$form = new Form($this->db);
     
    @@ -127,6 +146,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Renvoie la reference de commande suivante non utilisee
          *
    @@ -136,7 +156,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders
          */
         function commande_get_num($objsoc=0,$object='')
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$object);
         }
     }
    -
    diff --git a/htdocs/core/modules/supplier_order/modules_commandefournisseur.php b/htdocs/core/modules/supplier_order/modules_commandefournisseur.php
    index 4bd262d67fb..edb047510d5 100644
    --- a/htdocs/core/modules/supplier_order/modules_commandefournisseur.php
    +++ b/htdocs/core/modules/supplier_order/modules_commandefournisseur.php
    @@ -37,9 +37,13 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';	// requir
      */
     abstract class ModelePDFSuppliersOrders extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation models
     	 *
    @@ -49,6 +53,7 @@ abstract class ModelePDFSuppliersOrders extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +		// phpcs:enable
     		global $conf;
     
     		$type='order_supplier';
    @@ -59,7 +64,6 @@ abstract class ModelePDFSuppliersOrders extends CommonDocGenerator
     
     		return $liste;
     	}
    -
     }
     
     
    @@ -69,7 +73,10 @@ abstract class ModelePDFSuppliersOrders extends CommonDocGenerator
      */
     abstract class ModeleNumRefSuppliersOrders
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**  Return if a model can be used or not
     	 *
    diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php
    index 63f10111529..d869b5dd72d 100644
    --- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php
    +++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php
    @@ -41,23 +41,78 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
      */
     class pdf_muscadet extends ModelePDFSuppliersOrders
     {
    -    var $db;
    -    var $name;
    -    var $description;
    -    var $type;
    +    /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -    var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -    var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -    var $page_largeur;
    -    var $page_hauteur;
    -    var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
     
    -	var $emetteur;	// Objet societe qui emet
    +    /**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Company object that emits
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -67,9 +122,9 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		// Translations
    +		// Load translation files required by the page
     		$langs->loadLangs(array("main", "bills"));
     
     		$this->db = $db;
    @@ -142,6 +197,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Function to build pdf onto disk
          *
    @@ -155,18 +211,15 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
          */
     	function write_file($object,$outputlangs='',$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$hookmanager,$mysoc,$nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    -		$outputlangs->load("orders");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "orders", "companies", "bills", "dict", "products"));
     
     		$nblignes = count($object->lines);
     
    @@ -238,7 +291,6 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     					$this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir);
     					return 0;
     				}
    -
     			}
     
     			if (file_exists($dir))
    @@ -650,6 +702,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show payments table
     	 *
    @@ -661,10 +714,11 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    -
    +        // phpcs:enable
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -676,6 +730,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     	    global $conf;
     	    $default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -728,10 +783,11 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     		return $posy;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *	Show total to pay
    +	 *  Show total to pay
     	 *
    -	 *	@param	PDF			$pdf           Object PDF
    +	 *  @param	PDF			$pdf           Object PDF
     	 *	@param  Facture		$object         Object invoice
     	 *	@param  int			$deja_regle     Montant deja regle
     	 *	@param	int			$posy			Position depart
    @@ -740,6 +796,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1065,13 +1122,10 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     	 */
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
    -		global $langs,$conf,$mysoc;
    +		global $langs, $conf, $mysoc;
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("orders");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("sendings");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings"));
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -1317,5 +1371,4 @@ class pdf_muscadet extends ModelePDFSuppliersOrders
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'SUPPLIER_ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    diff --git a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php
    index f9567a32a5c..2a31f265097 100644
    --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php
    +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php
    @@ -38,23 +38,78 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functionsnumtoword.lib.php';
      */
     class pdf_standard extends ModelePDFSuppliersPayments
     {
    -    var $db;
    -    var $name;
    -    var $description;
    -    var $type;
    +    /**
    +     * @var DoliDb Database handler
    +     */
    +    public $db;
     
    -    var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -    var $version = 'dolibarr';
    +	/**
    +     * @var string model name
    +     */
    +    public $name;
     
    -    var $page_largeur;
    -    var $page_hauteur;
    -    var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	/**
    +     * @var string model description (short text)
    +     */
    +    public $description;
     
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +     * @var string document type
    +     */
    +    public $type;
    +
    +    /**
    +     * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +     */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';
    +
    +	/**
    +     * @var int page_largeur
    +     */
    +    public $page_largeur;
    +
    +	/**
    +     * @var int page_hauteur
    +     */
    +    public $page_hauteur;
    +
    +	/**
    +     * @var array format
    +     */
    +    public $format;
    +
    +	/**
    +     * @var int marge_gauche
    +     */
    +	public $marge_gauche;
    +
    +	/**
    +     * @var int marge_droite
    +     */
    +	public $marge_droite;
    +
    +	/**
    +     * @var int marge_haute
    +     */
    +	public $marge_haute;
    +
    +	/**
    +     * @var int marge_basse
    +     */
    +	public $marge_basse;
    +
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
     
     	/**
    @@ -64,9 +119,9 @@ class pdf_standard extends ModelePDFSuppliersPayments
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    -		
    -		// Translations
    +		global $conf, $langs, $mysoc;
    +
    +		// Load translation files required by the page
     		$langs->loadLangs(array("main", "bills"));
     
     		$this->db = $db;
    @@ -121,7 +176,8 @@ class pdf_standard extends ModelePDFSuppliersPayments
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		PaiementFourn		$object				Id of object to generate
    @@ -131,21 +187,19 @@ class pdf_standard extends ModelePDFSuppliersPayments
          *  @param		int					$hidedesc			Do not show desc
          *  @param		int					$hideref			Do not show ref
          *  @return		int										1=OK, 0=KO
    -	 */
    +     */
     	function write_file($object, $outputlangs='', $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
     	{
    -		global $user,$langs,$conf,$mysoc,$hookmanager;
    +        // phpcs:enable
    +		global $user, $langs, $conf, $mysoc, $hookmanager;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("products");
    -		$outputlangs->load("suppliers");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "suppliers", "companies", "bills", "dict", "products"));
    +
     		$object->factures = array();
     
     		if ($conf->fournisseur->payment->dir_output)
    @@ -457,6 +511,7 @@ class pdf_standard extends ModelePDFSuppliersPayments
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -468,6 +523,7 @@ class pdf_standard extends ModelePDFSuppliersPayments
     	 */
     	function _tableau_cheque(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     
             $default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -512,7 +568,6 @@ class pdf_standard extends ModelePDFSuppliersPayments
     		// Date
     		$pdf->SetXY($this->page_largeur - $this->marge_droite - 30, $posy);
     		$pdf->MultiCell(150, 4, date("d").' '.$outputlangs->transnoentitiesnoconv(date("F")).' '.date("Y"), 0, 'L', 1);
    -
     	}
     
     
    @@ -558,7 +613,6 @@ class pdf_standard extends ModelePDFSuppliersPayments
     
     		// Output Rect
     		//$this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom);	// Rect prend une longueur en 3eme param et 4eme param
    -
     	}
     
     
    @@ -573,12 +627,11 @@ class pdf_standard extends ModelePDFSuppliersPayments
     	 */
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
    -		global $langs,$conf,$mysoc;
    +		global $langs, $conf, $mysoc;
    +
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "orders", "companies", "bills"));
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("bills");
    -		$outputlangs->load("orders");
    -		$outputlangs->load("companies");
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
     		// Do not add the BACKGROUND as this is for suppliers
    @@ -757,6 +810,4 @@ class pdf_standard extends ModelePDFSuppliersPayments
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'SUPPLIER_INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
    index 97c7b077b22..216bc4bde90 100644
    --- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
    +++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php
    @@ -30,9 +30,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_payment/modules_supplier
      */
     class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Brodator';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Brodator';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Brodator';
     
     
         /**
    @@ -42,7 +61,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -124,6 +143,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -133,8 +153,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments
          */
         function commande_get_num($objsoc,$objforref)
         {
    +        // phpcs:enable
             return $this->getNextValue($objsoc,$objforref);
         }
    -
     }
    -
    diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php
    index 9b0012ec089..0d64991065a 100644
    --- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php
    +++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php
    @@ -29,10 +29,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_payment/modules_supplier
      */
     class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='SPAY';
    -	var $error='';
    -	var $nom='Bronan';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='SPAY';
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Bronan';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Bronan';
     
     
         /**
    @@ -135,6 +155,7 @@ class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return next free value
     	 *
    @@ -144,7 +165,7 @@ class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments
     	 */
     	function payment_get_num($objsoc,$objforref)
     	{
    +        // phpcs:enable
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/supplier_payment/modules_supplier_payment.php b/htdocs/core/modules/supplier_payment/modules_supplier_payment.php
    index 56c5bd94ae0..8eb706dc0ce 100644
    --- a/htdocs/core/modules/supplier_payment/modules_supplier_payment.php
    +++ b/htdocs/core/modules/supplier_payment/modules_supplier_payment.php
    @@ -22,18 +22,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
      */
     abstract class ModelePDFSuppliersPayments extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of active generation models
     	 *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of numbers
    -	 */
    +     */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='supplier_payment';
    @@ -44,7 +49,6 @@ abstract class ModelePDFSuppliersPayments extends CommonDocGenerator
     
     		return $liste;
     	}
    -
     }
     
     /**
    @@ -54,7 +58,10 @@ abstract class ModelePDFSuppliersPayments extends CommonDocGenerator
     
     abstract class ModeleNumRefSupplierPayments
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 *	Return if a module can be used or not
    diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
    index a8497416501..05bfe535ac7 100644
    --- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
    +++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
     *
     * 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,10 +38,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +   * Dolibarr version of the loaded document
    +   * @public string
    +   */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -50,10 +64,10 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -95,10 +109,10 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     	 */
     	function info($langs)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array('companies', 'errors'));
     
     		$form = new Form($this->db);
     
    @@ -207,6 +221,7 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -220,7 +235,8 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    -		global $user,$langs,$conf,$mysoc,$hookmanager;
    +        // phpcs:enable
    +		global $user, $langs, $conf, $mysoc, $hookmanager;
     
     		if (empty($srctemplatepath))
     		{
    @@ -241,10 +257,8 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "companies", "bills", "dict"));
     
     		if ($conf->supplier_proposal->dir_output)
     		{
    @@ -354,16 +368,17 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     					$odfHandler = new odf(
     						$srctemplatepath,
     						array(
    -						'PATH_TO_TMP'	  => $conf->supplier_proposal->dir_temp,
    -						'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    -						'DELIMITER_LEFT'  => '{',
    -						'DELIMITER_RIGHT' => '}'
    +							'PATH_TO_TMP'	  => $conf->supplier_proposal->dir_temp,
    +							'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    +							'DELIMITER_LEFT'  => '{',
    +							'DELIMITER_RIGHT' => '}'
     						)
     					);
     				}
    -				catch(Exception $e)
    +				catch (Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -377,8 +392,9 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -411,6 +427,7 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -443,9 +460,11 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     								}
     								catch(OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -469,6 +488,7 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -480,16 +500,18 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
     				else {
     					try {
    -					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +						$odfHandler->saveToDisk($file);
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -514,6 +536,4 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
    index bca4ae8425f..544a1040c9f 100644
    --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
    +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php
    @@ -42,17 +42,17 @@ class pdf_aurore extends ModelePDFSupplierProposal
          * @var DoliDb Database handler
          */
         public $db;
    -	
    +
     	/**
          * @var string model name
          */
         public $name;
    -	
    +
     	/**
          * @var string model description (short text)
          */
         public $description;
    -	
    +
     	/**
          * @var string document type
          */
    @@ -60,10 +60,10 @@ class pdf_aurore extends ModelePDFSupplierProposal
     
     	/**
          * @var array() Minimum version of PHP required by module.
    -	 * e.g.: PHP ≥ 5.3 = array(5, 3)
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
          */
    -	public $phpmin = array(5, 2); 
    -	
    +	public $phpmin = array(5, 4);
    +
     	/**
          * Dolibarr version of the loaded document
          * @public string
    @@ -74,32 +74,32 @@ class pdf_aurore extends ModelePDFSupplierProposal
          * @var int page_largeur
          */
         public $page_largeur;
    -	
    +
     	/**
          * @var int page_hauteur
          */
         public $page_hauteur;
    -	
    +
     	/**
          * @var array format
          */
         public $format;
    -	
    +
     	/**
          * @var int marge_gauche
          */
     	public $marge_gauche;
    -	
    +
     	/**
          * @var int marge_droite
          */
     	public $marge_droite;
    -	
    +
     	/**
          * @var int marge_haute
          */
     	public $marge_haute;
    -	
    +
     	/**
          * @var int marge_basse
          */
    @@ -120,7 +120,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	public function __construct($db)
     	{
     		global $conf, $langs, $mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
     
    @@ -160,7 +160,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     		$this->posxdesc=$this->marge_gauche+1;
     		$this->posxdiscount=162;
     		$this->postotalht=174;
    -		
    +
     		if ($conf->global->PRODUCT_USE_UNITS)
     		{
     		    $this->posxtva=101;
    @@ -172,7 +172,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     		    $this->posxup=126;
     		    $this->posxqty=145;
     		}
    -		
    +
     		if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) || ! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) $this->posxup=$this->posxtva;
     		$this->posxpicture=$this->posxtva - (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH);	// width of images
     		if ($this->page_largeur < 210) // To work with US executive format
    @@ -193,7 +193,8 @@ class pdf_aurore extends ModelePDFSupplierProposal
     		$this->atleastonediscount=0;
     	}
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -206,13 +207,14 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
     		// For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     		if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -		
    -		// Translations
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "supplier_proposal"));
     
     		$nblignes = count($object->lines);
    @@ -375,7 +377,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     				{
     					$tab_top -= 2;
     
    -          $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
    +                    $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     					complete_substitutions_array($substitutionarray, $outputlangs, $object);
     					$notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
     
    @@ -524,7 +526,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     					{
     					    $pdf->MultiCell($this->posxdiscount-$this->posxqty-0.8, 3, $qty, 0, 'R');
     					}
    -					
    +
     					// Unit
     					if($conf->global->PRODUCT_USE_UNITS)
     					{
    @@ -696,6 +698,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Show payments table
     	 *
    @@ -707,10 +710,11 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    -
    +        // phpcs:enable
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
    @@ -722,6 +726,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -877,6 +882,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Show total to pay
     	 *
    @@ -889,6 +895,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +        // phpcs:enable
     		global $conf,$mysoc;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -990,7 +997,6 @@ class pdf_aurore extends ModelePDFSupplierProposal
     
     								$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
     								$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
    -
     							}
     						}
     					}
    @@ -1232,7 +1238,7 @@ class pdf_aurore extends ModelePDFSupplierProposal
     		        $pdf->MultiCell($this->posxdiscount-$this->posxqty-1,2, $outputlangs->transnoentities("Qty"),'','C');
     		    }
     		}
    -		
    +
     		if($conf->global->PRODUCT_USE_UNITS) {
     		    $pdf->line($this->posxunit - 1, $tab_top, $this->posxunit - 1, $tab_top + $tab_height);
     		    if (empty($hidetop)) {
    @@ -1273,9 +1279,9 @@ class pdf_aurore extends ModelePDFSupplierProposal
     	 */
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
    -		global $conf,$langs;
    -		
    -		// Translations
    +		global $conf, $langs;
    +
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array("main", "bills", "supplier_proposal", "companies"));
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1494,6 +1500,4 @@ class pdf_aurore extends ModelePDFSupplierProposal
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'SUPPLIER_PROPOSAL_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php
    index fa8cf6c6460..e7fb65f7612 100644
    --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php
    +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php
    @@ -31,10 +31,30 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_proposal/modules_supplie
      */
     class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $prefix='RQ';               // RQ = Request for quotation
    -	var $error='';
    -	var $nom = "Marbre";
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	public $prefix='RQ';               // RQ = Request for quotation
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Marbre';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Marbre';
     
     
         /**
    @@ -149,5 +169,4 @@ class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal
     	{
     		return $this->getNextValue($objsoc,$objforref);
     	}
    -
     }
    diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php
    index 8781628917f..4827acdc9c8 100644
    --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php
    +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php
    @@ -33,9 +33,28 @@ require_once DOL_DOCUMENT_ROOT .'/core/modules/supplier_proposal/modules_supplie
      */
     class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal
     {
    -	var $version='dolibarr';		// 'development', 'experimental', 'dolibarr'
    -	var $error = '';
    -	var $nom = 'Saphir';
    +	/**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr';		// 'development', 'experimental', 'dolibarr'
    +
    +	/**
    +     * @var string Error code (or message)
    +     */
    +    public $error = '';
    +
    +	/**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Saphir';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Saphir';
     
     
         /**
    @@ -45,7 +64,7 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal
          */
     	function info()
         {
    -    	global $conf,$langs;
    +    	global $conf, $langs;
     
     		$langs->load("bills");
     
    @@ -127,5 +146,4 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal
     
     		return  $numFinal;
     	}
    -
     }
    diff --git a/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php b/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php
    index b324a1b03a8..df7c5ba7553 100644
    --- a/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php
    +++ b/htdocs/core/modules/supplier_proposal/modules_supplier_proposal.php
    @@ -36,18 +36,23 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';   // Requ
      */
     abstract class ModelePDFSupplierProposal extends CommonDocGenerator
     {
    -	var $error='';
    -
    -
     	/**
    -	 *  Return list of active generation modules
    -	 *
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     *  Return list of active generation modules
    +     *
          *  @param	DoliDB	$db     			Database handler
          *  @param  integer	$maxfilenamelength  Max length of value to show
          *  @return	array						List of templates
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='supplier_proposal';
    @@ -66,7 +71,10 @@ abstract class ModelePDFSupplierProposal extends CommonDocGenerator
      */
     abstract class ModeleNumRefSupplierProposal
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	/**
     	 * Return if a module can be used or not
    diff --git a/htdocs/core/modules/syslog/mod_syslog_chromephp.php b/htdocs/core/modules/syslog/mod_syslog_chromephp.php
    index a9b9ccd5836..2617cdb269d 100644
    --- a/htdocs/core/modules/syslog/mod_syslog_chromephp.php
    +++ b/htdocs/core/modules/syslog/mod_syslog_chromephp.php
    @@ -66,8 +66,8 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface
     			}
     			set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH);
     
    -		    $res = @include_once('ChromePhp.php');
    -		    if (! $res) $res=@include_once('ChromePhp.class.php');
    +		    $res = @include_once 'ChromePhp.php';
    +		    if (! $res) $res=@include_once 'ChromePhp.class.php';
     
     		    restore_include_path();
     
    @@ -121,13 +121,14 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface
     
     		if (! file_exists($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH.'/ChromePhp.php') && ! file_exists($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH.'/ChromePhp.class.php'))
     		{
    +			$conf->global->MAIN_SYSLOG_DISABLE_CHROMEPHP = 1; // avoid infinite loop
     			if (is_object($langs))   // $langs may not be defined yet.
     			{
    -			    $errors[] = $langs->trans("ErrorFailedToOpenFile", 'ChromePhp.class.php or ChromePhp.php');
    +				$errors[] = $langs->trans("ErrorFailedToOpenFile", 'ChromePhp.class.php or ChromePhp.php');
     			}
     			else
     			{
    -		        $errors[] = "ErrorFailedToOpenFile ChromePhp.class.php or ChromePhp.php";
    +				$errors[] = "ErrorFailedToOpenFile ChromePhp.class.php or ChromePhp.php";
     			}
     		}
     
    @@ -151,12 +152,12 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface
     
     		try
     		{
    -			// Warning ChromePHP must be into PHP include path. It is not possible to use into require_once() a constant from
    +			// Warning ChromePHP must be into PHP include path. It is not possible to use into require_once a constant from
     			// database or config file because we must be able to log data before database or config file read.
     			$oldinclude=get_include_path();
     			set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH);
    -		    $res = @include_once('ChromePhp.php');
    -		    if (! $res) $res=@include_once('ChromePhp.class.php');
    +		    $res = @include_once 'ChromePhp.php';
    +		    if (! $res) $res=@include_once 'ChromePhp.class.php';
     			set_include_path($oldinclude);
     			
     			ob_start();	// To be sure headers are not flushed until all page is completely processed
    diff --git a/htdocs/core/modules/syslog/mod_syslog_firephp.php b/htdocs/core/modules/syslog/mod_syslog_firephp.php
    index 69bc98230af..abc341f9a30 100644
    --- a/htdocs/core/modules/syslog/mod_syslog_firephp.php
    +++ b/htdocs/core/modules/syslog/mod_syslog_firephp.php
    @@ -122,7 +122,15 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface
     
     		if (!file_exists($conf->global->SYSLOG_FIREPHP_INCLUDEPATH . self::$firephp_class_path))
     		{
    -			$errors[] = $langs->trans("ErrorFailedToOpenFile", self::$firephp_class_path);
    +			$conf->global->MAIN_SYSLOG_DISABLE_FIREPHP = 1; // avoid infinite loop
    +			if (is_object($langs))   // $langs may not be defined yet.
    +			{
    +				$errors[] = $langs->trans("ErrorFailedToOpenFile", self::$firephp_class_path);
    +			}
    +			else
    +			{
    +				$errors[] = "ErrorFailedToOpenFile " . self::$firephp_class_path;
    +			}
     		}
     
     		return $errors;
    @@ -145,7 +153,7 @@ class mod_syslog_firephp extends LogHandler implements LogHandlerInterface
     
     		try
     		{
    -			// Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once() a constant from
    +			// Warning FirePHPCore must be into PHP include path. It is not possible to use into require_once a constant from
     			// database or config file because we must be able to log data before database or config file read.
     			$oldinclude=get_include_path();
     			set_include_path($conf->global->SYSLOG_FIREPHP_INCLUDEPATH);
    diff --git a/htdocs/core/modules/ticket/mod_ticket_simple.php b/htdocs/core/modules/ticket/mod_ticket_simple.php
    index b70b9babd05..c744453a899 100644
    --- a/htdocs/core/modules/ticket/mod_ticket_simple.php
    +++ b/htdocs/core/modules/ticket/mod_ticket_simple.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2010-2012    Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2010        Laurent Destailleur    <eldy@users.sourceforge.net>
    +/* Copyright (C) 2010-2012   Regis Houssin        <regis.houssin@capnetworks.com>
    + * Copyright (C) 2010        Laurent Destailleur  <eldy@users.sourceforge.net>
      *
      * 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
    @@ -30,11 +30,30 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/ticket/modules_ticket.php';
      */
     class mod_ticket_simple extends ModeleNumRefTicket
     {
    -    public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
    +    /**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
    +	public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
    +
         public $prefix = 'TS';
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
         public $error = '';
    -    public $nom = "Simple";
    -    public $name = "Simple";
    +
    +    /**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Simple';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Simple';
     
         /**
          *  Return description of numbering module
    @@ -140,5 +159,4 @@ class mod_ticket_simple extends ModeleNumRefTicket
             dol_syslog("mod_ticket_simple::getNextValue return " . $this->prefix . $yymm . "-" . $num);
             return $this->prefix . $yymm . "-" . $num;
         }
    -
     }
    diff --git a/htdocs/core/modules/ticket/mod_ticket_universal.php b/htdocs/core/modules/ticket/mod_ticket_universal.php
    index 2d521f18a5b..a8170935eb0 100644
    --- a/htdocs/core/modules/ticket/mod_ticket_universal.php
    +++ b/htdocs/core/modules/ticket/mod_ticket_universal.php
    @@ -29,10 +29,28 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/ticket/modules_ticket.php';
      */
     class mod_ticket_universal extends ModeleNumRefTicket
     {
    +    /**
    +     * Dolibarr version of the loaded document
    +     * @public string
    +     */
         public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr'
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
         public $error = '';
    -    public $nom = 'Universal';
    -    public $name = 'Universal';
    +
    +    /**
    +	 * @var string Nom du modele
    +	 * @deprecated
    +	 * @see name
    +	 */
    +	public $nom='Universal';
    +
    +	/**
    +	 * @var string model name
    +	 */
    +	public $name='Universal';
     
         /**
          *  Renvoi la description du modele de numerotation
    @@ -43,8 +61,8 @@ class mod_ticket_universal extends ModeleNumRefTicket
         {
             global $conf, $langs;
     
    -        $langs->load("ticket");
    -        $langs->load("admin");
    +        // Load translation files required by the page
    +        $langs->loadLangs(array("ticket","admin"));
     
             $form = new Form($this->db);
     
    @@ -121,5 +139,4 @@ class mod_ticket_universal extends ModeleNumRefTicket
     
             return $numFinal;
         }
    -
     }
    diff --git a/htdocs/core/modules/ticket/modules_ticket.php b/htdocs/core/modules/ticket/modules_ticket.php
    index d6f8b06d0e8..28587825d34 100644
    --- a/htdocs/core/modules/ticket/modules_ticket.php
    +++ b/htdocs/core/modules/ticket/modules_ticket.php
    @@ -29,6 +29,9 @@
      */
     abstract class ModeleNumRefTicket
     {
    +    /**
    +     * @var string Error code (or message)
    +     */
         public $error = '';
     
         /**
    diff --git a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php
    index a2c15780e35..f8b6e5cdaba 100644
    --- a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php
    +++ b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
     *
     * 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
    @@ -35,10 +36,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_user_odt extends ModelePDFUser
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +   * Dolibarr version of the loaded document
    +   * @public string
    +   */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -48,10 +62,10 @@ class doc_generic_user_odt extends ModelePDFUser
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +    $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -93,10 +107,10 @@ class doc_generic_user_odt extends ModelePDFUser
     	 */
     	function info($langs)
     	{
    -		global $conf,$langs;
    +		global $conf, $langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array('companies', 'errors'));
     
     		$form = new Form($this->db);
     
    @@ -190,6 +204,7 @@ class doc_generic_user_odt extends ModelePDFUser
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -203,7 +218,8 @@ class doc_generic_user_odt extends ModelePDFUser
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    -		global $user,$langs,$conf,$mysoc,$hookmanager;
    +        // phpcs:enable
    +		global $user, $langs, $conf, $mysoc, $hookmanager;
     
     		if (empty($srctemplatepath))
     		{
    @@ -224,10 +240,8 @@ class doc_generic_user_odt extends ModelePDFUser
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "companies", "bills", "dict"));
     
     		if ($conf->user->dir_output)
     		{
    @@ -320,16 +334,17 @@ class doc_generic_user_odt extends ModelePDFUser
     					$odfHandler = new odf(
     						$srctemplatepath,
     						array(
    -						'PATH_TO_TMP'	  => $conf->user->dir_temp,
    -						'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    -						'DELIMITER_LEFT'  => '{',
    -						'DELIMITER_RIGHT' => '}'
    +							'PATH_TO_TMP'	  => $conf->user->dir_temp,
    +							'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    +							'DELIMITER_LEFT'  => '{',
    +							'DELIMITER_RIGHT' => '}'
     						)
     					);
     				}
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_WARNING);
     					return -1;
     				}
     
    @@ -364,6 +379,7 @@ class doc_generic_user_odt extends ModelePDFUser
     					}
     					catch(OdfException $e)
     					{
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     					}
     				}
     
    @@ -374,8 +390,9 @@ class doc_generic_user_odt extends ModelePDFUser
     					try {
     						$odfHandler->setVars($key, $value, true, 'UTF-8');
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     					}
     				}
     
    @@ -387,16 +404,18 @@ class doc_generic_user_odt extends ModelePDFUser
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     						return -1;
     					}
     				}
     				else {
     					try {
    -					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +						$odfHandler->saveToDisk($file);
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     						return -1;
     					}
     				}
    @@ -409,7 +428,7 @@ class doc_generic_user_odt extends ModelePDFUser
     				$odfHandler=null;	// Destroy object
     
     				$this->result = array('fullpath'=>$file);
    -				
    +
     				return 1;   // Success
     			}
     			else
    @@ -422,8 +441,19 @@ class doc_generic_user_odt extends ModelePDFUser
     		return -1;
     	}
     
    -	function get_substitutionarray_object($object,$outputlangs,$array_key='object') {
    -		$array_other=array();
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
    +     * get substitution array for object
    +     *
    +     * @param User          $object         user
    +     * @param Translate     $outputlangs    translation object
    +     * @param string        $array_key      key for array
    +     * @return array                        array of substitutions
    +     */
    +    function get_substitutionarray_object($object,$outputlangs,$array_key='object')
    +    {
    +        // phpcs:enable
    +		$array_other = array();
     		foreach($object as $key => $value) {
     			if (!is_array($value) && !is_object($value)) {
     				$array_other[$array_key.'_'.$key] = $value;
    @@ -431,6 +461,4 @@ class doc_generic_user_odt extends ModelePDFUser
     		}
     		return $array_other;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/user/modules_user.class.php b/htdocs/core/modules/user/modules_user.class.php
    index 3e94ece9372..e7f071f01fd 100644
    --- a/htdocs/core/modules/user/modules_user.class.php
    +++ b/htdocs/core/modules/user/modules_user.class.php
    @@ -24,7 +24,7 @@
      *	    \class      ModeleProductCode
      *		\brief  	Parent class for product code generators
      */
    - 
    +
     /**
      *  \file       htdocs/core/modules/contract/modules_contract.php
      *  \ingroup    contract
    @@ -32,15 +32,19 @@
      */
     
      require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
    - 
    +
     /**
      *	Parent class to manage intervention document templates
      */
     abstract class ModelePDFUser extends CommonDocGenerator
     {
    -	var $error='';
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return list of active generation modules
     	 *
    @@ -50,6 +54,7 @@ abstract class ModelePDFUser extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$type='user';
    @@ -59,4 +64,4 @@ abstract class ModelePDFUser extends CommonDocGenerator
     		$liste=getListOfModels($db,$type,$maxfilenamelength);
     		return $liste;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php
    index 443981907e0..1f7678371e5 100644
    --- a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php
    +++ b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2010-2012 	Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2012		Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
     *
     * 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,10 +38,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
      */
     class doc_generic_usergroup_odt extends ModelePDFUserGroup
     {
    -	var $emetteur;	// Objet societe qui emet
    +	/**
    +	 * Issuer
    +	 * @var Societe
    +	 */
    +	public $emetteur;
     
    -	var $phpmin = array(5,2,0);	// Minimum version of PHP required by module
    -	var $version = 'dolibarr';
    +	/**
    +   * @var array() Minimum version of PHP required by module.
    +	 * e.g.: PHP ≥ 5.4 = array(5, 4)
    +   */
    +	public $phpmin = array(5, 4);
    +
    +	/**
    +   * Dolibarr version of the loaded document
    +   * @public string
    +   */
    +	public $version = 'dolibarr';
     
     
     	/**
    @@ -50,10 +64,10 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     	 */
     	function __construct($db)
     	{
    -		global $conf,$langs,$mysoc;
    +		global $conf, $langs, $mysoc;
     
    -		$langs->load("main");
    -		$langs->load("companies");
    +		// Load translation files required by the page
    +    $langs->loadLangs(array("main","companies"));
     
     		$this->db = $db;
     		$this->name = "ODT templates";
    @@ -97,8 +111,8 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     	{
     		global $conf,$langs;
     
    -		$langs->load("companies");
    -		$langs->load("errors");
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("errors","companies"));
     
     		$form = new Form($this->db);
     
    @@ -192,6 +206,7 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     		return $texte;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Function to build a document on disk using the generic odt module.
     	 *
    @@ -205,7 +220,8 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    -		global $user,$langs,$conf,$mysoc,$hookmanager;
    +        // phpcs:enable
    +		global $user, $langs, $conf, $mysoc, $hookmanager;
     
     		if (empty($srctemplatepath))
     		{
    @@ -226,10 +242,8 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     		$sav_charset_output=$outputlangs->charset_output;
     		$outputlangs->charset_output='UTF-8';
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("dict");
    -		$outputlangs->load("companies");
    -		$outputlangs->load("bills");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "companies", "bills", "dict"));
     
     		if ($conf->user->dir_output)
     		{
    @@ -342,16 +356,15 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     					$odfHandler = new odf(
     						$srctemplatepath,
     						array(
    -						'PATH_TO_TMP'	  => $conf->user->dir_temp,
    -						'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    -						'DELIMITER_LEFT'  => '{',
    -						'DELIMITER_RIGHT' => '}'
    +							'PATH_TO_TMP'	  => $conf->user->dir_temp,
    +							'ZIP_PROXY'		  => 'PclZipProxy',	// PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
    +							'DELIMITER_LEFT'  => '{',
    +							'DELIMITER_RIGHT' => '}'
     						)
     					);
    -				}
    -				catch(Exception $e)
    -				{
    +				} catch (Exception $e) {
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_WARNING);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -365,8 +378,9 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     				try {
     					$odfHandler->setVars('free_text', $newfreetext, true, 'UTF-8');
     				}
    -				catch(OdfException $e)
    +				catch (OdfException $e)
     				{
    +					dol_syslog($e->getMessage(), LOG_WARNING);
     				}
     
     				// Make substitutions into odt
    @@ -401,8 +415,9 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     							$odfHandler->setVars($key, $value, true, 'UTF-8');
     						}
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     					}
     				}
     				// Replace tags of lines
    @@ -412,7 +427,7 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     					try {
     						$listlines = $odfHandler->setSegment('lines');
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
     						// We may arrive here if tags for lines not present into template
     						$foundtagforlines = 0;
    @@ -433,15 +448,17 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     							{
     								try
     								{
    -									if(!is_array($val)) {
    +									if (!is_array($val)) {
     										$listlines->setVars($key, $val, true, 'UTF-8');
     									}
     								}
    -								catch(OdfException $e)
    +								catch (OdfException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_WARNING);
     								}
    -								catch(SegmentException $e)
    +								catch (SegmentException $e)
     								{
    +									dol_syslog($e->getMessage(), LOG_WARNING);
     								}
     							}
     							$listlines->merge();
    @@ -458,39 +475,42 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     
     				// Replace labels translated
     				$tmparray=$outputlangs->get_translations_for_substitutions();
    -				foreach($tmparray as $key=>$value)
    +				foreach($tmparray as $key => $value)
     				{
     					try {
     						$odfHandler->setVars($key, $value, true, 'UTF-8');
     					}
    -					catch(OdfException $e)
    +					catch (OdfException $e)
     					{
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     					}
     				}
     
     				// Call the beforeODTSave hook
    -				$parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
    -				$reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +				$parameters=array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs);
    +				$reshook=$hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action);    // Note that $action and $object may have been modified by some hooks
     
     				// Write new file
     				if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
    -					}catch (Exception $e){
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     						return -1;
     					}
     				}
     				else {
     					try {
    -					$odfHandler->saveToDisk($file);
    -					}catch (Exception $e){
    +						$odfHandler->saveToDisk($file);
    +					} catch (Exception $e) {
     						$this->error=$e->getMessage();
    +						dol_syslog($e->getMessage(), LOG_WARNING);
     						return -1;
     					}
     				}
     
    -				$reshook=$hookmanager->executeHooks('afterODTCreation',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    +				$reshook=$hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action);    // Note that $action and $object may have been modified by some hooks
     
     				if (! empty($conf->global->MAIN_UMASK))
     					@chmod($file, octdec($conf->global->MAIN_UMASK));
    @@ -510,6 +530,4 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup
     
     		return -1;
     	}
    -
     }
    -
    diff --git a/htdocs/core/modules/usergroup/modules_usergroup.class.php b/htdocs/core/modules/usergroup/modules_usergroup.class.php
    index 26edb08d57c..caa79594080 100644
    --- a/htdocs/core/modules/usergroup/modules_usergroup.class.php
    +++ b/htdocs/core/modules/usergroup/modules_usergroup.class.php
    @@ -24,7 +24,7 @@
      *	    \class      ModeleProductCode
      *		\brief  	Parent class for product code generators
      */
    - 
    +
     /**
      *  \file       htdocs/core/modules/contract/modules_contract.php
      *  \ingroup    contract
    @@ -32,16 +32,20 @@
      */
     
      require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php';
    - 
    +
     /**
      *	Parent class to manage intervention document templates
      */
     abstract class ModelePDFUserGroup extends CommonDocGenerator
     {
    -	var $error='';
    -
    -
     	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
     	 *	Return list of active generation modules
     	 *
          *  @param	DoliDB	$db     			Database handler
    @@ -50,13 +54,14 @@ abstract class ModelePDFUserGroup extends CommonDocGenerator
     	 */
     	static function liste_modeles($db,$maxfilenamelength=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
    -		$type='group';
    -		$liste=array();
    +		$type = 'group';
    +		$list = array();
     
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    -		$liste=getListOfModels($db,$type,$maxfilenamelength);
    -		return $liste;
    +		$list = getListOfModels($db, $type, $maxfilenamelength);
    +		return $list;
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php
    index 3f266e700cc..f4f178031de 100644
    --- a/htdocs/core/photos_resize.php
    +++ b/htdocs/core/photos_resize.php
    @@ -28,8 +28,8 @@ require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
     
    -$langs->load("products");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("products","other"));
     
     $id=GETPOST('id','int');
     $action=GETPOST('action','alpha');
    diff --git a/htdocs/core/tools.php b/htdocs/core/tools.php
    index 25e2eb3f903..3ceaaf17d33 100644
    --- a/htdocs/core/tools.php
    +++ b/htdocs/core/tools.php
    @@ -24,8 +24,8 @@
     
     require '../main.inc.php';
     
    -$langs->load("companies");
    -$langs->load("other");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","other"));
     
     // Security check
     $socid=0;
    diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php
    index 6a59722e4d8..2c971c7a553 100644
    --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php
    +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2010-2017	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -52,6 +53,7 @@ $langs->load("modulebuilder");
         		var required = jQuery("#required");
         		var alwayseditable = jQuery("#alwayseditable");
         		var list = jQuery("#list");
    +            var totalizable = jQuery("#totalizable");
         		<?php
         		if ((GETPOST('type','alpha') != "select") && (GETPOST('type','alpha') != "sellist"))
         		{
    @@ -144,7 +146,7 @@ $langs->load("modulebuilder");
     
     <table summary="listofattributes" class="border centpercent">
     <!-- Label -->
    -<tr><td class="titlefield fieldrequired"><?php echo $langs->trans("Label"); ?></td><td class="valeur"><input type="text" name="label" size="40" value="<?php echo GETPOST('label','alpha'); ?>"></td></tr>
    +<tr><td class="titlefield fieldrequired"><?php echo $langs->trans("LabelOrTranslationKey"); ?></td><td class="valeur"><input type="text" name="label" size="40" value="<?php echo GETPOST('label','alpha'); ?>"></td></tr>
     <!-- Code -->
     <tr><td class="fieldrequired"><?php echo $langs->trans("AttributeCode"); ?></td><td class="valeur"><input type="text" name="attrname" id="attrname"  size="10" value="<?php echo GETPOST('attrname','alpha'); ?>"> (<?php echo $langs->trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)</td></tr>
     <!-- Type -->
    @@ -186,12 +188,17 @@ $langs->load("modulebuilder");
     <tr class="extra_required"><td><?php echo $langs->trans("Required"); ?></td><td class="valeur"><input id="required" type="checkbox" name="required"<?php echo (GETPOST('required','alpha')?' checked':''); ?>></td></tr>
     <!-- Always editable -->
     <tr class="extra_alwayseditable"><td><?php echo $langs->trans("AlwaysEditable"); ?></td><td class="valeur"><input id="alwayseditable" type="checkbox" name="alwayseditable"<?php echo ((GETPOST('alwayseditable','alpha') || ! GETPOST('button','alpha'))?' checked':''); ?>></td></tr>
    -<?php if ($conf->multicompany->enabled) { ?>
    -    <tr><td><?php echo $langs->trans("AllEntities"); ?></td><td class="valeur"><input id="entitycurrentorall" type="checkbox" name="entitycurrentorall"<?php echo (GETPOST('entitycurrentorall','alpha') ? '':' checked'); ?>></td></tr>
    -<?php } ?>
     <!-- Visibility -->
     <tr><td class="extra_list"><?php echo $form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?>
     </td><td class="valeur"><input id="list" class="minwidth100" type="text" name="list" value="<?php echo GETPOST('list','int')!='' ? GETPOST('list','int') : '1'; ?>"></td></tr>
    +<!-- Totalizable -->
    +<tr class="extra_totalizable"><td><?php echo $langs->trans("Totalizable"); ?></td><td class="valeur"><input id="totalizable" type="checkbox" name="totalizable"<?php echo ((GETPOST('totalizable','alpha') || GETPOST('button','alpha'))?' checked':''); ?>></td></tr>
    +<!-- Help tooltip -->
    +<tr class="help"><td><?php echo $form->textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?></td><td class="valeur"><input id="help" class="quatrevingtpercent" type="text" name="help" value="<?php echo dol_escape_htmltag($help); ?>"></td></tr>
    +<?php if ($conf->multicompany->enabled) { ?>
    +	<!-- Multicompany entity -->
    +    <tr><td><?php echo $langs->trans("AllEntities"); ?></td><td class="valeur"><input id="entitycurrentorall" type="checkbox" name="entitycurrentorall"<?php echo (GETPOST('entitycurrentorall','alpha') ? '':' checked'); ?>></td></tr>
    +<?php } ?>
     </table>
     
     <?php dol_fiche_end(); ?>
    diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
    index 3c3cc1858c5..d4dc2776fde 100644
    --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php
    +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2010-2012	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2012		Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -51,6 +52,7 @@ $langs->load("modulebuilder");
         		var required = jQuery("#required");
         		var alwayseditable = jQuery("#alwayseditable");
         		var list = jQuery("#list");
    +            var totalizable = jQuery("#totalizable");
         		<?php
         		if((GETPOST('type','alpha') != "select") &&  (GETPOST('type','alpha') != "sellist"))
         		{
    @@ -156,6 +158,8 @@ $param=$extrafields->attributes[$elementtype]['param'][$attrname];
     $perms=$extrafields->attributes[$elementtype]['perms'][$attrname];
     $langfile=$extrafields->attributes[$elementtype]['langfile'][$attrname];
     $list=$extrafields->attributes[$elementtype]['list'][$attrname];
    +$totalizable = $extrafields->attributes[$elementtype]['totalizable'][$attrname];
    +$help=$extrafields->attributes[$elementtype]['help'][$attrname];
     $entitycurrentorall=$extrafields->attributes[$elementtype]['entityid'][$attrname];
     
     if((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param))
    @@ -176,7 +180,7 @@ elseif (($type== 'sellist') || ($type == 'chkbxlst') || ($type == 'link') || ($t
     }
     ?>
     <!-- Label -->
    -<tr><td class="titlefield fieldrequired"><?php echo $langs->trans("Label"); ?></td><td class="valeur"><input type="text" name="label" size="40" value="<?php echo $label; ?>"></td></tr>
    +<tr><td class="titlefield fieldrequired"><?php echo $langs->trans("LabelOrTranslationKey"); ?></td><td class="valeur"><input type="text" name="label" size="40" value="<?php echo $label; ?>"></td></tr>
     <!-- Code -->
     <tr><td class="fieldrequired"><?php echo $langs->trans("AttributeCode"); ?></td><td class="valeur"><?php echo $attrname; ?></td></tr>
     <!-- Type -->
    @@ -248,12 +252,16 @@ else
     <tr class="extra_required"><td><?php echo $langs->trans("Required"); ?></td><td class="valeur"><input id="required" type="checkbox" name="required"<?php echo ($required?' checked':''); ?>></td></tr>
     <!-- Always editable -->
     <tr class="extra_alwayseditable"><td><?php echo $langs->trans("AlwaysEditable"); ?></td><td class="valeur"><input id="alwayseditable" type="checkbox" name="alwayseditable"<?php echo ($alwayseditable?' checked':''); ?>></td></tr>
    +<tr><td class="extra_list"><?php echo $form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?>
    +</td><td class="valeur"><input id="list" class="minwidth100" type="text" name="list" value="<?php echo ($list!=''?$list:'1'); ?>"></td></tr>
    +<tr class="extra_totalizable"><td><?php echo $form->textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")); ?></td><td class="valeur"><input id="totalizable" type="checkbox" name="totalizable"<?php echo ($totalizable?' checked':''); ?>></td></tr>
    +<!-- Help tooltip -->
    +<tr class="help"><td><?php echo $form->textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?></td><td class="valeur"><input id="help" class="quatrevingtpercent" type="text" name="help" value="<?php echo dol_escape_htmltag($help); ?>"></td></tr>
     <?php if ($conf->multicompany->enabled) { ?>
    +	<!-- Multicompany entity -->
         <tr><td><?php echo $langs->trans("AllEntities"); ?></td><td class="valeur"><input id="entitycurrentorall" type="checkbox" name="entitycurrentorall"<?php echo (empty($entitycurrentorall) ?' checked':''); ?>></td></tr>
     <?php } ?>
     <!-- Visibility -->
    -<tr><td class="extra_list"><?php echo $form->textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?>
    -</td><td class="valeur"><input id="list" class="minwidth100" type="text" name="list" value="<?php echo ($list!=''?$list:'1'); ?>"></td></tr>
     </table>
     
     <?php dol_fiche_end(); ?>
    diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php
    index 1b0a5303bec..2672e593820 100644
    --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php
    +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2010-2018	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2012-2017	Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -49,18 +50,21 @@ print '<table summary="listofattributes" class="noborder" width="100%">';
     
     print '<tr class="liste_titre">';
     print '<td align="left">'.$langs->trans("Position");
    -print '<span class="nowrap"><img src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/1downarrow.png" alt="" title="A-Z" class="imgdown"></span>';
    +print '<span class="nowrap">';
    +print img_picto('A-Z', '1downarrow.png');
    +print '</span>';
     print '</td>';
    -print '<td>'.$langs->trans("Label").'</td>';
    +print '<td>'.$langs->trans("LabelOrTranslationKey").'</td>';
     print '<td>'.$langs->trans("TranslationString").'</td>';
     print '<td>'.$langs->trans("AttributeCode").'</td>';
     print '<td>'.$langs->trans("Type").'</td>';
     print '<td align="right">'.$langs->trans("Size").'</td>';
    -print '<td align="center">'.$langs->trans("Unique").'</td>';
     print '<td>'.$langs->trans("ComputedFormula").'</td>';
    +print '<td align="center">'.$langs->trans("Unique").'</td>';
     print '<td align="center">'.$langs->trans("Required").'</td>';
     print '<td align="center">'.$langs->trans("AlwaysEditable").'</td>';
     print '<td align="center">'.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).'</td>';
    +print '<td align="center">'.$form->textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")).'</td>';
     if ($conf->multicompany->enabled)  {
     	print '<td align="center">'.$langs->trans("Entities").'</td>';
     }
    @@ -83,11 +87,12 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel
     		print "<td>".$key."</td>\n";
     		print "<td>".$type2label[$extrafields->attributes[$elementtype]['type'][$key]]."</td>\n";
     		print '<td align="right">'.$extrafields->attributes[$elementtype]['size'][$key]."</td>\n";
    -		print '<td align="center">'.yn($extrafields->attributes[$elementtype]['unique'][$key])."</td>\n";
     		print '<td>'.dol_trunc($extrafields->attributes[$elementtype]['computed'][$key], 20)."</td>\n";
    +		print '<td align="center">'.yn($extrafields->attributes[$elementtype]['unique'][$key])."</td>\n";
     		print '<td align="center">'.yn($extrafields->attributes[$elementtype]['required'][$key])."</td>\n";
     		print '<td align="center">'.yn($extrafields->attributes[$elementtype]['alwayseditable'][$key])."</td>\n";
     		print '<td align="center">'.$extrafields->attributes[$elementtype]['list'][$key]."</td>\n";
    +		print '<td align="center">'.yn($extrafields->attributes[$elementtype]['totalizable'][$key])."</td>\n";
     		if (! empty($conf->multicompany->enabled))  {
     			print '<td align="center">'.($extrafields->attributes[$elementtype]['entityid'][$key]==0?$langs->trans("All"):$extrafields->attributes[$elementtype]['entitylabel'][$key]).'</td>';
     		}
    diff --git a/htdocs/core/tpl/advtarget.tpl.php b/htdocs/core/tpl/advtarget.tpl.php
    index a25abbdde6a..15ab669bd9a 100644
    --- a/htdocs/core/tpl/advtarget.tpl.php
    +++ b/htdocs/core/tpl/advtarget.tpl.php
    @@ -1,9 +1,18 @@
     <?php
    -
    -/* 
    - * To change this license header, choose License Headers in Project Properties.
    - * To change this template file, choose Tools | Templates
    - * and open the template in the editor.
    +/*
    + *
    + * 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 <http://www.gnu.org/licenses/>.
      */
     
     print '<script type="text/javascript" language="javascript">
    @@ -36,8 +45,8 @@ print '<script type="text/javascript" language="javascript">
     		});
     	});
     </script>';
    -		
    -		
    +
    +
     		print_fiche_titre($langs->trans("AdvTgtTitle"));
     
     		print '<div class="tabBar">' . "\n";
    @@ -272,9 +281,9 @@ print '<script type="text/javascript" language="javascript">
     
     						print '<table class="nobordernopadding"><tr>';
     						print '<td>' . $langs->trans("AdvTgtStartDt") . '</td><td>';
    -						print $form->select_date('', 'options_' . $key . '_st_dt');
    +						print $form->selectDate('', 'options_' . $key . '_st_dt');
     						print '</td><td>' . $langs->trans("AdvTgtEndDt") . '</td><td>';
    -						print $form->select_date('', 'options_' . $key . '_end_dt');
    +						print $form->selectDate('', 'options_' . $key . '_end_dt');
     						print '</td></tr></table>';
     
     						print '</td><td>' . "\n";
    @@ -397,9 +406,9 @@ print '<script type="text/javascript" language="javascript">
     		print '</td><td>' . "\n";
     		print '<table class="nobordernopadding"><tr>';
     		print '<td>' . $langs->trans("AdvTgtStartDt") . '</td><td>';
    -		print $form->select_date($array_query['contact_create_st_dt'], 'contact_create_st_dt', 0, 0, 1, 'find_customer', 1, 1);
    +		print $form->selectDate($array_query['contact_create_st_dt'], 'contact_create_st_dt', 0, 0, 1, 'find_customer', 1, 1);
     		print '</td><td>' . $langs->trans("AdvTgtEndDt") . '</td><td>';
    -		print $form->select_date($array_query['contact_create_end_dt'], 'contact_create_end_dt', 0, 0, 1, 'find_customer', 1, 1);
    +		print $form->selectDate($array_query['contact_create_end_dt'], 'contact_create_end_dt', 0, 0, 1, 'find_customer', 1, 1);
     		print '</td></tr></table>';
     		print '</td><td>' . "\n";
     		print '</td></tr>' . "\n";
    @@ -412,9 +421,9 @@ print '<script type="text/javascript" language="javascript">
     		print '</td><td>' . "\n";
     		print '<table class="nobordernopadding"><tr>';
     		print '<td>' . $langs->trans("AdvTgtStartDt") . '</td><td>';
    -		print $form->select_date($array_query['contact_update_st_dt'], 'contact_update_st_dt', 0, 0, 1, 'find_customer', 1, 1);
    +		print $form->selectDate($array_query['contact_update_st_dt'], 'contact_update_st_dt', 0, 0, 1, 'find_customer', 1, 1);
     		print '</td><td>' . $langs->trans("AdvTgtEndDt") . '</td><td>';
    -		print $form->select_date($array_query['contact_update_end_dt'], 'contact_update_end_dt', 0, 0, 1, 'find_customer', 1, 1);
    +		print $form->selectDate($array_query['contact_update_end_dt'], 'contact_update_end_dt', 0, 0, 1, 'find_customer', 1, 1);
     		print '</td></tr></table>';
     		print '</td><td>' . "\n";
     		print '</td></tr>' . "\n";
    @@ -461,9 +470,9 @@ print '<script type="text/javascript" language="javascript">
     
     					print '<table class="nobordernopadding"><tr>';
     					print '<td>' . $langs->trans("AdvTgtStartDt") . '</td><td>';
    -					print $form->select_date('', 'options_' . $key . '_st_dt' . '_cnct');
    +					print $form->selectDate('', 'options_' . $key . '_st_dt' . '_cnct');
     					print '</td><td>' . $langs->trans("AdvTgtEndDt") . '</td><td>';
    -					print $form->select_date('', 'options_' . $key . '_end_dt' . '_cnct');
    +					print $form->selectDate('', 'options_' . $key . '_end_dt' . '_cnct');
     					print '</td></tr></table>';
     
     					print '</td><td>' . "\n";
    diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php
    index b6f11828ffe..0d1fd84923c 100644
    --- a/htdocs/core/tpl/card_presend.tpl.php
    +++ b/htdocs/core/tpl/card_presend.tpl.php
    @@ -74,6 +74,7 @@ if ($action == 'presend')
     	{
     		$outputlangs = new Translate('', $conf);
     		$outputlangs->setDefaultLang($newlang);
    +		// Load traductions files requiredby by page
     		$outputlangs->loadLangs(array('commercial','bills','orders','contracts','members','propal','products','supplier_proposal','interventions'));
     	}
     
    @@ -168,7 +169,6 @@ if ($action == 'presend')
     			$formmail->withtouser = $listeuser;
     			$formmail->withtoccuser = $listeuser;
     		}
    -
     	}
     
     	$formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste;
    diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php
    index 99ae9a699a1..cc361be5e60 100644
    --- a/htdocs/core/tpl/contacts.tpl.php
    +++ b/htdocs/core/tpl/contacts.tpl.php
    @@ -199,12 +199,12 @@ if ($permission) {
     			if ($tab[$i]['source']=='internal')
     			{
     				$userstatic->fetch($tab[$i]['id']);
    -				echo $userstatic->getNomUrl(-1);
    +				echo $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle');
     			}
     			if ($tab[$i]['source']=='external')
     			{
     				$contactstatic->fetch($tab[$i]['id']);
    -				echo $contactstatic->getNomUrl(1);
    +				echo $contactstatic->getNomUrl(1, '', 0, 0, 0, 0, '', 'valignmiddle');
     			}
     			?>
     		</div>
    diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php
    index aa7caaa1e87..429fe8ac682 100644
    --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php
    +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php
    @@ -52,7 +52,7 @@ if (in_array($modulepart, array('product', 'produit', 'societe', 'user', 'ticket
     if ($action == 'delete')
     {
     	$langs->load("companies");	// Need for string DeleteFile+ConfirmDeleteFiles
    -	$ret = $form->form_confirm(
    +	print $form->formconfirm(
     			$_SERVER["PHP_SELF"] . '?id=' . $object->id . '&urlfile=' . urlencode(GETPOST("urlfile")) . '&linkid=' . GETPOST('linkid', 'int') . (empty($param)?'':$param),
     			$langs->trans('DeleteFile'),
     			$langs->trans('ConfirmDeleteFile'),
    @@ -61,7 +61,6 @@ if ($action == 'delete')
     			0,
     			1
     	);
    -	if ($ret == 'html') print '<br>';
     }
     
     $formfile=new FormFile($db);
    diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    index d7b5f67adaf..6b6d22cf822 100644
    --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    @@ -40,6 +40,14 @@ if (! empty($extrafieldsobjectkey))	// $extrafieldsobject is the $object->table_
     				print $extrafields->showOutputField($key, $value, '', $extrafieldsobjectkey);
     				print '</td>';
     				if (! $i) $totalarray['nbfield']++;
    +
    +                if ($extrafields->attributes[$extrafieldsobjectkey]['totalizable'][$key]) {
    +                    if (! $i) {
    +                        // we keep position for the first line
    +                        $totalarray['totalizable'][$key]['pos'] = $totalarray['nbfield'];
    +                    }
    +                    $totalarray['totalizable'][$key]['total'] += $obj->$tmpkey;
    +                }
     				if (! empty($val['isameasure']))
     				{
     					if (! $i) $totalarray['pos'][$totalarray['nbfield']]='ef.'.$tmpkey;
    diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php
    index 7253474c36b..ed093e4c506 100644
    --- a/htdocs/core/tpl/extrafields_view.tpl.php
    +++ b/htdocs/core/tpl/extrafields_view.tpl.php
    @@ -24,34 +24,36 @@
      * $parameters
      * $cols
      */
    -
     // Protection to avoid direct call of template
     if (empty($object) || ! is_object($object))
     {
     	print "Error, template page can't be called as URL";
     	exit;
     }
    +
     if (! is_object($form)) $form=new Form($db);
     
    +
     ?>
     <!-- BEGIN PHP TEMPLATE extrafields_view.tpl.php -->
     <?php
    -
     if (! is_array($parameters)) $parameters = array();
     if (! empty($cols)) $parameters['colspan'] = ' colspan="'.$cols.'"';
     if (! empty($cols)) $parameters['cols'] = $cols;
     if (! empty($object->fk_soc)) $parameters['socid'] = $object->fk_soc;
    -
     $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);
     print $hookmanager->resPrint;
     if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
     
    +
     //var_dump($extrafields->attributes[$object->table_element]);
     if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]['label']))
    +
     {
     	foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label)
     	{
     		// Discard if extrafield is a hidden field on form
    +
     		$enabled = 1;
     		if ($enabled && isset($extrafields->attributes[$object->table_element]['enabled'][$key]))
     		{
    @@ -74,7 +76,6 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
     
     		// Load language if required
     		if (! empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]);
    -
     		if ($action == 'edit_extras')
     		{
     			$value = (isset($_POST["options_" . $key]) ? $_POST["options_" . $key] : $object->array_options["options_" . $key]);
    @@ -96,27 +97,25 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
     			print '<td';
     			print ' class="';
     			//var_dump($action);exit;
    +
     			if ((! empty($action) && ($action == 'create' || $action == 'edit')) && ! empty($extrafields->attributes[$object->table_element]['required'][$key])) print ' fieldrequired';
     			print '">';
    -			if (! empty($extrafields->attributes[$object->table_element]['help'][$key])) print $form->textwithpicto($langs->trans($label), $extrafields->attributes[$object->table_element]['help'][$key]);
    +			if (! empty($extrafields->attributes[$object->table_element]['help'][$key])) print $form->textwithpicto($langs->trans($label), $langs->trans($extrafields->attributes[$object->table_element]['help'][$key]));
     			else print $langs->trans($label);
     			print '</td>';
     
     			//TODO Improve element and rights detection
     			//var_dump($user->rights);
     			$permok=false;
    -
     			$keyforperm=$object->element;
     			if ($object->element == 'fichinter') $keyforperm='ficheinter';
     			if (isset($user->rights->$keyforperm)) $permok=$user->rights->$keyforperm->creer||$user->rights->$keyforperm->create||$user->rights->$keyforperm->write;
    -
     			if ($object->element=='order_supplier')   $permok=$user->rights->fournisseur->commande->creer;
     			if ($object->element=='invoice_supplier') $permok=$user->rights->fournisseur->facture->creer;
     			if ($object->element=='shipping')         $permok=$user->rights->expedition->creer;
     			if ($object->element=='delivery')         $permok=$user->rights->expedition->livraison->creer;
     			if ($object->element=='productlot')       $permok=$user->rights->stock->creer;
     			if ($object->element=='facturerec') 	  $permok=$user->rights->facture->creer;
    -
     			if (($object->statut == 0 || ! empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key]))
     				&& $permok && ($action != 'edit_extras' || GETPOST('attribute') != $key)
     			    && empty($extrafields->attributes[$object->table_element]['computed'][$key]))
    @@ -129,6 +128,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
     			print '</td>';
     
     			$html_id = !empty($object->id) ? $object->element.'_extras_'.$key.'_'.$object->id : '';
    +
     			print '<td id="'.$html_id.'" class="'.$object->element.'_extras_'.$key.'"'.($cols?' colspan="'.$cols.'"':'').'>';
     
     			// Convert date into timestamp format
    @@ -143,21 +143,19 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
     				//print 'x'.$object->array_options['options_' . $key].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour');
     				$value = isset($_POST["options_" . $key]) ? dol_mktime($_POST["options_" . $key . "hour"], $_POST["options_" . $key . "min"], 0, $_POST["options_" . $key . "month"], $_POST["options_" . $key . "day"], $_POST["options_" . $key . "year"]) : $datenotinstring;
     			}
    -
     			//TODO Improve element and rights detection
     			if ($action == 'edit_extras' && $permok && GETPOST('attribute','none') == $key)
     			{
     			    $fieldid='id';
     			    if ($object->table_element == 'societe') $fieldid='socid';
    -
     			    print '<form enctype="multipart/form-data" action="' . $_SERVER["PHP_SELF"] . '" method="post" name="formextra">';
     				print '<input type="hidden" name="action" value="update_extras">';
     				print '<input type="hidden" name="attribute" value="' . $key . '">';
     				print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
     				print '<input type="hidden" name="'.$fieldid.'" value="' . $object->id . '">';
    -
     				print $extrafields->showInputField($key, $value, '', '', '', 0, $object->id);
     
    +
     				print '<input type="submit" class="button" value="' . dol_escape_htmltag($langs->trans('Modify')) . '">';
     
     				print '</form>';
    @@ -167,6 +165,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
     				//print $key.'-'.$value.'-'.$object->table_element;
     				print $extrafields->showOutputField($key, $value, '', $object->table_element);
     			}
    +
     			print '</td>';
     			print '</tr>' . "\n";
     		}
    @@ -203,11 +202,10 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element]
     								});
     					    	});
     						}
    -
     						setListDependencies();
     				    });
     				</script>'."\n";
     	}
     }
     ?>
    -<!-- END PHP TEMPLATE extrafields_view.tpl.php -->
    \ No newline at end of file
    +<!-- END PHP TEMPLATE extrafields_view.tpl.php -->
    diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php
    index b60941f4eeb..5ee19aa25a8 100644
    --- a/htdocs/core/tpl/filemanager.tpl.php
    +++ b/htdocs/core/tpl/filemanager.tpl.php
    @@ -28,7 +28,7 @@ if (empty($conf) || ! is_object($conf))
     ?>
     
     <!-- BEGIN PHP TEMPLATE core/tpl/filemanager.tpl.php -->
    -<!-- Doc of fileTree plugin at http://www.abeautifulsite.net/blog/2008/03/jquery-file-tree/ -->
    +<!-- Doc of fileTree plugin at https://www.abeautifulsite.net/jquery-file-tree -->
     
     <?php
     
    @@ -38,15 +38,18 @@ if (empty($module)) $module='ecm';
     
     $permtoadd = 0;
     $permtoupload = 0;
    +$showroot = 0;
     if ($module == 'ecm')
     {
     	$permtoadd = $user->rights->ecm->setup;
     	$permtoupload = $user->rights->ecm->upload;
    +	$showroot = 0;
     }
     if ($module == 'medias')
     {
     	$permtoadd = ($user->rights->mailing->creer || $user->rights->website->write);
     	$permtoupload = ($user->rights->mailing->creer || $user->rights->website->write);
    +	$showroot = 1;
     }
     
     
    @@ -69,29 +72,25 @@ if (($action == 'delete' || $action == 'file_manager_delete') && empty($conf->us
     print '<div class="inline-block toolbarbutton centpercent">';
     
     // Toolbar
    -//if (preg_match('/\/ecm/', $_SERVER['PHP_SELF'])) {
    -//if ($module == 'ecm') {
    -
    -	if ($permtoadd)
    -	{
    -	    print '<a href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&module='.urlencode($module).($website?'&website='.$website:'').($pageid?'&pageid='.$pageid:'').'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$website.'&pageid='.$pageid).'" class="inline-block valignmiddle toolbarbutton" title="'.dol_escape_htmltag($langs->trans('ECMAddSection')).'">';
    -	    print '<img class="toolbarbutton" border="0" src="'.DOL_URL_ROOT.'/theme/common/folder-new.png">';
    -	    print '</a>';
    -	}
    -	else
    -	{
    -	    print '<a href="#" class="inline-block valignmiddle toolbarbutton" title="'.$langs->trans("NotAllowed").'">';
    -	    print '<img class="toolbarbutton" border="0" src="'.DOL_URL_ROOT.'/theme/common/folder-new.png">';
    -	    print '</a>';
    -	}
    -	if ($module == 'ecm')
    -	{
    -		$tmpurl=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&amp;module='.$module:'').($section?'&amp;section='.$section:'')));
    -		print '<a href="'.$tmpurl.'" class="inline-block valignmiddle toolbarbutton" title="'.dol_escape_htmltag($langs->trans('ReSyncListOfDir')).'">';
    -		print '<img id="refreshbutton" class="toolbarbutton" border="0" src="'.DOL_URL_ROOT.'/theme/common/view-refresh.png">';
    -		print '</a>';
    -	}
    -//}
    +if ($permtoadd)
    +{
    +	print '<a href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&module='.urlencode($module).($websitekey?'&website='.$websitekey:'').($pageid?'&pageid='.$pageid:'').'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid).'" class="inline-block valignmiddle toolbarbutton" title="'.dol_escape_htmltag($langs->trans('ECMAddSection')).'">';
    +    print '<img class="toolbarbutton" border="0" src="'.DOL_URL_ROOT.'/theme/common/folder-new.png">';
    +    print '</a>';
    +}
    +else
    +{
    +    print '<a href="#" class="inline-block valignmiddle toolbarbutton" title="'.$langs->trans("NotAllowed").'">';
    +    print '<img class="toolbarbutton" border="0" src="'.DOL_URL_ROOT.'/theme/common/folder-new.png">';
    +    print '</a>';
    +}
    +if ($module == 'ecm')
    +{
    +	$tmpurl=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&amp;module='.$module:'').($section?'&amp;section='.$section:'')));
    +	print '<a href="'.$tmpurl.'" class="inline-block valignmiddle toolbarbutton" title="'.dol_escape_htmltag($langs->trans('ReSyncListOfDir')).'">';
    +	print '<img id="refreshbutton" class="toolbarbutton" border="0" src="'.DOL_URL_ROOT.'/theme/common/view-refresh.png">';
    +	print '</a>';
    +}
     
     // Start "Add new file" area
     $nameforformuserfile = 'formuserfileecm';
    @@ -112,7 +111,7 @@ if ((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABL
     		<?php
     	}
     
    -	$sectiondir=GETPOST('file','alpha');
    +	$sectiondir=GETPOST('file','alpha')?GETPOST('file','alpha'):GETPOST('section_dir','alpha');
     	print '<!-- Start form to attach new file in filemanager.tpl.php sectionid='.$section.' sectiondir='.$sectiondir.' -->'."\n";
     	include_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
         $formfile=new FormFile($db);
    @@ -148,7 +147,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
     
     	print '<!-- Title for manual directories -->'."\n";
     	print '<tr class="liste_titre">'."\n";
    -    print '<th class="liste_titre" align="left" colspan="6">';
    +    print '<th class="liste_titre" align="left">';
         print '&nbsp;'.$langs->trans("ECMSections");
     	print '</th></tr>';
     
    @@ -159,18 +158,26 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
     
         if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
         {
    -        print '<tr><td colspan="6">';
    +    	// Show the link to "Root"
    +    	if ($showroot)
    +    	{
    +    		print '<tr><td><div style="padding-left: 5px; padding-right: 5px;"><a href="'.$_SERVER["PHP_SELF"].'?file_manager=1&pageid='.$pageid.'">'.$langs->trans("Root").'</a></div></td></tr>';
    +    	}
     
    -    	// Show filemanager tree (will be filled by call of ajax enablefiletreeajax.tpl.php that execute ajaxdirtree.php)
    +
    +
    +    	print '<tr><td>';
    +
    +    	// Show filemanager tree (will be filled by a call of ajax /ecm/tpl/enablefiletreeajax.tpl.php, later, that executes ajaxdirtree.php)
     	    print '<div id="filetree" class="ecmfiletree"></div>';
     
     	    if ($action == 'deletefile') print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile');
     
     	    print '</td></tr>';
         }
    -    else
    +    else	// Show filtree when ajax is disabled (rare)
         {
    -        print '<tr><td colspan="6" style="padding-left: 20px">';
    +        print '<tr><td style="padding-left: 20px">';
     
             $_POST['modulepart'] = $module;
             $_POST['openeddir'] = GETPOST('openeddir');
    @@ -179,6 +186,9 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
             // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show)
             print '<div id="filetree" class="ecmfiletree">';
     
    +        // Variables that may be defined:
    +        // $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
    +        // $_POST['dir']
             $mode='noajax';
             if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
             include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php';
    @@ -204,7 +214,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
     
     $mode='noajax';
     if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
    -include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
    +include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';	// Show content of a directory on right side
     
     
     // End right panel
    @@ -217,7 +227,15 @@ include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
     <?php
     
     
    -if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) {
    +if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) // Show filtree when ajax is enabled
    +{
    +	//var_dump($modulepart);
    +	// Variables that may be defined:
    +	// $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
    +	// $_POST['dir']
    +	// $_POST['section_dir'], $_POST['section_id'], $_POST['token'], $_POST['max_file_size'], $_POST['sendit']
    +	if (GETPOST('section_dir','alpha')) { $preopened=GETPOST('section_dir','alpha'); }
    +
     	include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
     }
     
    diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php
    index 0f22527ff01..f3367d3e90f 100644
    --- a/htdocs/core/tpl/login.tpl.php
    +++ b/htdocs/core/tpl/login.tpl.php
    @@ -19,6 +19,7 @@
     // Need global variable $title to be defined by caller (like dol_loginfunction)
     // Caller can also set 	$morelogincontent = array(['options']=>array('js'=>..., 'table'=>...);
     
    +
     // Protection to avoid direct call of template
     if (empty($conf) || ! is_object($conf))
     {
    @@ -27,6 +28,8 @@ if (empty($conf) || ! is_object($conf))
     }
     
     
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +
     header('Cache-Control: Public, must-revalidate');
     header("Content-type: text/html; charset=".$conf->file->character_set_client);
     
    @@ -55,10 +58,16 @@ if (! preg_match('/'.constant('DOL_APPLICATION_TITLE').'/', $title)) $disablenof
     
     print top_htmlhead('', $titleofloginpage, 0, 0, $arrayofjs, array(), 0, $disablenofollow);
     
    +
    +$colorbackhmenu1='60,70,100';      // topmenu
    +if (! isset($conf->global->THEME_ELDY_TOPMENU_BACK1)) $conf->global->THEME_ELDY_TOPMENU_BACK1=$colorbackhmenu1;
    +$colorbackhmenu1     =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TOPMENU_BACK1)?$colorbackhmenu1:$conf->global->THEME_ELDY_TOPMENU_BACK1):(empty($user->conf->THEME_ELDY_TOPMENU_BACK1)?$colorbackhmenu1:$user->conf->THEME_ELDY_TOPMENU_BACK1);
    +$colorbackhmenu1=join(',',colorStringToArray($colorbackhmenu1));    // Normalize value to 'x,y,z'
    +
     ?>
     <!-- BEGIN PHP TEMPLATE LOGIN.TPL.PHP -->
     
    -<body class="body bodylogin"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>>
    +<body class="body bodylogin"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode('logos/'.$conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>>
     
     <?php if (empty($conf->dol_use_jmobile)) { ?>
     <script type="text/javascript">
    @@ -69,7 +78,7 @@ $(document).ready(function () {
     </script>
     <?php } ?>
     
    -<div class="login_center center">
    +<div class="login_center center"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND)?' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: linear-gradient(rgb('.$colorbackhmenu1.',0.3), rgb(240,240,240));"':'' ?>>
     <div class="login_vertical_align">
     
     <form id="login" name="login" method="post" action="<?php echo $php_self; ?>">
    @@ -114,26 +123,29 @@ if ($disablenofollow) echo '</a>';
     
     <div id="login_right">
     
    -<table class="left centpercent" title="<?php echo $langs->trans("EnterLoginDetail"); ?>">
    +<div class="tagtable left centpercent" title="<?php echo $langs->trans("EnterLoginDetail"); ?>">
    +
     <!-- Login -->
    -<tr>
    -<td class="nowrap center valignmiddle">
    +<div class="trinputlogin">
    +<div class="tagtd nowrap center valignmiddle tdinputlogin">
     <?php if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { ?><label for="username" class="hidden"><?php echo $langs->trans("Login"); ?></label><?php } ?>
     <!-- <span class="span-icon-user">-->
     <span class="fa fa-user">
    -<input type="text" id="username" placeholder="<?php echo $langs->trans("Login"); ?>" name="username" class="flat input-icon-user minwidth150" value="<?php echo dol_escape_htmltag($login); ?>" tabindex="1" autofocus="autofocus" />
     </span>
    -</td>
    -</tr>
    +<input type="text" id="username" placeholder="<?php echo $langs->trans("Login"); ?>" name="username" class="flat input-icon-user minwidth150" value="<?php echo dol_escape_htmltag($login); ?>" tabindex="1" autofocus="autofocus" />
    +</div>
    +</div>
    +
     <!-- Password -->
    -<tr>
    -<td class="nowrap center valignmiddle">
    +<div class="trinputlogin">
    +<div class="tagtd nowrap center valignmiddle tdinputlogin">
     <?php if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { ?><label for="password" class="hidden"><?php echo $langs->trans("Password"); ?></label><?php } ?>
     <!--<span class="span-icon-password">-->
     <span class="fa fa-key">
    -<input id="password" placeholder="<?php echo $langs->trans("Password"); ?>" name="password" class="flat input-icon-password minwidth150" type="password" value="<?php echo dol_escape_htmltag($password); ?>" tabindex="2" autocomplete="<?php echo empty($conf->global->MAIN_LOGIN_ENABLE_PASSWORD_AUTOCOMPLETE)?'off':'on'; ?>" />
     </span>
    -</td></tr>
    +<input id="password" placeholder="<?php echo $langs->trans("Password"); ?>" name="password" class="flat input-icon-password minwidth150" type="password" value="<?php echo dol_escape_htmltag($password); ?>" tabindex="2" autocomplete="<?php echo empty($conf->global->MAIN_LOGIN_ENABLE_PASSWORD_AUTOCOMPLETE)?'off':'on'; ?>" />
    +</div></div>
    +
     <?php
     if (! empty($morelogincontent)) {
     	if (is_array($morelogincontent)) {
    @@ -159,10 +171,11 @@ if ($captcha) {
     	// TODO: provide accessible captcha variants
     ?>
     	<!-- Captcha -->
    -	<tr>
    -	<td class="nowrap none center">
    +	<div class="trinputlogin">
    +	<div class="tagtd nowrap none center valignmiddle tdinputlogin">
     
    -	<table class="login_table_securitycode centpercent"><tr>
    +	<table class="login_table_securitycode centpercent">
    +	<tr class="valignmiddle">
     	<td>
     	<span class="span-icon-security">
     	<input id="securitycode" placeholder="<?php echo $langs->trans("SecurityCode"); ?>" class="flat input-icon-security width100" type="text" maxlength="5" name="code" tabindex="3" />
    @@ -170,15 +183,17 @@ if ($captcha) {
     	</td>
     	<td><img src="<?php echo DOL_URL_ROOT ?>/core/antispamimage.php" border="0" width="80" height="32" id="img_securitycode" /></td>
     	<td><a href="<?php echo $php_self; ?>" tabindex="4" data-role="button"><?php echo $captcha_refresh; ?></a></td>
    -	</tr></table>
    +	</tr>
    +	</table>
     
    -	</td></tr>
    +	</div></div>
     <?php } ?>
    -</table>
     
    -</div> <!-- end div login-right -->
    +</div>
     
    -</div> <!-- end div login-line1 -->
    +</div> <!-- end div login_right -->
    +
    +</div> <!-- end div login_line1 -->
     
     
     <div id="login_line2" style="clear: both">
    @@ -196,11 +211,12 @@ if ($forgetpasslink || $helpcenterlink)
     	if ($dol_use_jmobile)    $moreparam.=(strpos($moreparam,'?')===false?'?':'&').'dol_use_jmobile='.$dol_use_jmobile;
     
     	echo '<br>';
    -	echo '<div class="center" style="margin-top: 8px;">';
    +	echo '<div class="center" style="margin-top: 15px;">';
     	if ($forgetpasslink) {
    -		echo '<a class="alogin" href="'.DOL_URL_ROOT.'/user/passwordforgotten.php'.$moreparam.'">(';
    +		$url=DOL_URL_ROOT.'/user/passwordforgotten.php'.$moreparam;
    +		if (! empty($conf->global->MAIN_PASSWORD_FORGOTLINK)) $url=$conf->global->MAIN_PASSWORD_FORGOTLINK;
    +		echo '<a class="alogin" href="'.dol_escape_htmltag($url).'">';
     		echo $langs->trans('PasswordForgotten');
    -		if (! $helpcenterlink) echo ')';
     		echo '</a>';
     	}
     
    @@ -210,9 +226,8 @@ if ($forgetpasslink || $helpcenterlink)
     		$url=DOL_URL_ROOT.'/support/index.php'.$moreparam;
     		if (! empty($conf->global->MAIN_HELPCENTER_LINKTOUSE)) $url=$conf->global->MAIN_HELPCENTER_LINKTOUSE;
     		echo '<a class="alogin" href="'.dol_escape_htmltag($url).'" target="_blank">';
    -		if (! $forgetpasslink) echo '(';
     		echo $langs->trans('NeedHelpCenter');
    -		echo ')</a>';
    +		echo '</a>';
     	}
     	echo '</div>';
     }
    diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php
    index 61818d4deb9..23640216cd9 100644
    --- a/htdocs/core/tpl/objectline_create.tpl.php
    +++ b/htdocs/core/tpl/objectline_create.tpl.php
    @@ -6,6 +6,7 @@
      * Copyright (C) 2014		Florian Henry		<florian.henry@open-concept.pro>
      * Copyright (C) 2014       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2015-2016	Marcos García		<marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -107,7 +108,7 @@ if ($nolinesbefore) {
     	if ($object->element == 'supplier_proposal' || $object->element == 'order_supplier' || $object->element == 'invoice_supplier')	// We must have same test in printObjectLines
     	{
     	?>
    -		<td class="linecolrefsupplier" align="right"><span id="title_fourn_ref"><?php echo $langs->trans('SupplierRef'); ?></span></td>
    +		<td class="linecolrefsupplier"><span id="title_fourn_ref"><?php echo $langs->trans('SupplierRef'); ?></span></td>
     	<?php } ?>
     	<td class="linecolvat" align="right"><span id="title_vat"><?php echo $langs->trans('VAT'); ?></span></td>
     	<td class="linecoluht" align="right"><span id="title_up_ht"><?php echo $langs->trans('PriceUHT'); ?></span></td>
    @@ -159,6 +160,7 @@ if ($nolinesbefore) {
     ?>
     <tr class="pair nodrag nodrop nohoverpair<?php echo ($nolinesbefore || $object->element=='contrat')?'':' liste_titre_create'; ?>">
     <?php
    +// Adds a line numbering column
     if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) {
     	$coldisplay=2;
     	?>
    @@ -481,16 +483,16 @@ if ((! empty($conf->service->enabled) || ($object->element == 'contrat')) && $da
     	if (! empty($object->element) && $object->element == 'contrat')
     	{
     		print $langs->trans("DateStartPlanned").' ';
    -		$form->select_date($date_start,"date_start",$usehm,$usehm,1,"addproduct");
    +		print $form->selectDate($date_start,"date_start",$usehm,$usehm,1,"addproduct");
     		print ' &nbsp; '.$langs->trans("DateEndPlanned").' ';
    -		$form->select_date($date_end,"date_end",$usehm,$usehm,1,"addproduct");
    +		print $form->selectDate($date_end,"date_end",$usehm,$usehm,1,"addproduct");
     	}
     	else
     	{
     		echo $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' ';
    -		echo $form->select_date($date_start,'date_start',empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1,empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1,1,"addproduct",1,0,1);
    +		print $form->selectDate($date_start, 'date_start', empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1, empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1, 1, "addproduct", 1, 0);
     		echo ' '.$langs->trans('to').' ';
    -		echo $form->select_date($date_end,'date_end',empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1,empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1,1,"addproduct",1,0,1);
    +		print $form->selectDate($date_end, 'date_end', empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1, empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?0:1, 1, "addproduct", 1, 0);
     	};
     	print '<script type="text/javascript">';
     	if (!$date_start) {
    diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php
    index d3dc9807c5a..0a5f3bc43bd 100644
    --- a/htdocs/core/tpl/objectline_edit.tpl.php
    +++ b/htdocs/core/tpl/objectline_edit.tpl.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2012       Cédric Salvador     <csalvador@gpcsolutions.fr>
      * Copyright (C) 2012-2014  Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2013		Florian Henry		<florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -258,9 +259,9 @@ if (!empty($extrafieldsline))
     	<td colspan="<?php echo 7+$colspan ?>"><?php echo $langs->trans('ServiceLimitedDuration').' '.$langs->trans('From').' '; ?>
     	<?php
     	$hourmin=(isset($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE)?$conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE:'');
    -	echo $form->select_date($line->date_start,'date_start',$hourmin,$hourmin,$line->date_start?0:1,"updateligne",1,0,1);
    -	echo ' '.$langs->trans('to').' ';
    -	echo $form->select_date($line->date_end,'date_end',$hourmin,$hourmin,$line->date_end?0:1,"updateligne",1,0,1);
    +	print $form->selectDate($line->date_start, 'date_start', $hourmin, $hourmin, $line->date_start?0:1, "updateline", 1, 0);
    +	print ' '.$langs->trans('to').' ';
    +	print $form->selectDate($line->date_end, 'date_end', $hourmin, $hourmin, $line->date_end?0:1, "updateline", 1, 0);
     	print '<script type="text/javascript">';
     	if (!$line->date_start) {
     		if (isset($conf->global->MAIN_DEFAULT_DATE_START_HOUR)) {
    diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php
    index 313a4ee4def..776506bdaee 100644
    --- a/htdocs/core/tpl/objectline_view.tpl.php
    +++ b/htdocs/core/tpl/objectline_view.tpl.php
    @@ -66,7 +66,7 @@ $domData .= ' data-product_type="'.$line->product_type.'"';
     ?>
     <?php $coldisplay=0; ?>
     <!-- BEGIN PHP TEMPLATE objectline_view.tpl.php -->
    -<tr <?php echo 'id="row-'.$line->id.'" '.$bcdd[$var]; echo $domData; ?> >
    +<tr  id="row-<?php echo $line->id?>" class="drag drop oddeven" <?php echo $domData; ?> >
     	<?php if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { ?>
     	<td class="linecolnum" align="center"><?php $coldisplay++; ?><?php echo ($i+1); ?></td>
     	<?php } ?>
    @@ -292,7 +292,7 @@ $domData .= ' data-product_type="'.$line->product_type.'"';
     	</td>
     
     	<?php
    -	if ($num > 1 && empty($conf->browser->phone) && ($this->situation_counter == 1 || !$this->situation_cycle_ref) && empty($disablemove)) { ?>
    +	if ($num > 1 && $conf->browser->layout != 'phone' && ($this->situation_counter == 1 || !$this->situation_cycle_ref) && empty($disablemove)) { ?>
     	<td align="center" class="linecolmove tdlineupdown"><?php $coldisplay++; ?>
     		<?php if ($i > 0) { ?>
     		<a class="lineupdown" href="<?php echo $_SERVER["PHP_SELF"].'?id='.$this->id.'&amp;action=up&amp;rowid='.$line->id; ?>">
    @@ -306,7 +306,7 @@ $domData .= ' data-product_type="'.$line->product_type.'"';
     		<?php } ?>
     	</td>
         <?php } else { ?>
    -    <td align="center"<?php echo ((empty($conf->browser->phone) && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"'); ?>><?php $coldisplay++; ?></td>
    +    <td align="center"<?php echo (($conf->browser->layout != 'phone' && empty($disablemove)) ?' class="linecolmove tdlineupdown"':' class="linecolmove"'); ?>><?php $coldisplay++; ?></td>
     	<?php } ?>
     <?php } else { ?>
     	<td colspan="3"><?php $coldisplay=$coldisplay+3; ?></td>
    @@ -321,7 +321,7 @@ $domData .= ' data-product_type="'.$line->product_type.'"';
     //Line extrafield
     if (!empty($extrafieldsline))
     {
    -	print $line->showOptionals($extrafieldsline, 'view', array('style'=>$bcdd[$var],'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1);
    +	print $line->showOptionals($extrafieldsline, 'view', array('style'=>'class="drag drop oddeven"','colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1);
     }
     ?>
     
    diff --git a/htdocs/core/tpl/onlinepaymentlinks.tpl.php b/htdocs/core/tpl/onlinepaymentlinks.tpl.php
    index a425055135f..37639a5f8e6 100644
    --- a/htdocs/core/tpl/onlinepaymentlinks.tpl.php
    +++ b/htdocs/core/tpl/onlinepaymentlinks.tpl.php
    @@ -118,6 +118,28 @@ if (! empty($conf->adherent->enabled))
     	}
     	print '<br>';
     }
    +if (! empty($conf->don->enabled))
    +{
    +	print img_picto('','object_globe.png').' '.$langs->trans("ToOfferALinkForOnlinePaymentOnDonation",$servicename).':<br>';
    +	print '<strong>'.getOnlinePaymentUrl(1,'donation')."</strong><br>\n";
    +	if (! empty($conf->global->PAYMENT_SECURITY_TOKEN) && ! empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE))
    +	{
    +	    $langs->load("members");
    +	    print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    +	    print $langs->trans("EnterRefToBuildUrl",$langs->transnoentitiesnoconv("Don")).': ';
    +        print '<input type="text class="flat" id="generate_donation_ref" name="generate_donation_ref" value="'.GETPOST('generate_donation_ref','alpha').'" size="10">';
    +        print '<input type="submit" class="none reposition button" value="'.$langs->trans("GetSecuredUrl").'">';
    +        if (GETPOST('generate_donation_ref'))
    +        {
    +            print '<br> -> <strong>';
    +            $url=getOnlinePaymentUrl(0,'donation',GETPOST('generate_donation_ref','alpha'));
    +            print $url;
    +            print "</strong><br>\n";
    +        }
    +        print '</form>';
    +	}
    +	print '<br>';
    +}
     
     if (! empty($conf->use_javascript_ajax))
     {
    @@ -140,3 +162,4 @@ print info_admin($langs->trans("YouCanAddTagOnUrl"));
     
     print '<!-- END PHP TEMPLATE ONLINEPAYMENTLINKS -->';
     
    +
    diff --git a/htdocs/core/tpl/passwordforgotten.tpl.php b/htdocs/core/tpl/passwordforgotten.tpl.php
    index 2f36d32535f..101c9ec7e67 100644
    --- a/htdocs/core/tpl/passwordforgotten.tpl.php
    +++ b/htdocs/core/tpl/passwordforgotten.tpl.php
    @@ -24,6 +24,8 @@ if (empty($conf) || ! is_object($conf))
     }
     
     
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +
     header('Cache-Control: Public, must-revalidate');
     header("Content-type: text/html; charset=".$conf->file->character_set_client);
     
    @@ -42,10 +44,17 @@ $php_self.= dol_escape_htmltag($_SERVER["QUERY_STRING"])?'?'.dol_escape_htmltag(
     $titleofpage=$langs->trans('SendNewPassword');
     
     print top_htmlhead('', $titleofpage);
    +
    +
    +$colorbackhmenu1='60,70,100';      // topmenu
    +if (! isset($conf->global->THEME_ELDY_TOPMENU_BACK1)) $conf->global->THEME_ELDY_TOPMENU_BACK1=$colorbackhmenu1;
    +$colorbackhmenu1     =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty($conf->global->THEME_ELDY_TOPMENU_BACK1)?$colorbackhmenu1:$conf->global->THEME_ELDY_TOPMENU_BACK1)   :(empty($user->conf->THEME_ELDY_TOPMENU_BACK1)?$colorbackhmenu1:$user->conf->THEME_ELDY_TOPMENU_BACK1);
    +$colorbackhmenu1=join(',',colorStringToArray($colorbackhmenu1));    // Normalize value to 'x,y,z'
    +
     ?>
     <!-- BEGIN PHP TEMPLATE PASSWORDFORGOTTEN.TPL.PHP -->
     
    -<body class="body bodylogin"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode($conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>>
    +<body class="body bodylogin"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: url(\''.DOL_URL_ROOT.'/viewimage.php?cache=1&noalt=1&modulepart=mycompany&file='.urlencode('logos/'.$conf->global->MAIN_LOGIN_BACKGROUND).'\')"'; ?>>
     
     <?php if (empty($conf->dol_use_jmobile)) { ?>
     <script type="text/javascript">
    @@ -57,7 +66,7 @@ $(document).ready(function () {
     <?php } ?>
     
     
    -<div class="login_center center">
    +<div class="login_center center"<?php print empty($conf->global->MAIN_LOGIN_BACKGROUND)?' style="background-size: cover; background-position: center center; background-attachment: fixed; background-repeat: no-repeat; background-image: linear-gradient(rgb('.$colorbackhmenu1.',0.3), rgb(240,240,240));"':'' ?>>
     <div class="login_vertical_align">
     
     <form id="login" name="login" method="POST" action="<?php echo $php_self; ?>">
    @@ -88,17 +97,17 @@ if ($disablenofollow) echo '</a>';
     
     <div id="login_right">
     
    -<table summary="Login pass" class="centpercent">
    +<div class="tagtable centpercent" title="Login pass" >
     
     <!-- Login -->
    -<tr>
    -<td valign="bottom" class="nowrap center">
    +<div class="trinputlogin">
    +<div class="tagtd nowrap center valignmiddle tdinputlogin">
     <!-- <span class="span-icon-user">-->
     <span class="fa fa-user">
    -<input type="text" placeholder="<?php echo $langs->trans("Login"); ?>" <?php echo $disabled; ?> id="username" name="username" class="flat input-icon-user minwidth150" value="<?php echo dol_escape_htmltag($username); ?>" tabindex="1" />
     </span>
    -</td>
    -</tr>
    +<input type="text" placeholder="<?php echo $langs->trans("Login"); ?>" <?php echo $disabled; ?> id="username" name="username" class="flat input-icon-user minwidth150" value="<?php echo dol_escape_htmltag($username); ?>" tabindex="1" />
    +</div>
    +</div>
     
     <?php
     if (! empty($morelogincontent)) {
    @@ -125,10 +134,11 @@ if (! empty($morelogincontent)) {
     		else $php_self.='?time='.dol_print_date(dol_now(),'dayhourlog');
     	?>
     	<!-- Captcha -->
    -	<tr>
    -	<td class="tdtop nowrap none center">
    +	<div class="trinputlogin">
    +	<div class="tdinputlogin nowrap none center valignmiddle tdinputlogin">
     
    -	<table class="login_table_securitycode centpercent"><tr class="valignmiddle">
    +	<table class="login_table_securitycode centpercent">
    +	<tr class="valignmiddle">
     	<td>
     	<!-- <span class="span-icon-security"> -->
     	<span class="nofa">
    @@ -139,12 +149,12 @@ if (! empty($morelogincontent)) {
     	<td><a href="<?php echo $php_self; ?>" tabindex="4"><?php echo $captcha_refresh; ?></a></td>
     	</tr></table>
     
    -	</td></tr>
    +	</div></div>
     <?php } ?>
     
    -</table>
    +</div>
     
    -</div> <!-- end div login right -->
    +</div> <!-- end div login_right -->
     
     </div> <!-- end div login_line1 -->
     
    @@ -155,7 +165,7 @@ if (! empty($morelogincontent)) {
     <br><input type="submit" <?php echo $disabled; ?> class="button" name="button_password" value="<?php echo $langs->trans('SendNewPassword'); ?>" tabindex="4" />
     
     <br>
    -<div align="center" style="margin-top: 8px;">
    +<div align="center" style="margin-top: 15px;">
     	<?php
     	$moreparam='';
     	if (! empty($conf->dol_hide_topmenu))   $moreparam.=(strpos($moreparam,'?')===false?'?':'&').'dol_hide_topmenu='.$conf->dol_hide_topmenu;
    @@ -163,7 +173,7 @@ if (! empty($morelogincontent)) {
     	if (! empty($conf->dol_no_mouse_hover)) $moreparam.=(strpos($moreparam,'?')===false?'?':'&').'dol_no_mouse_hover='.$conf->dol_no_mouse_hover;
     	if (! empty($conf->dol_use_jmobile))    $moreparam.=(strpos($moreparam,'?')===false?'?':'&').'dol_use_jmobile='.$conf->dol_use_jmobile;
     
    -	print '<a class="alogin" href="'.$dol_url_root.'/index.php'.$moreparam.'">('.$langs->trans('BackToLoginPage').')</a>';
    +	print '<a class="alogin" href="'.$dol_url_root.'/index.php'.$moreparam.'">'.$langs->trans('BackToLoginPage').'</a>';
     	?>
     </div>
     
    @@ -174,7 +184,7 @@ if (! empty($morelogincontent)) {
     </form>
     
     
    -<div class="center login_main_home paddingtopbottom<?php echo empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' backgroundsemitransparent'; ?>" style="max-width: 70%">
    +<div class="center login_main_home divpasswordmessagedesc paddingtopbottom<?php echo empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' backgroundsemitransparent'; ?>" style="max-width: 70%">
     <?php if ($mode == 'dolibarr' || ! $disabled) { ?>
     	<span class="passwordmessagedesc">
     	<?php echo $langs->trans('SendNewPasswordDesc'); ?>
    diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php
    index af1d25aaee1..f9daffe33ed 100644
    --- a/htdocs/core/tpl/resource_add.tpl.php
    +++ b/htdocs/core/tpl/resource_add.tpl.php
    @@ -9,7 +9,7 @@ if (empty($conf) || ! is_object($conf))
     }
     
     
    -require_once(DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php');
    +require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php';
     
     $form = new Form($db);
     $formresources = new FormResource($db);
    @@ -28,7 +28,7 @@ $out .= '<input type="hidden" name="resource_type" value="'.(empty($resource_typ
     $out .= '<div class="tagtd">'.$langs->trans("SelectResource").'</div>';
     $out .= '<div class="tagtd">';
     $events=array();
    -$out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2);
    +$out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2,null);
     $out .= '</div>';
     
     $out .= '<div class="tagtd"><label>'.$langs->trans('Busy').'</label> '.$form->selectyesno('busy',(isset($_POST['busy'])?$_POST['busy']:1),1).'</div>';
    diff --git a/htdocs/core/tpl/resource_view.tpl.php b/htdocs/core/tpl/resource_view.tpl.php
    index aff342191cb..59491c01b6f 100644
    --- a/htdocs/core/tpl/resource_view.tpl.php
    +++ b/htdocs/core/tpl/resource_view.tpl.php
    @@ -98,7 +98,6 @@ if( (array) $linked_resources && count($linked_resources) > 0)
     			print '</form>';
     		}
     	}
    -
     }
     else {
     	print '<form class="tagtr oddeven">';
    diff --git a/htdocs/core/triggers/dolibarrtriggers.class.php b/htdocs/core/triggers/dolibarrtriggers.class.php
    index 61a89b083f8..a66eb12c78e 100644
    --- a/htdocs/core/triggers/dolibarrtriggers.class.php
    +++ b/htdocs/core/triggers/dolibarrtriggers.class.php
    @@ -80,11 +80,12 @@ abstract class DolibarrTriggers
     	 *
     	 * @param DoliDB $db Database handler
     	 */
    -	public function __construct(DoliDB $db) {
    +    public function __construct(DoliDB $db)
    +    {
     
     		$this->db = $db;
     
    -		if (empty($this->name)) 
    +		if (empty($this->name))
     		{
     			$this->name = preg_replace('/^Interface/i', '', get_class($this));
     		}
    @@ -145,5 +146,4 @@ abstract class DolibarrTriggers
     	 * @return int         				<0 if KO, 0 if no triggered ran, >0 if OK
     	 */
     	abstract function runTrigger($action, $object, User $user, Translate $langs, Conf $conf);
    -
     }
    diff --git a/htdocs/core/triggers/interface_20_all_Logevents.class.php b/htdocs/core/triggers/interface_20_all_Logevents.class.php
    index c2f15bd336d..772e9b39a51 100644
    --- a/htdocs/core/triggers/interface_20_all_Logevents.class.php
    +++ b/htdocs/core/triggers/interface_20_all_Logevents.class.php
    @@ -31,9 +31,19 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
      */
     class InterfaceLogevents extends DolibarrTriggers
     {
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'technic';
    +
     	public $family = 'core';
    +
     	public $description = "Triggers of this module allows to add security event records inside Dolibarr.";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
     
     	/**
    @@ -60,7 +70,7 @@ class InterfaceLogevents extends DolibarrTriggers
             $date = dol_now();
     
             // Actions
    -        if ($action == 'USER_LOGIN')
    +        /*if ($action == 'USER_LOGIN')
             {
                 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
     
    @@ -87,7 +97,7 @@ class InterfaceLogevents extends DolibarrTriggers
                 // Initialisation donnees (date,duree,texte,desc)
                 $text="(UserLogoff,".$object->login.")";
                 $desc="(UserLogoff,".$object->login.")";
    -        }
    +        }*/
             if ($action == 'USER_CREATE')
             {
                 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
    @@ -202,5 +212,4 @@ class InterfaceLogevents extends DolibarrTriggers
                 return -1;
             }
         }
    -
     }
    diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php
    index 94aaaeaa542..90806746da8 100644
    --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php
    +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php
    @@ -32,9 +32,18 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
     
     class InterfaceWorkflowManager extends DolibarrTriggers
     {
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'technic';
    +
     	public $family = 'core';
     	public $description = "Triggers of this module allows to manage workflows";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
     
     	/**
    @@ -309,5 +318,4 @@ class InterfaceWorkflowManager extends DolibarrTriggers
     
             return 0;
         }
    -
     }
    diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
    index 481df585f3a..938b63d90f3 100644
    --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
    +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php
    @@ -36,7 +36,16 @@ class InterfaceActionsAuto extends DolibarrTriggers
     {
     	public $family = 'agenda';
     	public $description = "Triggers of this module add actions in agenda according to setup made in agenda setup.";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
    +
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'action';
     
     	/**
    @@ -78,9 +87,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		// Actions
     		if ($action == 'COMPANY_CREATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("companies");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","companies"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("NewCompanyToDolibarr",$object->name);
                 $object->actionmsg=$langs->transnoentities("NewCompanyToDolibarr",$object->name);
    @@ -91,9 +99,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'COMPANY_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) dol_syslog('Trigger called with property actionmsg2 on object not defined', LOG_ERR);
     
    @@ -102,9 +109,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
             elseif ($action == 'CONTRACT_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("contracts");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","contracts"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ContractValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("ContractValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -113,9 +119,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'CONTRACT_SENTBYMAIL')
     		{
    -			$langs->load("agenda");
    -			$langs->load("other");
    -			$langs->load("contract");
    +			// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","contracts"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ContractSentByEMail",$object->ref);
     			if (empty($object->actionmsg))
    @@ -128,9 +133,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPAL_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("propal");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("PropalValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -139,9 +143,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
             elseif ($action == 'PROPAL_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("propal");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProposalSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -154,9 +157,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPAL_CLOSE_SIGNED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("propal");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedSignedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("PropalClosedSignedInDolibarr",$object->ref);
    @@ -165,9 +167,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPAL_CLASSIFY_BILLED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("propal");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClassifiedBilledInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("PropalClassifiedBilledInDolibarr",$object->ref);
    @@ -176,9 +177,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPAL_CLOSE_REFUSED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("propal");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedRefusedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("PropalClosedRefusedInDolibarr",$object->ref);
    @@ -187,8 +187,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("OrderValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -197,9 +197,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_CLOSE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderDeliveredInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("OrderDeliveredInDolibarr",$object->ref);
    @@ -208,9 +207,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_CLASSIFY_BILLED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderBilledInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("OrderBilledInDolibarr",$object->ref);
    @@ -219,9 +217,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_CANCEL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderCanceledInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("OrderCanceledInDolibarr",$object->ref);
    @@ -230,9 +227,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -245,9 +241,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'BILL_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("InvoiceValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -256,9 +251,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'BILL_UNVALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +           // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceBackToDraftInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InvoiceBackToDraftInDolibarr",$object->ref);
    @@ -267,9 +261,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
             elseif ($action == 'BILL_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -282,9 +275,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'BILL_PAYED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 // Values for this action can't be defined by caller.
                 $object->actionmsg2=$langs->transnoentities("InvoicePaidInDolibarr",$object->ref);
    @@ -294,9 +286,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'BILL_CANCEL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceCanceledInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InvoiceCanceledInDolibarr",$object->ref);
    @@ -305,9 +296,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'FICHINTER_CREATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionCreatedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InterventionCreatedInDolibarr",$object->ref);
    @@ -318,9 +308,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'FICHINTER_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("InterventionValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -331,9 +320,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'FICHINTER_MODIFY')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionModifiedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InterventionModifiedInDolibarr",$object->ref);
    @@ -344,9 +332,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'FICHINTER_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -359,9 +346,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'FICHINTER_CLASSIFY_BILLED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionClassifiedBilledInDolibarr",$object->ref);
                	$object->actionmsg=$langs->transnoentities("InterventionClassifiedBilledInDolibarr",$object->ref);
    @@ -370,9 +356,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     	    elseif ($action == 'FICHINTER_CLASSIFY_UNBILLED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionClassifiedUnbilledInDolibarr",$object->ref);
                	$object->actionmsg=$langs->transnoentities("InterventionClassifiedUnbilledInDolibarr",$object->ref);
    @@ -381,9 +366,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'FICHINTER_DELETE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("interventions");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","interventions"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InterventionDeletedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InterventionDeletedInDolibarr",$object->ref);
    @@ -394,9 +378,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
             elseif ($action == 'SHIPPING_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("sendings");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","sendings"));
     
             	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ShippingValidated",($object->newref?$object->newref:$object->ref));
             	if (empty($object->actionmsg))
    @@ -409,9 +392,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     		elseif ($action == 'SHIPPING_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("sendings");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","sendings"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ShippingSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -424,9 +406,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPOSAL_SUPPLIER_VALIDATE')
     		{
    -			$langs->load("agenda");
    -			$langs->load("other");
    -			$langs->load("propal");
    +			// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
     			$object->actionmsg=$langs->transnoentities("PropalValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -435,9 +416,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPOSAL_SUPPLIER_SENTBYMAIL')
     		{
    -			$langs->load("agenda");
    -			$langs->load("other");
    -			$langs->load("propal");
    +			// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProposalSentByEMail",$object->ref);
     			if (empty($object->actionmsg))
    @@ -450,9 +430,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPOSAL_SUPPLIER_CLOSE_SIGNED')
     		{
    -			$langs->load("agenda");
    -			$langs->load("other");
    -			$langs->load("propal");
    +			// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedSignedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("PropalClosedSignedInDolibarr",$object->ref);
    @@ -461,9 +440,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'PROPOSAL_SUPPLIER_CLOSE_REFUSED')
     		{
    -			$langs->load("agenda");
    -			$langs->load("other");
    -			$langs->load("propal");
    +			// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","propal"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("PropalClosedRefusedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("PropalClosedRefusedInDolibarr",$object->ref);
    @@ -472,9 +450,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_CREATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderCreatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("OrderCreatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -483,9 +460,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("OrderValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -494,9 +470,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_APPROVE')
     		{
    -            $langs->load("agenda");
    -		    $langs->load("other");
    -			$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderApprovedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("OrderApprovedInDolibarr",$object->ref);
    @@ -505,9 +480,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_REFUSE')
     		{
    -            $langs->load("agenda");
    -		    $langs->load("other");
    -			$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("OrderRefusedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("OrderRefusedInDolibarr",$object->ref);
    @@ -516,9 +490,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_SUBMIT')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderSubmitedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("SupplierOrderSubmitedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -527,9 +500,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_RECEIVE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderReceivedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("SupplierOrderReceivedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -538,10 +510,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'ORDER_SUPPLIER_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    -            $langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -554,10 +524,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     		elseif ($action == 'ORDER_SUPPLIER_CLASSIFY_BILLED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    -            $langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierOrderClassifiedBilled",$object->ref);
                 if (empty($object->actionmsg))
    @@ -569,9 +537,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     		elseif ($action == 'BILL_SUPPLIER_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
                 $object->actionmsg=$langs->transnoentities("InvoiceValidatedInDolibarr",($object->newref?$object->newref:$object->ref));
    @@ -580,9 +547,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'BILL_SUPPLIER_UNVALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceBackToDraftInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InvoiceBackToDraftInDolibarr",$object->ref);
    @@ -591,10 +557,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
             elseif ($action == 'BILL_SUPPLIER_SENTBYMAIL')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    -            $langs->load("orders");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills","orders"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("SupplierInvoiceSentByEMail",$object->ref);
                 if (empty($object->actionmsg))
    @@ -607,9 +571,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     		elseif ($action == 'BILL_SUPPLIER_PAYED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoicePaidInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InvoicePaidInDolibarr",$object->ref);
    @@ -618,9 +581,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
     		elseif ($action == 'BILL_SUPPLIER_CANCELED')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("bills");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","bills"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("InvoiceCanceledInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("InvoiceCanceledInDolibarr",$object->ref);
    @@ -631,9 +593,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             // Members
             elseif ($action == 'MEMBER_VALIDATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("members");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberValidatedInDolibarr",$object->getFullName($langs));
                 $object->actionmsg=$langs->transnoentities("MemberValidatedInDolibarr",$object->getFullName($langs));
    @@ -644,9 +605,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     		elseif ($action == 'MEMBER_MODIFY')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("members");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberModifiedInDolibarr",$object->getFullName($langs));
                 $object->actionmsg=$langs->transnoentities("MemberModifiedInDolibarr",$object->getFullName($langs));
    @@ -657,9 +617,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
     		}
             elseif ($action == 'MEMBER_SUBSCRIPTION_CREATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("members");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberSubscriptionAddedInDolibarr",$object->ref,$object->getFullName($langs));
                 $object->actionmsg=$langs->transnoentities("MemberSubscriptionAddedInDolibarr",$object->ref,$object->getFullName($langs));
    @@ -673,9 +632,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'MEMBER_SUBSCRIPTION_MODIFY')
             {
    -        	$langs->load("agenda");
    -        	$langs->load("other");
    -        	$langs->load("members");
    +        	// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
             	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberSubscriptionModifiedInDolibarr",$object->ref,$object->getFullName($langs));
             	$object->actionmsg=$langs->transnoentities("MemberSubscriptionModifiedInDolibarr",$object->ref,$object->getFullName($langs));
    @@ -689,9 +647,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'MEMBER_SUBSCRIPTION_DELETE')
             {
    -        	$langs->load("agenda");
    -        	$langs->load("other");
    -        	$langs->load("members");
    +        	// Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
             	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberSubscriptionDeletedInDolibarr",$object->ref,$object->getFullName($langs));
             	$object->actionmsg=$langs->transnoentities("MemberSubscriptionDeletedInDolibarr",$object->ref,$object->getFullName($langs));
    @@ -705,9 +662,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'MEMBER_RESILIATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("members");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberResiliatedInDolibarr",$object->getFullName($langs));
                 $object->actionmsg=$langs->transnoentities("MemberResiliatedInDolibarr",$object->getFullName($langs));
    @@ -718,9 +674,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
             elseif ($action == 'MEMBER_DELETE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("members");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","members"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("MemberDeletedInDolibarr",$object->getFullName($langs));
                 $object->actionmsg=$langs->transnoentities("MemberDeletedInDolibarr",$object->getFullName($langs));
    @@ -733,9 +688,8 @@ class InterfaceActionsAuto extends DolibarrTriggers
             // Projects
             elseif ($action == 'PROJECT_CREATE')
             {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -        	$langs->load("projects");
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","projects"));
     
             	if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectCreatedInDolibarr",$object->ref);
             	$object->actionmsg=$langs->transnoentities("ProjectCreatedInDolibarr",$object->ref);
    @@ -743,10 +697,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
     
             	$object->sendtoid=0;
             }
    -        elseif($action == 'PROJECT_VALIDATE') {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("projects");
    +        elseif($action == 'PROJECT_VALIDATE')
    +        {
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","projects"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectValidatedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("ProjectValidatedInDolibarr",$object->ref);
    @@ -754,10 +708,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
     
                 $object->sendtoid=0;
             }
    -        elseif($action == 'PROJECT_MODIFY') {
    -            $langs->load("agenda");
    -            $langs->load("other");
    -            $langs->load("projects");
    +        elseif($action == 'PROJECT_MODIFY')
    +        {
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","projects"));
     
                 if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("ProjectModifiedInDolibarr",$object->ref);
                 $object->actionmsg=$langs->transnoentities("ProjectModifiedInDolibarr",$object->ref);
    @@ -767,10 +721,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
             }
     
     		// Project tasks
    -		elseif($action == 'TASK_CREATE') {
    -            $langs->load("agenda");
    -		    $langs->load("other");
    -			$langs->load("projects");
    +		elseif($action == 'TASK_CREATE')
    +		{
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","projects"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TaskCreatedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("TaskCreatedInDolibarr",$object->ref);
    @@ -779,10 +733,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
     			$object->sendtoid=0;
     		}
     
    -		elseif($action == 'TASK_MODIFY') {
    -            $langs->load("agenda");
    -		    $langs->load("other");
    -			$langs->load("projects");
    +		elseif($action == 'TASK_MODIFY')
    +		{
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","projects"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TaskModifiedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("TaskModifieddInDolibarr",$object->ref);
    @@ -791,10 +745,10 @@ class InterfaceActionsAuto extends DolibarrTriggers
     			$object->sendtoid=0;
     		}
     
    -		elseif($action == 'TASK_DELETE') {
    -            $langs->load("agenda");
    -		    $langs->load("other");
    -			$langs->load("projects");
    +		elseif($action == 'TASK_DELETE')
    +		{
    +            // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other","projects"));
     
     			if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities("TaskDeletedInDolibarr",$object->ref);
     			$object->actionmsg=$langs->transnoentities("TaskDeletedInDolibarr",$object->ref);
    @@ -803,10 +757,11 @@ class InterfaceActionsAuto extends DolibarrTriggers
     			$object->sendtoid=0;
     		}
     		// TODO Merge all previous cases into this generic one
    -		else {
    +		else
    +		{
     		    // Note: We are here only if $conf->global->MAIN_AGENDA_ACTIONAUTO_action is on (tested at begining of this function)
    -		    $langs->load("agenda");
    -		    $langs->load("other");
    +		    // Load translation files required by the page
    +            $langs->loadLangs(array("agenda","other"));
     
     		    if (empty($object->actionmsg2)) $object->actionmsg2=$langs->transnoentities($action."InDolibarr",$object->ref);
     		    if (empty($object->actionmsg))  $object->actionmsg=$langs->transnoentities($action."InDolibarr",$object->ref);
    @@ -927,5 +882,4 @@ class InterfaceActionsAuto extends DolibarrTriggers
                 return -1;
     		}
         }
    -
     }
    diff --git a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php
    index 2750834bac6..f2c19394df9 100644
    --- a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php
    +++ b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php
    @@ -32,7 +32,16 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers
     {
     	public $family = 'system';
     	public $description = "Triggers of this module add action for BlockedLog module.";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
    +
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'technic';
     
     	/**
    @@ -133,5 +142,4 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers
     			return 1;
     		}
         }
    -
     }
    diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php
    index 7677c1743a8..7d528b55c30 100644
    --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php
    +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php
    @@ -33,7 +33,16 @@ class InterfaceLdapsynchro extends DolibarrTriggers
     {
     	public $family = 'ldap';
     	public $description = "Triggers of this module allows to synchronize Dolibarr toward a LDAP database.";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
    +
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'technic';
     
     	/**
    @@ -799,5 +808,4 @@ class InterfaceLdapsynchro extends DolibarrTriggers
     
     		return $result;
     	}
    -
     }
    diff --git a/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php b/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php
    index c5f704fdcb1..0197e6bf280 100644
    --- a/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php
    +++ b/htdocs/core/triggers/interface_50_modMailmanspip_Mailmanspipsynchro.class.php
    @@ -31,7 +31,16 @@ class InterfaceMailmanSpipsynchro extends DolibarrTriggers
     {
     	public $family = 'mailmanspip';
     	public $description = "Triggers of this module allows to synchronize Mailman an Spip.";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
    +
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'technic';
     
     	/**
    @@ -148,5 +157,4 @@ class InterfaceMailmanSpipsynchro extends DolibarrTriggers
     
     		return 0;
         }
    -
     }
    diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
    index 8698b08a5c3..f5995c47c84 100644
    --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
    +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
    @@ -32,10 +32,20 @@ class InterfaceNotification extends DolibarrTriggers
     {
     	public $family = 'notification';
     	public $description = "Triggers of this module send email notifications according to Notification module setup.";
    +
    +	/**
    +	 * Version of the trigger
    +	 * @var string
    +	 */
     	public $version = self::VERSION_DOLIBARR;
    +
    +	/**
    +	 * @var string Image of the trigger
    +	 */
     	public $picto = 'email';
     
    -	var $listofmanagedevents=array(
    +	// @TODO Defined also into notify.class.php)
    +	public $listofmanagedevents=array(
     		'BILL_VALIDATE',
     		'BILL_PAYED',
     		'ORDER_VALIDATE',
    @@ -46,8 +56,12 @@ class InterfaceNotification extends DolibarrTriggers
     		'ORDER_SUPPLIER_VALIDATE',
     		'ORDER_SUPPLIER_APPROVE',
     		'ORDER_SUPPLIER_REFUSE',
    -		'SHIPPING_VALIDATE'
    -   	);
    +		'SHIPPING_VALIDATE',
    +		'EXPENSE_REPORT_VALIDATE',
    +		'EXPENSE_REPORT_APPROVE',
    +		'HOLIDAY_VALIDATE',
    +		'HOLIDAY_APPROVE'
    +	);
     
     	/**
     	 * Function called when a Dolibarrr business event is done.
    @@ -103,7 +117,7 @@ class InterfaceNotification extends DolibarrTriggers
     
     				$qualified=0;
     				// Check is this event is supported by notification module
    -				if (in_array($obj->code,$this->listofmanagedevents)) $qualified=1;
    +				if (in_array($obj->code, $this->listofmanagedevents)) $qualified=1;
     				// Check if module for this event is active
     				if ($qualified)
     				{
    @@ -116,7 +130,7 @@ class InterfaceNotification extends DolibarrTriggers
     					elseif ($element == 'withdraw' && empty($conf->prelevement->enabled)) $qualified=0;
     					elseif ($element == 'shipping' && empty($conf->expedition->enabled)) $qualified=0;
     					elseif ($element == 'member' && empty($conf->adherent->enabled)) $qualified=0;
    -					elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member')) && empty($conf->$element->enabled)) $qualified=0;
    +					elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member','expensereport')) && empty($conf->$element->enabled)) $qualified=0;
     				}
     
     				if ($qualified)
    @@ -131,5 +145,4 @@ class InterfaceNotification extends DolibarrTriggers
     
     		return $ret;
     	}
    -
     }
    diff --git a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php
    index 56bbd897f3d..f8f5595887d 100644
    --- a/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php
    +++ b/htdocs/core/triggers/interface_50_modTicket_TicketEmail.class.php
    @@ -30,6 +30,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
      */
     class InterfaceTicketEmail extends DolibarrTriggers
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
     
         /**
    @@ -153,7 +156,7 @@ class InterfaceTicketEmail extends DolibarrTriggers
     	                        include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
     		                    $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, '', '', 0, -1);
     		                    if ($mailfile->error) {
    -	                            setEventMessage($mailfile->error, 'errors');
    +	                            setEventMessages($mailfile->error, $mailfile->errors, 'errors');
     		                    } else {
     		                        $result = $mailfile->sendfile();
     		                    }
    diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    index 3f724e5b096..8282a09a43d 100644
    --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    @@ -17,7 +17,7 @@
      */
     
     /**
    - *  \file       htdocs/core/triggers/interface_50_modStripe_Stripe.class.php
    + *  \file       htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
      *  \ingroup    core
      *  \brief      Fichier
      *  \remarks    Son propre fichier d'actions peut etre cree par recopie de celui-ci:
    @@ -35,6 +35,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
      */
     class InterfaceStripe
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
     
         /**
    @@ -111,13 +114,12 @@ class InterfaceStripe
     	 */
     	public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
     	{
    -		// Put here code you want to execute when a Dolibarr business events occurs.
    +		// Put here code you want to execute when a Dolibarr business event occurs.
     		// Data and type of action are stored into $object and $action
     		global $langs, $db, $conf;
    -		$langs->load("members");
    -		$langs->load("users");
    -		$langs->load("mails");
    -		$langs->load('other');
    +
    +		// Load translation files required by the page
    +        $langs->loadLangs(array("members","other","users","mails"));
     
     		require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
     		$stripe = new Stripe($db);
    @@ -145,19 +147,33 @@ class InterfaceStripe
     				if ($customer)
     				{
     					$namecleaned = $object->name ? $object->name : null;
    -					$vatcleaned = $object->tva_intra ? $object->tva_intra : null;	// We force data to "null" if empty as expected by Stripe
    +					$vatcleaned = $object->tva_intra ? $object->tva_intra : null;
    +
    +					$taxinfo = array('type'=>'vat');
    +					if ($vatcleaned)
    +					{
    +						$taxinfo["tax_id"] = $vatcleaned;
    +					}
    +					// We force data to "null" if not defined as expected by Stripe
    +					if (empty($vatcleaned)) $taxinfo=null;
     
     					// Detect if we change a Stripe info (email, description, vat id)
     					$changerequested = 0;
     					if (! empty($object->email) && $object->email != $customer->email) $changerequested++;
     					if ($namecleaned != $customer->description) $changerequested++;
    -					if ($vatcleaned != $customer->business_vat_id) $changerequested++;
    +					if (! isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) $changerequested++;
    +					elseif (isset($customer->tax_info['tax_id']) && is_null($vatcleaned)) $changerequested++;
    +					elseif (isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned))
    +					{
    +						if ($vatcleaned != $customer->tax_info['tax_id']) $changerequested++;
    +					}
     
     					if ($changerequested)
     					{
     						if (! empty($object->email)) $customer->email = $object->email;
     						$customer->description = $namecleaned;
    -						$customer->business_vat_id = $vatcleaned;
    +						if (empty($taxinfo)) $customer->tax_info = array('type'=>'vat', 'tax_id'=>null);
    +						else $customer->tax_info = $taxinfo;
     
     						$customer->save();
     					}
    @@ -184,7 +200,6 @@ class InterfaceStripe
     		if ($action == 'COMPANYPAYMENTMODE_MODIFY' && $object->type == 'card') {
     
     			// For creation of credit card, we do not create in Stripe automatically
    -
     		}
     		if ($action == 'COMPANYPAYMENTMODE_MODIFY' && $object->type == 'card') {
     			dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id);
    diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
    index 46b1f955177..1338104de0b 100644
    --- a/htdocs/core/website.inc.php
    +++ b/htdocs/core/website.inc.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2013 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2017-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
      *
     * 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,11 +18,76 @@
     
     /**
      *	\file			htdocs/core/website.inc.php
    - *  \brief			Common file loaded used by all website pages (after master.inc.php)
    - *  			    The global variable $website must be defined.
    + *  \brief			Common file loaded by all website pages (after master.inc.php). It set the new object $weblangs, using parameter 'l'.
    + *  				This file is included in top of all container pages.
    + *  			    The global variable $websitekey must be defined.
      */
     
    -
    +// Load website class
     include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
    -$website=new Website($db);
    -$website->fetch(0,$websitekey);
    +// Define $website
    +if (! is_object($website))
    +{
    +	$website=new Website($db);
    +	$website->fetch(0,$websitekey);
    +}
    +// Define $weblangs
    +if (! is_object($weblangs))
    +{
    +	$weblangs = dol_clone($langs);	// TODO Use an object lang from a language set into $website object instead of backoffice
    +}
    +// Define $websitepage if we have $websitepagefile defined
    +if (! $pageid && ! empty($websitepagefile))
    +{
    +	$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +}
    +if ($pageid > 0)
    +{
    +	include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    +	$websitepage=new WebsitePage($db);
    +	$websitepage->fetch($pageid);
    +}
    +
    +// A lang was forced, so we change weblangs init
    +if (GETPOST('l','aZ09')) $weblangs->setDefaultLang(GETPOST('l','aZ09'));
    +// A lang was forced, so we check to find if we must make a redirect on translation page
    +if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php')	// If we browsing page using Dolibarr server or a Native web server
    +{
    +	//print_r(get_defined_constants(true));exit;
    +	if (GETPOST('l','aZ09'))
    +	{
    +		$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    +		$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
    +		$sql.=" WHERE wp.fk_website = ".$website->id;
    +		$sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
    +		if (is_object($websitepage) && $websitepage->fk_page > 0) $sql.=" OR wp.fk_page = ".$websitepage->fk_page." OR wp.rowid = ".$websitepage->fk_page;
    +		$sql.=")";
    +		$sql.= " AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    +
    +		$resql = $db->query($sql);
    +		if ($resql)
    +		{
    +			$obj = $db->fetch_object($resql);
    +			if ($obj)
    +			{
    +				$newpageid = $obj->rowid;
    +				if ($newpageid != $pageid) 		// To avoid to make a redirect on same page (infinite loop)
    +				{
    +					if (defined('USEDOLIBARRSERVER')) {
    +						header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'&l='.GETPOST('l','aZ09'));
    +						exit;
    +					}
    +					else
    +					{
    +						$newpageref = $obj->pageurl;
    +						header("Location: ".$newpageref.'.php?l='.GETPOST('l','aZ09'));
    +						exit;
    +					}
    +				}
    +			}
    +		}
    +	}
    +}
    +
    +// Load websitepage class
    +include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    diff --git a/htdocs/cron/admin/cron.php b/htdocs/cron/admin/cron.php
    index 729772bcf7e..647aa8b96e3 100644
    --- a/htdocs/cron/admin/cron.php
    +++ b/htdocs/cron/admin/cron.php
    @@ -25,7 +25,7 @@
      */
     
     // Dolibarr environment
    -$res = @include("../../main.inc.php"); // From htdocs directory
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/cron.lib.php';
     
    diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php
    index bdbab5e30b0..152657e216a 100644
    --- a/htdocs/cron/card.php
    +++ b/htdocs/cron/card.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2012      Nicolas Villa aka Boyquotes http://informetic.fr
    - * Copyright (C) 2013      Florian Henry <florian.henry@open-concpt.pro>
    - * Copyright (C) 2013-2016 Laurent Destailleur <eldy@users.sourceforge.net>
    +/* Copyright (C) 2012       Nicolas Villa aka Boyquotes http://informetic.fr
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concpt.pro>
    + * Copyright (C) 2013-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -469,11 +470,11 @@ if (($action=="create") || ($action=="edit"))
     	print $langs->trans('CronDtStart')."</td><td>";
     	if(!empty($object->datestart))
     	{
    -	    $form->select_date($object->datestart,'datestart',1,1,'',"cronform");
    +        print $form->selectDate($object->datestart, 'datestart', 1, 1, '', "cronform");
     	}
     	else
     	{
    -	    $form->select_date('','datestart',1,1,'',"cronform");
    +        print $form->selectDate('', 'datestart', 1, 1, '', "cronform");
     	}
     	print "</td>";
     	print "<td>";
    @@ -483,10 +484,10 @@ if (($action=="create") || ($action=="edit"))
     	print "<tr><td>";
     	print $langs->trans('CronDtEnd')."</td><td>";
     	if(!empty($object->dateend)){
    -	    $form->select_date($object->dateend,'dateend',1,1,'',"cronform");
    +        print $form->selectDate($object->dateend, 'dateend', 1, 1, '', "cronform");
     	}
     	else{
    -	    $form->select_date(-1,'dateend',1,1,1,"cronform");
    +        print $form->selectDate(-1, 'dateend', 1, 1, 1, "cronform");
     	}
     	print "</td>";
     	print "<td>";
    @@ -523,11 +524,11 @@ if (($action=="create") || ($action=="edit"))
     	print "</td><td>";
     	if(!empty($object->datenextrun))
     	{
    -	    $form->select_date($object->datenextrun,'datenextrun',1,1,'',"cronform");
    +        print $form->selectDate($object->datenextrun, 'datenextrun', 1, 1, '', "cronform");
     	}
     	else
     	{
    -	    $form->select_date(-1,'datenextrun',1,1,'',"cronform");
    +        print $form->selectDate(-1, 'datenextrun', 1, 1, '', "cronform");
     	}
     	print "</td>";
         print "<td>";
    @@ -545,7 +546,6 @@ if (($action=="create") || ($action=="edit"))
     	print "</div>";
     
     	print "</form>\n";
    -
     }
     else
     {
    diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
    index e3235789d66..a71088f3286 100644
    --- a/htdocs/cron/class/cronjob.class.php
    +++ b/htdocs/cron/class/cronjob.class.php
    @@ -22,23 +22,43 @@
      */
     
     // Put here all includes required by your class file
    -require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
    +require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
     
     
     /**
    - *	Crob Job class
    + *	Cron Job class
      */
     class Cronjob extends CommonObject
     {
    -	public $element='cronjob';			//!< Id that identify managed objects
    -	public $table_element='cronjob';		//!< Name of table without prefix where object is stored
    -    public $picto = 'cron';
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='cronjob';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='cronjob';
    +
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'cron';
    +
    +    /**
    +	 * @var int Entity
    +	 */
    +	public $entity;
     
    -    public $entity;
         public $jobtype;
     	public $tms='';
     	public $datec='';
    -	public $label;
    +
    +	/**
    +     * @var string Cron Job label
    +     */
    +    public $label;
    +
     	public $command;
     	public $classesname;
     	public $objectname;
    @@ -56,10 +76,24 @@ class Cronjob extends CommonObject
     	public $lastoutput;
     	public $unitfrequency;
     	public $frequency;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	public $processing;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_mod;
    +
     	public $nbrun;
     	public $libname;
     	public $test;					// A test condition to know if job is visible/qualified
    @@ -77,7 +111,6 @@ class Cronjob extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -230,8 +263,8 @@ class Cronjob extends CommonObject
             {
                 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."cronjob");
     
    -			if (! $notrigger)
    -			{
    +			//if (! $notrigger)
    +			//{
     	            // Uncomment this and change MYOBJECT to your own tag if you
     	            // want this action calls a trigger.
     
    @@ -241,7 +274,7 @@ class Cronjob extends CommonObject
     	            //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
     	            //if ($result < 0) { $error++; $this->errors=$interface->errors; }
     	            //// End call triggers
    -			}
    +			//}
             }
     
             // Commit or rollback
    @@ -360,6 +393,7 @@ class Cronjob extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Load object in memory from the database
          *
    @@ -374,7 +408,8 @@ class Cronjob extends CommonObject
          */
         function fetch_all($sortorder='DESC', $sortfield='t.rowid', $limit=0, $offset=0, $status=1, $filter='', $processing=-1)
         {
    -    	global $langs;
    +        // phpcs:enable
    +        global $langs;
     
         	$this->lines=array();
     
    @@ -414,7 +449,7 @@ class Cronjob extends CommonObject
         	$sql.= " WHERE 1 = 1";
         	if ($processing >= 0) $sql.= " AND t.processing = ".(empty($processing)?'0':'1');
         	if ($status >= 0 && $status < 2) $sql.= " AND t.status = ".(empty($status)?'0':'1');
    -    	if ($status == 2) $sql.= " AND t.status = 2";
    +    	elseif ($status == 2) $sql.= " AND t.status = 2";
         	//Manage filter
         	if (is_array($filter) && count($filter)>0) {
         		foreach($filter as $key => $value)
    @@ -617,10 +652,8 @@ class Cronjob extends CommonObject
             $resql = $this->db->query($sql);
         	if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
     
    -		if (! $error)
    -		{
    -			if (! $notrigger)
    -			{
    +		//if (! $error && ! $notrigger)
    +		//{
     	            // Uncomment this and change MYOBJECT to your own tag if you
     	            // want this action calls a trigger.
     
    @@ -630,8 +663,7 @@ class Cronjob extends CommonObject
     	            //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
     	            //if ($result < 0) { $error++; $this->errors=$interface->errors; }
     	            //// End call triggers
    -	    	}
    -		}
    +		//}
     
             // Commit or rollback
     		if ($error)
    @@ -747,11 +779,11 @@ class Cronjob extends CommonObject
     			$error++;
     		}
     
    -		if (! $error)
    -		{
    +		//if (! $error)
    +		//{
     
     
    -		}
    +		//}
     
     		unset($this->context['createfromclone']);
     
    @@ -911,6 +943,7 @@ class Cronjob extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Run a job.
     	 * Once job is finished, status and nb of run is updated.
    @@ -921,6 +954,7 @@ class Cronjob extends CommonObject
     	 */
     	function run_jobs($userlogin)
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		$now=dol_now();
    @@ -1181,6 +1215,7 @@ class Cronjob extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Reprogram a job
     	 *
    @@ -1190,6 +1225,7 @@ class Cronjob extends CommonObject
     	 */
     	function reprogram_jobs($userlogin, $now)
     	{
    +        // phpcs:enable
     		dol_syslog(get_class($this)."::reprogram_jobs userlogin:$userlogin", LOG_DEBUG);
     
     		require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
    @@ -1268,6 +1304,7 @@ class Cronjob extends CommonObject
     	    return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -1277,39 +1314,39 @@ class Cronjob extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    -	    global $langs;
    +        // phpcs:enable
    +        global $langs;
     	    $langs->load('users');
     
     	    if ($mode == 0)
     	    {
    -	        $prefix='';
     	        if ($status == 1) return $langs->trans('Enabled');
    -	        if ($status == 0) return $langs->trans('Disabled');
    +	        elseif ($status == 0) return $langs->trans('Disabled');
     	    }
    -	    if ($mode == 1)
    +	    elseif ($mode == 1)
     	    {
     	        if ($status == 1) return $langs->trans('Enabled');
    -	        if ($status == 0) return $langs->trans('Disabled');
    +	        elseif ($status == 0) return $langs->trans('Disabled');
     	    }
    -	    if ($mode == 2)
    +	    elseif ($mode == 2)
     	    {
     	        if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
    -	        if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
    +	        elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
     	    }
    -	    if ($mode == 3)
    +	    elseif ($mode == 3)
     	    {
     	        if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
    -	        if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
    +	        elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
     	    }
    -	    if ($mode == 4)
    +	    elseif ($mode == 4)
     	    {
     	        if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
    -	        if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
    +	        elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
     	    }
    -	    if ($mode == 5)
    +	    elseif ($mode == 5)
     	    {
     	        if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
    -	        if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
    +	        elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
     	    }
     	}
     }
    @@ -1321,12 +1358,24 @@ class Cronjob extends CommonObject
     class Cronjobline
     {
     
    +	/**
    +	 * @var int ID
    +	 */
     	public $id;
    +
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
     
     	public $tms='';
     	public $datec='';
    -	public $label;
    +
    +	/**
    +     * @var string Cron Job Line label
    +     */
    +    public $label;
    +
     	public $jobtype;
     	public $command;
     	public $classesname;
    @@ -1344,9 +1393,22 @@ class Cronjobline
     	public $lastoutput;
     	public $unitfrequency;
     	public $frequency;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_mod;
    +
     	public $note;
     	public $nbrun;
     	public $libname;
    diff --git a/htdocs/datapolicy/ChangeLog.md b/htdocs/datapolicy/ChangeLog.md
    new file mode 100644
    index 00000000000..1c149a77e39
    --- /dev/null
    +++ b/htdocs/datapolicy/ChangeLog.md
    @@ -0,0 +1,24 @@
    +**2.2**
    +* Fix link to accept or refuse
    +
    +**2.1**
    +* Change IT translations
    +
    +**2.0**
    +* Add date of agreement
    +* Add possibility to send e-mail
    +* Save the agreement by e-mail
    +
    +**1.2**
    +* Bug fixed
    +
    +**1.1**
    +* Add some translations
    +* Add some type of company
    +* Bug fixed
    +
    +
    +**1.0**
    +* The end of the beginning
    +
    +
    diff --git a/htdocs/datapolicy/admin/setup.php b/htdocs/datapolicy/admin/setup.php
    new file mode 100644
    index 00000000000..8e92e1e6231
    --- /dev/null
    +++ b/htdocs/datapolicy/admin/setup.php
    @@ -0,0 +1,201 @@
    +<?php
    +/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018      Nicolas ZABOURI      <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/admin/setup.php
    + * \ingroup datapolicy
    + * \brief   datapolicy setup page.
    + */
    +
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
    +require_once '../lib/datapolicy.lib.php';
    +//require_once "../class/myclass.class.php";
    +
    +// Translations
    +$langs->load('admin');
    +$langs->load('companies');
    +$langs->load('members');
    +$langs->load('datapolicy@datapolicy');
    +
    +// Access control
    +if (! $user->admin) accessforbidden();
    +
    +// Parameters
    +$action = GETPOST('action', 'alpha');
    +$backtopage = GETPOST('backtopage', 'alpha');
    +
    +$arrayofparameters=array(
    +    'DATAPOLICY_TIERS_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_ADHERENT'=>array('css'=>'minwidth200'),
    +);
    +
    +
    +/*
    + * Actions
    + */
    +
    +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
    +
    +if (DOL_VERSION < '7' && $action == 'update') {
    +    foreach ($arrayofparameters as $k => $v) {
    +        $res = dolibarr_set_const($db,$k,GETPOST($k),'chaine',0,'',$conf->entity);
    +        if (! $res > 0) $error++;
    +    }
    +    if (! $error)
    +    {
    +        $db->commit();
    +        if (empty($nomessageinsetmoduleoptions)) setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        $db->rollback();
    +        if (empty($nomessageinsetmoduleoptions)) setEventMessages($langs->trans("SetupNotSaved"), null, 'errors');
    +    }
    +}
    +
    +
    +$arrayofparameters=array(
    +    'ThirdParty' => array(
    +        'DATAPOLICY_TIERS_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +    ),
    +    'Contact' => array(
    +        'DATAPOLICY_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +    ),
    +    'Member' => array(
    +        'DATAPOLICY_ADHERENT'=>array('css'=>'minwidth200'),
    +    )
    +);
    +
    +$valTab = array(
    +    '' => $langs->trans('Never'),
    +    '6' => $langs->trans('NB_MONTHS', 6),
    +    '12' => $langs->trans('ONE_YEAR'),
    +    '24' => $langs->trans('NB_YEARS', 2),
    +    '36' => $langs->trans('NB_YEARS', 3),
    +    '48' => $langs->trans('NB_YEARS', 4),
    +    '60' => $langs->trans('NB_YEARS', 5),
    +    '120' => $langs->trans('NB_YEARS', 10),
    +	'180' => $langs->trans('NB_YEARS', 15),
    +	'240' => $langs->trans('NB_YEARS', 20),
    +);
    +
    +
    +/*
    + * View
    + */
    +
    +$page_name = "datapolicySetup";
    +llxHeader('', $langs->trans($page_name));
    +
    +// Subheader
    +$linkback = '<a href="'.($backtopage?$backtopage:DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
    +
    +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicy@datapolicy');
    +
    +// Configuration header
    +$head = datapolicyAdminPrepareHead();
    +dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy");
    +
    +// Setup page goes here
    +echo '<span class="opacitymedium">'.$langs->trans("datapolicySetupPage").'</span><br><br>';
    +
    +
    +if ($action == 'edit')
    +{
    +	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    +	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +	print '<input type="hidden" name="action" value="update">';
    +
    +	print '<table class="noborder" width="100%">';
    +	print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
    +
    +	foreach($arrayofparameters as $title => $tab)
    +	{
    +        print '<tr class="liste_titre"><td class="titlefield" colspan="2">'.$langs->trans($title).'</td></tr>';
    +        foreach($tab as $key => $val)
    +        {
    +            print '<tr class="oddeven"><td>';
    +            print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip'));
    +            print '</td><td>';
    +            print '<select name="'.$key.'"  class="flat '.(empty($val['css'])?'minwidth200':$val['css']).'">';
    +            foreach ($valTab as $key1 => $val1) {
    +                print '<option value="'.$key1.'" ' . ($conf->global->$key == $key1 ? 'selected="selected"' : '') . '>';
    +                print $val1;
    +                print '</option>';
    +            }
    +            print '</select>';
    +            print '</td></tr>';
    +        }
    +	}
    +
    +	print '</table>';
    +
    +	print '<br><div class="center">';
    +	print '<input class="button" type="submit" value="'.$langs->trans("Save").'">';
    +	print '</div>';
    +
    +	print '</form>';
    +	print '<br>';
    +}
    +else
    +{
    +	print '<table class="noborder" width="100%">';
    +	print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
    +
    +    foreach($arrayofparameters as $title => $tab)
    +    {
    +        print '<tr class="liste_titre"><td class="titlefield" colspan="2">'.$langs->trans($title).'</td></tr>';
    +        foreach($tab as $key => $val)
    +        {
    +            print '<tr class="oddeven"><td>';
    +            print $form->textwithpicto($langs->trans($key),$langs->trans('DATAPOLICY_Tooltip_SETUP'));
    +            print '</td><td>' . ($conf->global->$key == '' ? $langs->trans('None') : $valTab[$conf->global->$key]) . '</td></tr>';
    +        }
    +    }
    +
    +	print '</table>';
    +
    +	print '<div class="tabsAction">';
    +	print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
    +	print '</div>';
    +}
    +
    +
    +// Page end
    +dol_fiche_end();
    +
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/datapolicy/admin/setupmail.php b/htdocs/datapolicy/admin/setupmail.php
    new file mode 100644
    index 00000000000..214f673a15f
    --- /dev/null
    +++ b/htdocs/datapolicy/admin/setupmail.php
    @@ -0,0 +1,167 @@
    +<?php
    +
    +/* Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Nicolas ZABOURI         <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php';
    +require_once '../lib/datapolicy.lib.php';
    +
    +// Translations
    +$langs->loadLangs(array('admin', 'companies', 'members', 'datapolicy'));
    +
    +
    +// Parameters
    +$action = GETPOST('action', 'alpha');
    +$backtopage = GETPOST('backtopage', 'alpha');
    +$formadmin = new FormAdmin($db);
    +
    +if (GETPOST('l')) {
    +    $l = GETPOST('l');
    +} else {
    +    $l = $langs->defaultlang;
    +}
    +// Access control
    +if (!$user->admin)
    +    accessforbidden();
    +
    +/*
    + * Actions
    + */
    +
    +include DOL_DOCUMENT_ROOT . '/core/actions_setmoduleoptions.inc.php';
    +
    +if ($action == 'setvalue' && $user->admin) {
    +    $db->begin();
    +    $sub = "DATAPOLICIESSUBJECT_" . $l;
    +    $result = dolibarr_set_const($db, $sub, GETPOST($sub), 'chaine', 0, '', $conf->entity);
    +    $cont = "DATAPOLICIESCONTENT_" . $l;
    +    $result = dolibarr_set_const($db, $cont, GETPOST($cont), 'chaine', 0, '', $conf->entity);
    +    $cont = "TXTLINKDATAPOLICIESACCEPT_" . $l;
    +    $result = dolibarr_set_const($db, $cont, GETPOST($cont), 'chaine', 0, '', $conf->entity);
    +    $cont = "TXTLINKDATAPOLICIESREFUSE_" . $l;
    +    $result = dolibarr_set_const($db, $cont, GETPOST($cont), 'chaine', 0, '', $conf->entity);
    +    $sub = "DATAPOLICIESACCEPT_" . $l;
    +    $result = dolibarr_set_const($db, $sub, GETPOST($sub), 'chaine', 0, '', $conf->entity);
    +    $sub = "DATAPOLICIESREFUSE_" . $l;
    +    $result = dolibarr_set_const($db, $sub, GETPOST($sub), 'chaine', 0, '', $conf->entity);
    +    if (!$result > 0)
    +        $error++;
    +    if (!$error) {
    +        $db->commit();
    +        setEventMessage($langs->trans("SetupSaved"));
    +    } else {
    +        $db->rollback();
    +        dol_print_error($db);
    +    }
    +}
    +
    +
    +/*
    + * View
    + */
    +
    +$page_name = "datapolicySetup";
    +llxHeader('', $langs->trans($page_name));
    +
    +// Subheader
    +$linkback = '<a href="' . ($backtopage ? $backtopage : DOL_URL_ROOT . '/admin/modules.php?restore_lastsearch_values=1') . '">' . $langs->trans("BackToModuleList") . '</a>';
    +
    +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicy@datapolicy');
    +
    +// Configuration header
    +$head = datapolicyAdminPrepareHead();
    +dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy");
    +
    +
    +
    +
    +
    +print "<script type='text/javascript'>
    +        $(document).ready(function(){
    +         $('#default_lang').change(function(){
    +         lang=$('#default_lang').val();
    +                    window.location.replace('" . $_SERVER['PHP_SELF'] . "?l='+lang);
    +                    });
    +        });
    +</script>";
    +
    +print '<form method="post" action="' . $_SERVER["PHP_SELF"] . '?l=' . $l . '">';
    +print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
    +print '<input type="hidden" name="action" value="setvalue">';
    +print '<table>';
    +if ($conf->global->MAIN_MULTILANGS) {
    +    print '<tr><td>' . fieldLabel('DefaultLang', 'default_lang') . '</td><td colspan="3" class="maxwidthonsmartphone">' . "\n";
    +    print $formadmin->select_language((GETPOST('l') ? GETPOST('l') : $langs->defaultlang), 'default_lang', 0, 0, 1, 0, 0, 'maxwidth200onsmartphone');
    +    print '</tr>';
    +}
    +$subject = 'DATAPOLICIESSUBJECT_' . $l;
    +$linka = 'TXTLINKDATAPOLICIESACCEPT_' . $l;
    +$linkr = 'TXTLINKDATAPOLICIESREFUSE_' . $l;
    +$content = 'DATAPOLICIESCONTENT_' . $l;
    +$acc = 'DATAPOLICIESACCEPT_' . $l;
    +$ref = 'DATAPOLICIESREFUSE_' . $l;
    +print '<tr class"oddeven"><td class="fieldrequired">';
    +print $langs->trans('DATAPOLICIESSUBJECTMAIL') . '</td><td>';
    +print '<input type="text" size="100" name="' . $subject . '" value="' . $conf->global->$subject . '" />';
    +print '</td><tr>';
    +print '<tr class"oddeven"><td class="fieldrequired">';
    +print $langs->trans('DATAPOLICIESCONTENTMAIL').'</td><td>';
    +print $langs->trans('DATAPOLICIESSUBSITUTION');echo'__LINKACCEPT__,__LINKREFUSED__,__FIRSTNAME__,__NAME__,__CIVILITY__';
    +$doleditor = new DolEditor($content, $conf->global->$content, '', 250, 'Full', '', false, true, 1, 200, 70);
    +$doleditor->Create();
    +print '</td><tr>';
    +print '<tr class"oddeven"><td class="fieldrequired">';
    +print $langs->trans('TXTLINKDATAPOLICIESACCEPT') . '</td><td>';
    +print '<input type="text" size="200" name="' . $linka . '" value="' . $conf->global->$linka . '" />';
    +print '</td><tr>';
    +print '<tr class"oddeven"><td class="fieldrequired">';
    +print $langs->trans('TXTLINKDATAPOLICIESREFUSE') . '</td><td>';
    +print '<input type="text" size="200" name="' . $linkr . '" value="' . $conf->global->$linkr . '" />';
    +print '</td><tr>';
    +print '<tr class"oddeven"><td class="fieldrequired">';
    +
    +print $langs->trans('DATAPOLICIESACCEPT').'</td><td>';
    +
    +$doleditor = new DolEditor($acc, $conf->global->$acc, '', 250, 'Full', '', false, true, 1, 200, 70);
    +$doleditor->Create();
    +print '</td><tr>';
    +print '<tr class"oddeven"><td class="fieldrequired">';
    +print $langs->trans('DATAPOLICIESREFUSE').'</td><td>';
    +
    +print $langs->trans('');
    +$doleditor = new DolEditor($ref, $conf->global->$ref, '', 250, 'Full', '', false, true, 1, 200, 70);
    +$doleditor->Create();
    +print '</td><tr>';
    +print '</table>';
    +
    +print '<br><center><input type="submit" class="button" value="' . $langs->trans("Modify") . '"></center>';
    +
    +print '</form>';
    +
    +dol_fiche_end();
    +
    +print '<br><br>';
    +
    +print $langs->trans('SendAgreementText');
    +print '<a class="button" href="'.dol_buildpath('/datapolicy/mailing.php').'">'.$langs->trans('SendAgreement').'</a>';
    +
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/datapolicy/class/actions_datapolicy.class.php b/htdocs/datapolicy/class/actions_datapolicy.class.php
    new file mode 100644
    index 00000000000..21fcb4a5a44
    --- /dev/null
    +++ b/htdocs/datapolicy/class/actions_datapolicy.class.php
    @@ -0,0 +1,482 @@
    +<?php
    +/* Copyright (C) 2018       Nicolas ZABOURI         <info@inovea-conseom.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/class/actions_datapolicy.class.php
    + * \ingroup datapolicy
    + * \brief   Example hook overload.
    + */
    +
    +/**
    + * Class ActionsDatapolicy
    + */
    +class ActionsDatapolicy
    +{
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +     * @var string Error
    +     */
    +    public $error = '';
    +
    +    /**
    +     * @var array Errors
    +     */
    +    public $errors = array();
    +
    +    /**
    +     * @var array Hook results. Propagated to $hookmanager->resArray for later reuse
    +     */
    +    public $results = array();
    +
    +    /**
    +     * @var string String displayed by executeHook() immediately after return
    +     */
    +    public $resprints;
    +
    +    /**
    +     * Constructor
    +     *
    +     *  @param  DoliDB      $db      Database handler
    +     */
    +    public function __construct($db)
    +    {
    +        $this->db = $db;
    +    }
    +
    +    /**
    +     * Execute action
    +     *
    +     * @param   array           $parameters		Array of parameters
    +     * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +     * @param   string          $action      	'add', 'update', 'view'
    +     * @return  int         					<0 if KO,
    +     *                           				=0 if OK but we want to process standard actions too,
    +     *                            				>0 if OK and we want to replace standard actions.
    +     */
    +    function getNomUrl($parameters, &$object, &$action)
    +    {
    +        global $db, $langs, $conf, $user;
    +        $this->resprints = '';
    +        return 0;
    +    }
    +
    +    /**
    +     * Overloading the doActions function : replacing the parent's function with the one below
    +     *
    +     * @param   array           $parameters     Hook metadatas (context, etc...)
    +     * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +     * @param   string          $action         Current action (if set). Generally create or edit or null
    +     * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
    +     * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
    +     */
    +    public function doActions($parameters, &$object, &$action, $hookmanager)
    +    {
    +        global $conf, $user, $langs;
    +        $langs->load('datapolicy@datapolicy');
    +        $error = 0; // Error counter
    +
    +        if (GETPOST('socid') && $parameters['currentcontext'] == 'thirdpartycard') {
    +            $object->fetch(GETPOST('socid'));
    +        }
    +
    +        // FIXME Removed hard coded id, use codes
    +        if ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'anonymiser' && (in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8)) {
    +            // on verifie si l'objet est utilisé
    +            if ($object->isObjectUsed(GETPOST('socid'))) {
    +                $object->name = $langs->trans('ANONYME');
    +                $object->name_bis = '';
    +                $object->name_alias = '';
    +                $object->address = '';
    +                $object->town = '';
    +                $object->zip = '';
    +                $object->phone = '';
    +                $object->email = '';
    +                $object->url = '';
    +                $object->fax = '';
    +                $object->state = '';
    +                $object->country = '';
    +                $object->state_id = '';
    +                $object->skype = '';
    +                $object->country_id = '';
    +                $object->note_private = $object->note_private . '<br/>' . $langs->trans('ANONYMISER_AT', dol_print_date(time()));
    +
    +                if ($object->update($object->id, $user, 0)) {
    +
    +                    // On supprime les contacts associé
    +                    $sql = "DELETE FROM " . MAIN_DB_PREFIX . "socpeople WHERE fk_soc = " . $object->id;
    +                    $this->db->query($sql);
    +
    +                    setEventMessages($langs->trans('ANONYMISER_SUCCESS'), array());
    +                    header('Location:' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id);
    +                }
    +            }
    +        } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'datapolicy_portabilite') {
    +            header('Content-Type: application/csv');
    +            header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
    +            header('Pragma: no-cache');
    +            $object->fetch(GETPOST('socid'));
    +            echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
    +            echo $object->name . ';';
    +            echo ';';
    +            echo ';';
    +            echo ';';
    +            echo ';';
    +            echo $object->address . ';';
    +            echo $object->zip . ';';
    +            echo $object->town . ';';
    +            echo $object->state . ';';
    +            echo $object->country . ';';
    +            echo $object->email . ';';
    +            echo $object->phone . ';';
    +            echo ';';
    +            echo ';';
    +            echo $object->skype . ';';
    +            echo ';';
    +            exit;
    +        } elseif ($parameters['currentcontext'] == 'membercard' && $action == 'datapolicy_portabilite') {
    +            header('Content-Type: application/csv');
    +            header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
    +            header('Pragma: no-cache');
    +            $soc = $object->fetch_thirdparty();
    +
    +            echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
    +            echo $object->lastname . ';';
    +            echo $object->firstname . ';';
    +            echo $object->getCivilityLabel() . ';';
    +            echo ($soc != -1 ? $object->thirdparty->name : '') . ';';
    +            echo ';';
    +            echo $object->address . ';';
    +            echo $object->zip . ';';
    +            echo $object->town . ';';
    +            echo $object->state . ';';
    +            echo $object->country . ';';
    +            echo $object->email . ';';
    +            echo $object->phone . ';';
    +            echo $object->phone_perso . ';';
    +            echo $object->phone_mobile . ';';
    +            echo $object->skype . ';';
    +            echo dol_print_date($object->birth) . ';';
    +            exit;
    +        } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'datapolicy_portabilite') {
    +            $object->fetch(GETPOST('id'));
    +            header('Content-Type: application/csv');
    +            header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
    +            header('Pragma: no-cache');
    +            $soc = $object->fetch_thirdparty();
    +            echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
    +            echo $object->lastname . ';';
    +            echo $object->firstname . ';';
    +            echo $object->getCivilityLabel() . ';';
    +            echo ($soc != -1 ? $object->thirdparty->name : '') . ';';
    +            echo $object->poste . ';';
    +            echo $object->address . ';';
    +            echo $object->zip . ';';
    +            echo $object->town . ';';
    +            echo $object->state . ';';
    +            echo $object->country . ';';
    +            echo $object->email . ';';
    +            echo $object->phone_pro . ';';
    +            echo $object->phone_perso . ';';
    +            echo $object->phone_mobile . ';';
    +            echo $object->jabberid . ';';
    +            echo dol_print_date($object->birth) . ';';
    +            exit;
    +        } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'send_datapolicy') {
    +            $object->fetch(GETPOST('id'));
    +
    +            require_once  DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
    +            require_once  DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +            DataPolicy::sendMailDataPolicyContact($object);
    +        }
    +         elseif ($parameters['currentcontext'] == 'membercard' && $action == 'send_datapolicy') {
    +             $object->fetch(GETPOST('id'));
    +            require_once  DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
    +            require_once  DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +            DataPolicy::sendMailDataPolicyAdherent($object);
    +        } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'send_datapolicy') {
    +            $object->fetch(GETPOST('socid'));
    +            require_once  DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
    +            require_once  DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +            DataPolicy::sendMailDataPolicyCompany($object);
    +        }
    +
    +
    +        if (!$error) {
    +            $this->results = array('myreturn' => 999);
    +            $this->resprints = 'A text to show';
    +            return 0; // or return 1 to replace standard code
    +        } else {
    +            $this->errors[] = 'Error message';
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * Overloading the doActions function : replacing the parent's function with the one below
    +     *
    +     * @param   array           $parameters     Hook metadatas (context, etc...)
    +     * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +     * @param   string          $action         Current action (if set). Generally create or edit or null
    +     * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
    +     * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
    +     */
    +    public function doMassActions($parameters, &$object, &$action, $hookmanager)
    +    {
    +        global $conf, $user, $langs;
    +
    +        $error = 0; // Error counter
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +        //if (in_array($parameters['currentcontext'], array('somecontext1', 'somecontext2'))) {
    +        //    // do something only for the context 'somecontext1' or 'somecontext2'
    +        //    foreach ($parameters['toselect'] as $objectid) {
    +        //        // Do action on each object id
    +        //    }
    +        //}
    +
    +        if (!$error) {
    +            $this->results = array('myreturn' => 999);
    +            $this->resprints = 'A text to show';
    +            return 0; // or return 1 to replace standard code
    +        } else {
    +            $this->errors[] = 'Error message';
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * Overloading the addMoreMassActions function : replacing the parent's function with the one below
    +     *
    +     * @param   array           $parameters		Hook metadatas (context, etc...)
    +     * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +     * @param   string          $action         Current action (if set). Generally create or edit or null
    +     * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
    +     * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
    +     */
    +    public function addMoreMassActions($parameters, &$object, &$action, $hookmanager)
    +    {
    +        global $conf, $user, $langs;
    +
    +        $error = 0; // Error counter
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +        if (in_array($parameters['currentcontext'], array('somecontext1', 'somecontext2'))) {  // do something only for the context 'somecontext1' or 'somecontext2'
    +            $this->resprints = '<option value="0"' . ($disabled ? ' disabled="disabled"' : '') . '>' . $langs->trans("datapolicyMassAction") . '</option>';
    +        }
    +
    +        if (!$error) {
    +            return 0; // or return 1 to replace standard code
    +        } else {
    +            $this->errors[] = 'Error message';
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * Execute action
    +     *
    +     * @param   array	$parameters		Array of parameters
    +     * @param   Object	$object		   	Object output on PDF
    +     * @param   string	$action     	'add', 'update', 'view'
    +     * @return  int 		        	<0 if KO,
    +     *                          		=0 if OK but we want to process standard actions too,
    +     *  	                            >0 if OK and we want to replace standard actions.
    +     */
    +    function beforePDFCreation($parameters, &$object, &$action)
    +    {
    +        global $conf, $user, $langs;
    +        global $hookmanager;
    +
    +        $outputlangs = $langs;
    +
    +        $ret = 0;
    +        $deltemp = array();
    +        dol_syslog(get_class($this) . '::executeHooks action=' . $action);
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +        if (in_array($parameters['currentcontext'], array('somecontext1', 'somecontext2'))) {  // do something only for the context 'somecontext1' or 'somecontext2'
    +
    +        }
    +
    +        return $ret;
    +    }
    +
    +    /**
    +     * Execute action
    +     *
    +     * @param	array	$parameters		Array of parameters
    +     * @param   Object	$pdfhandler   	PDF builder handler
    +     * @param   string	$action     	'add', 'update', 'view'
    +     * @return  int 		        	<0 if KO,
    +     *                          		=0 if OK but we want to process standard actions too,
    +     *  	                            >0 if OK and we want to replace standard actions.
    +     */
    +    function afterPDFCreation($parameters, &$pdfhandler, &$action)
    +    {
    +        global $conf, $user, $langs;
    +        global $hookmanager;
    +
    +        $outputlangs = $langs;
    +
    +        $ret = 0;
    +        $deltemp = array();
    +        dol_syslog(get_class($this) . '::executeHooks action=' . $action);
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +        if (in_array($parameters['currentcontext'], array('somecontext1', 'somecontext2'))) {  // do something only for the context 'somecontext1' or 'somecontext2'
    +
    +        }
    +
    +        return $ret;
    +    }
    +
    +    /**
    +     * addMoreActionsButtons
    +     *
    +     * @param array 		$parameters		array of parameters
    +     * @param Object	 	$object			Object
    +     * @param string		$action			Actions
    +     * @param HookManager	$hookmanager	Hook manager
    +     * @return void
    +     */
    +    function addMoreActionsButtons($parameters, &$object, &$action, $hookmanager)
    +    {
    +        global $conf, $user, $langs;
    +        $langs->load('datapolicy@datapolicy');
    +
    +        if (! empty($conf->global->DATAPOLICIES_ENABLE_EMAILS))
    +        {
    +	        $dialog = '<div id="dialogdatapolicy" style="display:none;" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">';
    +	        $dialog .= '<div class="confirmmessage">' . img_help('', '') . ' ' . $langs->trans('DATAPOLICIES_PORTABILITE_CONFIRMATION') . '</div>';
    +	        $dialog .= "</div>";
    +	        $dialog .= '<script>
    +	                  $( function() {
    +	                    $("#rpgpdbtn").on("click", function(){
    +	                        var href = $(this).attr("href");
    +	                        $( "#dialogdatapolicy" ).dialog({
    +	                          modal: true,
    +	                          buttons: {
    +	                            "OK": function() {
    +	                              window.open(href);
    +	                              $( this ).dialog( "close" );
    +	                            },
    +	                            "' . $langs->trans('Cancel') . '": function() {
    +	                              $( this ).dialog( "close" );
    +	                            }
    +	                          }
    +	                        });
    +
    +
    +	                    return false;
    +	                    });
    +	                  } );
    +	                  </script>';
    +	        echo $dialog;
    +	        if ($parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=datapolicy_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	        } elseif ($parameters['currentcontext'] == 'membercard') {
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=datapolicy_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	        } elseif ($parameters['currentcontext'] == 'contactcard') {
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=datapolicy_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	        }
    +	        if (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=send_datapolicy" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'membercard') {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=send_datapolicy" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'contactcard') {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=send_datapolicy" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        }
    +        }
    +    }
    +
    +    /**
    +     * printCommonFooter
    +     *
    +     * @param array 		$parameters		array of parameters
    +     * @param Object	 	$object			Object
    +     * @param string		$action			Actions
    +     * @param HookManager	$hookmanager	Hook manager
    +     * @return void
    +     */
    +    function printCommonFooter($parameters, &$object, &$action, $hookmanager)
    +    {
    +        global $conf, $user, $langs;
    +
    +        $jsscript = '';
    +        if ($parameters['currentcontext'] == 'thirdpartycard') {
    +            if (GETPOST('action') == 'create' || GETPOST('action') == 'edit' || GETPOST('action') == '') {
    +                $jsscript .= '<script>';
    +                $jsscript .= "var elementToHide = 'tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection';" . PHP_EOL;
    +                $jsscript .= "var forme_juridique = [" . PHP_EOL;
    +                $jsscript .= "11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005" . PHP_EOL;
    +                $jsscript .= "];" . PHP_EOL;
    +                $jsscript .= "function hideRgPD() {" . PHP_EOL;
    +                $jsscript .= " if ($('#typent_id').val() == 8 || forme_juridique.indexOf(parseInt($('#forme_juridique_code').val())) > -1) {" . PHP_EOL;
    +                $jsscript .= " console.log(elementToHide);" . PHP_EOL;
    +                $jsscript .= " $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').show(); } else { $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').hide(); }}" . PHP_EOL;
    +                $jsscript .= "hideRgPD();" . PHP_EOL;
    +                $jsscript .= "$('#forme_juridique_code, #typent_id').change(function(){ hideRgPD(); });" . PHP_EOL;
    +                $jsscript .= '</script>';
    +            } elseif (GETPOST('action') == 'confirm_delete' && GETPOST('confirm') == 'yes' && GETPOST('socid') > 0) {
    +
    +                // La suppression n'a pas été possible
    +                require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
    +                $societe = new Societe($this->db);
    +                $societe->fetch(GETPOST('socid'));
    +                // On vérifie si il est utilisé
    +                if ((in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $societe->typent_id == 8) && $societe->isObjectUsed(GETPOST('socid'))) {
    +
    +                    require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
    +                    $form = new Form($this->db);
    +                    echo $form->formconfirm($_SERVER["PHP_SELF"] . "?socid=" . GETPOST('socid'), substr($langs->trans("DATAPOLICIES_POPUP_ANONYME_TITLE"), 0, strlen($langs->trans("DATAPOLICIES_POPUP_ANONYME_TITLE")) - 2), $langs->trans("DATAPOLICIES_POPUP_ANONYME_TEXTE"), 'anonymiser', '', '', 1);
    +                }
    +            }
    +
    +            if (GETPOST('socid')) {
    +                require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
    +                $societe = new Societe($this->db);
    +                $societe->fetch(GETPOST('socid'));
    +
    +                if (!in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) && $societe->typent_id != 8) {
    +
    +                    require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
    +                    $jsscript .= '<script>';
    +                    $jsscript .= "var elementToHide = 'td.societe_extras_datapolicy_opposition_traitement, td.societe_extras_datapolicy_opposition_prospection, td.societe_extras_datapolicy_consentement';" . PHP_EOL;
    +                    $jsscript .= "$(elementToHide).parent('tr').hide();" . PHP_EOL;
    +                    $jsscript .= '</script>';
    +                }
    +            }
    +        } elseif ($parameters['currentcontext'] == 'contactcard') {
    +            if (GETPOST('action') == 'create' || GETPOST('action') == 'edit') {
    +                $jsscript .= '<script>';
    +                $jsscript .= "$('#options_datapolicy_opposition_traitement, #options_datapolicy_opposition_prospection, input[name=\"options_datapolicy_opposition_traitement\"], input[name=\"options_datapolicy_opposition_prospection\"]').change(function(){
    +                    if($('#options_datapolicy_opposition_traitement').prop('checked') == true || $('input[name=options_datapolicy_opposition_traitement]').prop('checked') || $('#options_datapolicy_opposition_prospection').prop('checked') || $('input[name=options_datapolicy_opposition_prospection]').prop('checked')) {
    +                        $('#no_email').val(1);
    +                    }
    +                });";
    +                $jsscript .= '</script>';
    +            }
    +        }
    +
    +        echo $jsscript;
    +    }
    +}
    diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php
    new file mode 100644
    index 00000000000..4914d248490
    --- /dev/null
    +++ b/htdocs/datapolicy/class/datapolicy.class.php
    @@ -0,0 +1,356 @@
    +<?php
    +/* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/class/datapolicy.class.php
    + * \ingroup datapolicy
    + * \brief   Class to manage feature of Data Policy module.
    + */
    +include_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
    +include_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
    +include_once DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
    +
    +
    +/**
    + * Class DataPolicy
    + */
    +Class DataPolicy extends Contact
    +{
    +	/**
    +	 * getAllContactNotInformed
    +	 *
    +	 * @return number
    +	 */
    +    function getAllContactNotInformed()
    +    {
    +        global $langs, $conf, $db, $user;
    +
    +        $langs->load("companies");
    +
    +        $sql = "SELECT c.rowid";
    +        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople as c";
    +        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON c.fk_soc = s.rowid";
    +        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "socpeople_extrafields as spe ON spe.fk_object = c.rowid";
    +        $sql .= " WHERE (c.statut=1 AND c.no_email=0 AND (spe.datapolicy_consentement=0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement=0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection=0 OR spe.datapolicy_opposition_prospection IS NULL))";
    +        $sql .= " AND spe.datapolicy_send IS NULL";
    +        $sql .= " AND c.entity=" . $conf->entity;
    +        $resql = $this->db->query($sql);
    +        if ($resql) {
    +            $num = $this->db->num_rows($resql);
    +            $i = 0;
    +            while ($i < $num) {
    +                $obj = $this->db->fetch_object($resql);
    +                $contact = new Contact($db);
    +                $contact->fetch($obj->rowid);
    +
    +                DataPolicy::sendMailDataPolicyContact($contact);
    +                $i++;
    +            }
    +        } else {
    +            $this->error = $this->db->error();
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * getAllCompaniesNotInformed
    +     *
    +     * @return number
    +     */
    +    function getAllCompaniesNotInformed()
    +    {
    +        global $langs, $conf, $db, $user;
    +
    +        $langs->load("companies");
    +
    +        $sql = "SELECT s.rowid";
    +        $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s";
    +        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_extrafields as se ON se.fk_object = s.rowid";
    +        $sql .= " WHERE s.statut=0 AND (se.datapolicy_consentement=0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement=0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection=0 OR se.datapolicy_opposition_prospection IS NULL)";
    +        $sql .= " AND se.datapolicy_send IS NULL";
    +        $sql .= " AND s.entity=" . $conf->entity;
    +        $resql = $this->db->query($sql);
    +        if ($resql) {
    +            $num = $this->db->num_rows($resql);
    +            $i = 0;
    +            while ($i < $num) {
    +                $obj = $this->db->fetch_object($resql);
    +                $societe = new Societe($db);
    +                $societe->fetch($obj->rowid);
    +
    +                DataPolicy::sendMailDataPolicyCompany($societe);
    +                $i++;
    +            }
    +        } else {
    +            $this->error = $this->db->error();
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * getAllAdherentsNotInformed
    +     *
    +     * @return number
    +     */
    +    function getAllAdherentsNotInformed()
    +    {
    +        global $langs, $conf, $db, $user;
    +
    +        $langs->load("adherent");
    +
    +        $sql = "SELECT a.rowid";
    +        $sql .= " FROM " . MAIN_DB_PREFIX . "adherent as a";
    +        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "adherent_extrafields as ae ON ae.fk_object = a.rowid";
    +        $sql .= " WHERE a.statut=0 AND (ae.datapolicy_consentement=0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)";
    +        $sql .= " AND ae.datapolicy_send IS NULL";
    +        $sql .= " AND a.entity=" . $conf->entity;
    +        $resql = $this->db->query($sql);
    +        if ($resql) {
    +            $num = $this->db->num_rows($resql);
    +            $i = 0;
    +            while ($i < $num) {
    +                $obj = $this->db->fetch_object($resql);
    +                $adherent = new Adherent($db);
    +                $adherent->fetch($obj->rowid);
    +
    +                DataPolicy::sendMailDataPolicyAdherent($adherent);
    +                $i++;
    +            }
    +        } else {
    +            $this->error = $this->db->error();
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * sendMailDataPolicyContact
    +     *
    +     * @param 	mixed		$contact		Contact
    +     * @return	void
    +     */
    +    function sendMailDataPolicyContact($contact)
    +    {
    +     	global $langs, $conf, $db, $user;
    +
    +     	$error = 0;
    +
    +     	$from = $user->getFullName($langs) . ' <' . $user->email . '>';
    +
    +     	$sendto = $contact->email;
    +     	$code= md5($contact->email);
    +     	if (!empty($contact->default_lang)) {
    +     		$l = $contact->default_lang;
    +     	} else {
    +     		$l = $langs->defaultlang;
    +     	}
    +     	$s = "DATAPOLICIESSUBJECT_" . $l;
    +     	$ma = "DATAPOLICIESCONTENT_" . $l;
    +     	$la = 'TXTLINKDATAPOLICIESACCEPT_' . $l;
    +     	$lr = 'TXTLINKDATAPOLICIESREFUSE_' . $l;
    +
    +     	$subject = $conf->global->$s;
    +     	$message = $conf->global->$ma;
    +     	$linka = $conf->global->$la;
    +     	$linkr = $conf->global->$lr;
    +     	$sendtocc = $sendtobcc = '';
    +     	$filepath = $mimetype = $filename = array();
    +     	$deliveryreceipt = 0;
    +
    +     	$substitutionarray = array(
    +     	'__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=1&c='.$contact->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    +     	'__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=2&c='.$contact->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
    +     	'__FIRSTNAME__' => $contact->firstname,
    +     	'__NAME__' => $contact->lastname,
    +     	'__CIVILITY__' => $contact->civility,
    +     	);
    +     	$subject = make_substitutions($subject, $substitutionarray);
    +     	$message = make_substitutions($message, $substitutionarray);
    +
    +     	$actiontypecode = 'AC_EMAIL';
    +     	$actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto;
    +     	if ($message) {
    +     		if ($sendtocc)
    +     			$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
    +     			$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
    +     			$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
    +     			$actionmsg = dol_concatdesc($actionmsg, $message);
    +     	}
    +
    +
    +     	// Send mail
    +     	require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
    +     	$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1);
    +
    +     	if ($mailfile->error) {
    +     		$resultmasssend .= '<div class="error">' . $mailfile->error . '</div>';
    +     	} else {
    +     		$result4 = $mailfile->sendfile();
    +     		if (!$error) {
    +
    +     			$resultmasssend .= $langs->trans("MailSent") . ': ' . $sendto . "<br>";
    +     			$contact->array_options['options_datapolicy_send'] = date('Y-m-d', time());
    +     			$contact->update($contact->id);
    +     		} else {
    +     			dol_print_error($db);
    +     		}
    +     	}
    +     	setEventMessage($resultmasssend);
    +    }
    +
    +    /**
    +     * sendMailDataPolicyCompany
    +     *
    +     * @param Societe	$societe	Object societe
    +     * @return	void
    +     */
    +    function sendMailDataPolicyCompany($societe)
    +    {
    +     	global $langs, $conf, $db, $user;
    +
    +     	$error = 0;
    +
    +     	$from = $user->getFullName($langs) . ' <' . $user->email . '>';
    +
    +     	$sendto = $societe->email;
    +
    +     	$code= md5($societe->email);
    +     	if (!empty($societe->default_lang)) {
    +     		$l = $societe->default_lang;
    +     	} else {
    +     		$l = $langs->defaultlang;
    +     	}
    +     	$s = "DATAPOLICIESSUBJECT_" . $l;
    +     	$ma = "DATAPOLICIESCONTENT_" . $l;
    +     	$la = 'TXTLINKDATAPOLICIESACCEPT_' . $l;
    +     	$lr = 'TXTLINKDATAPOLICIESREFUSE_' . $l;
    +
    +     	$subject = $conf->global->$s;
    +     	$message = $conf->global->$ma;
    +     	$linka = $conf->global->$la;
    +     	$linkr = $conf->global->$lr;
    +     	$sendtocc = $sendtobcc = '';
    +     	$filepath = $mimetype = $filename = array();
    +     	$deliveryreceipt = 0;
    +
    +     	$substitutionarray = array(
    +            '__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=1&s='.$societe->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    +            '__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=2&s='.$societe->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
    +     	);
    +     	$subject = make_substitutions($subject, $substitutionarray);
    +     	$message = make_substitutions($message, $substitutionarray);
    +
    +     	$actiontypecode = 'AC_EMAIL';
    +     	$actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto;
    +     	if ($message) {
    +     		if ($sendtocc) {
    +                 $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
    +             }
    +            $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
    +            $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
    +            $actionmsg .= dol_concatdesc($actionmsg, $message);
    +        }
    +
    +     	// Send mail
    +     	require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
    +     	$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1);
    +     	if ($mailfile->error) {
    +     		$resultmasssend .= '<div class="error">' . $mailfile->error . '</div>';
    +     	} else {
    +     		$result4 = $mailfile->sendfile();
    +
    +     		if (!$error) {
    +     			$resultmasssend .= $langs->trans("MailSent") . ': ' . $sendto . "<br>";
    +     			$societe->array_options['options_datapolicy_send'] = date('Y-m-d', time());
    +     			$societe->update($societe->id);
    +     		} else {
    +     			dol_print_error($db);
    +     		}
    +     	}
    +     	setEventMessage($resultmasssend);
    +    }
    +
    +    /**
    +     * sendMailDataPolicyAdherent
    +     *
    +     * @param Adherent	$adherent		Member
    +     * @return void
    +     */
    +    function sendMailDataPolicyAdherent($adherent)
    +    {
    +    	global $langs, $conf, $db, $user;
    +
    +    	$error = 0;
    +
    +    	$from = $user->getFullName($langs) . ' <' . $user->email . '>';
    +
    +    	$sendto = $adherent->email;
    +
    +    	$code= md5($adherent->email);
    +    	if (!empty($adherent->default_lang)) {
    +    		$l = $adherent->default_lang;
    +    	} else {
    +    		$l = $langs->defaultlang;
    +    	}
    +    	$la = 'TXTLINKDATAPOLICIESACCEPT_' . $l;
    +    	$lr = 'TXTLINKDATAPOLICIESREFUSE_' . $l;
    +
    +    	$subject = $conf->global->$s;
    +    	$message = $conf->global->$ma;
    +    	$linka = $conf->global->$la;
    +    	$linkr = $conf->global->$lr;
    +    	$sendtocc = $sendtobcc = '';
    +    	$filepath = $mimetype = $filename = array();
    +    	$deliveryreceipt = 0;
    +
    +    	$substitutionarray = array(
    +            '__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=1&a='.$adherent->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    +            '__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=2&a='.$adherent->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
    +    	);
    +    	$subject = make_substitutions($subject, $substitutionarray);
    +    	$message = make_substitutions($message, $substitutionarray);
    +
    +    	$actiontypecode = 'AC_EMAIL';
    +    	$actionmsg = $langs->transnoentities('MailSentBy') . ' ' . $from . ' ' . $langs->transnoentities('To') . ' ' . $sendto;
    +    	if ($message) {
    +    		if ($sendtocc) {
    +                $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
    +            }
    +            $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
    +            $actionmsg .= dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
    +            $actionmsg .= dol_concatdesc($actionmsg, $message);
    +    	}
    +
    +
    +    	// Send mail
    +    	require_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
    +    	$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1);
    +    	if ($mailfile->error) {
    +    		$resultmasssend .= '<div class="error">' . $mailfile->error . '</div>';
    +    	} else {
    +    		$result4 = $mailfile->sendfile();
    +
    +    		if (!$error) {
    +    			$resultmasssend .= $langs->trans("MailSent") . ': ' . $sendto . "<br>";
    +    			$adherent->array_options['options_datapolicy_send'] = date('Y-m-d', time());
    +    			$adherent->update($user);
    +    		} else {
    +    			dol_print_error($db);
    +    		}
    +    	}
    +    	setEventMessage($resultmasssend);
    +    }
    +}
    diff --git a/htdocs/datapolicy/class/datapolicycron.class.php b/htdocs/datapolicy/class/datapolicycron.class.php
    new file mode 100644
    index 00000000000..ab4b55b35dc
    --- /dev/null
    +++ b/htdocs/datapolicy/class/datapolicycron.class.php
    @@ -0,0 +1,521 @@
    +<?php
    +/* Copyright (C) 2018 Nicolas ZABOURI   <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/class/datapolicycron.class.php
    + * \ingroup datapolicy
    + * \brief   Example hook overload.
    + */
    +
    +/**
    + * Class DataPolicyCron
    + */
    +class DataPolicyCron
    +{
    +	/**
    +	 * Function exec
    +	 *
    +	 * @return boolean
    +	 */
    +    public function exec()
    +    {
    +        global $conf, $db, $langs, $user;
    +
    +        $langs->load('datapolicy@datapolicy');
    +
    +        // FIXME Removed hardcoded values of id
    +        $arrayofparameters=array(
    +            'DATAPOLICIES_TIERS_CLIENT' => array(
    +                'sql' => "
    +                    SELECT s.rowid FROM ".MAIN_DB_PREFIX."societe as s
    +                    WHERE (s.fk_forme_juridique IN (11, 12, 13, 15, 17, 18, 19, 35, 60, 312, 316, 401, 600, 700, 1005) OR s.fk_typent = 8)
    +                    AND s.entity = %d
    +                    AND s.client = 1
    +                    AND s.fournisseur = 0
    +                    AND s.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_soc
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_soc IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Societe",
    +                "file" => DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php',
    +                'fields_anonym' => array(
    +                    'name' => $langs->trans('ANONYME'),
    +                    'name_bis' => '',
    +                    'name_alias' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_TIERS_PROSPECT' => array(
    +                'sql' => "
    +                    SELECT s.rowid FROM ".MAIN_DB_PREFIX."societe as s
    +                    WHERE (s.fk_forme_juridique IN (11, 12, 13, 15, 17, 18, 19, 35, 60, 312, 316, 401, 600, 700, 1005) OR s.fk_typent = 8)
    +                    AND s.entity = %d
    +                    AND s.client = 2
    +                    AND s.fournisseur = 0
    +                    AND s.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_soc
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_soc IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Societe",
    +                "file" => DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php',
    +                'fields_anonym' => array(
    +                    'name' => $langs->trans('ANONYME'),
    +                    'name_bis' => '',
    +                    'name_alias' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_TIERS_PROSPECT_CLIENT' => array(
    +                'sql' => "
    +                    SELECT s.rowid FROM ".MAIN_DB_PREFIX."societe as s
    +                    WHERE (s.fk_forme_juridique  IN (11, 12, 13, 15, 17, 18, 19, 35, 60, 312, 316, 401, 600, 700, 1005) OR s.fk_typent = 8)
    +                    AND s.entity = %d
    +                    AND s.client = 3
    +                    AND s.fournisseur = 0
    +                    AND s.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_soc
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_soc IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Societe",
    +                "file" => DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php',
    +                'fields_anonym' => array(
    +                    'name' => $langs->trans('ANONYME'),
    +                    'name_bis' => '',
    +                    'name_alias' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT' => array(
    +                'sql' => "
    +                    SELECT s.rowid FROM ".MAIN_DB_PREFIX."societe as s
    +                    WHERE (s.fk_forme_juridique  IN (11, 12, 13, 15, 17, 18, 19, 35, 60, 312, 316, 401, 600, 700, 1005) OR s.fk_typent = 8)
    +                    AND s.entity = %d
    +                    AND s.client = 0
    +                    AND s.fournisseur = 0
    +                    AND s.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_soc
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_soc IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Societe",
    +                "file" => DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php',
    +                'fields_anonym' => array(
    +                    'name' => $langs->trans('ANONYME'),
    +                    'name_bis' => '',
    +                    'name_alias' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_TIERS_FOURNISSEUR' => array(
    +                'sql' => "
    +                    SELECT s.rowid FROM ".MAIN_DB_PREFIX."societe as s
    +                    WHERE (s.fk_forme_juridique  IN (11, 12, 13, 15, 17, 18, 19, 35, 60, 312, 316, 401, 600, 700, 1005) OR s.fk_typent = 8)
    +                    AND s.entity = %d
    +                    AND s.fournisseur = 1
    +                    AND s.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_soc
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_contact IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Societe",
    +                "file" => DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php',
    +                'fields_anonym' => array(
    +                    'name' => $langs->trans('ANONYME'),
    +                    'name_bis' => '',
    +                    'name_alias' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_CONTACT_CLIENT' => array(
    +                'sql' => "
    +                    SELECT c.rowid FROM ".MAIN_DB_PREFIX."socpeople as c
    +                    INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc
    +                    WHERE c.entity = %d
    +                    AND c.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.client = 1
    +                    AND s.fournisseur = 0
    +                    AND c.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_contact
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_contact IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Contact",
    +                "file" => DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php',
    +                'fields_anonym' => array(
    +                    'lastname' => $langs->trans('ANONYME'),
    +                    'firstname' => '',
    +                    'civility_id' => '',
    +                    'poste' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone_pro' => '',
    +                    'phone_perso' => '',
    +                    'phone_mobile' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'jabberid' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_CONTACT_PROSPECT' => array(
    +                'sql' => "
    +                    SELECT c.rowid FROM ".MAIN_DB_PREFIX."socpeople as c
    +                    INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc
    +                    WHERE c.entity = %d
    +                    AND c.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.client = 2
    +                    AND s.fournisseur = 0
    +                    AND c.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_contact
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_contact IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Contact",
    +                "file" => DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php',
    +                'fields_anonym' => array(
    +                    'lastname' => $langs->trans('ANONYME'),
    +                    'firstname' => '',
    +                    'civility_id' => '',
    +                    'poste' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone_pro' => '',
    +                    'phone_perso' => '',
    +                    'phone_mobile' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'jabberid' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_CONTACT_PROSPECT_CLIENT' => array(
    +                'sql' => "
    +                    SELECT c.rowid FROM ".MAIN_DB_PREFIX."socpeople as c
    +                    INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc
    +                    WHERE c.entity = %d
    +                    AND c.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.client = 3
    +                    AND s.fournisseur = 0
    +                    AND c.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_contact
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_contact IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Contact",
    +                "file" => DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php',
    +                'fields_anonym' => array(
    +                    'lastname' => $langs->trans('ANONYME'),
    +                    'firstname' => '',
    +                    'civility_id' => '',
    +                    'poste' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone_pro' => '',
    +                    'phone_perso' => '',
    +                    'phone_mobile' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'jabberid' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT' => array(
    +                'sql' => "
    +                    SELECT c.rowid FROM ".MAIN_DB_PREFIX."socpeople as c
    +                    INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc
    +                    WHERE c.entity = %d
    +                    AND c.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.client = 0
    +                    AND s.fournisseur = 0
    +                    AND c.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_contact
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_contact IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Contact",
    +                "file" => DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php',
    +                'fields_anonym' => array(
    +                    'lastname' => $langs->trans('ANONYME'),
    +                    'firstname' => '',
    +                    'civility_id' => '',
    +                    'poste' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone_pro' => '',
    +                    'phone_perso' => '',
    +                    'phone_mobile' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'jabberid' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_CONTACT_FOURNISSEUR' => array(
    +                'sql' => "
    +                    SELECT c.rowid FROM ".MAIN_DB_PREFIX."socpeople as c
    +                    INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc
    +                    WHERE c.entity = %d
    +                    AND c.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND s.fournisseur = 1
    +                    AND c.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_contact
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.fk_contact IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Contact",
    +                "file" => DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php',
    +                'fields_anonym' => array(
    +                    'lastname' => $langs->trans('ANONYME'),
    +                    'firstname' => '',
    +                    'civility_id' => '',
    +                    'poste' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone_pro' => '',
    +                    'phone_perso' => '',
    +                    'phone_mobile' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'jabberid' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +            'DATAPOLICIES_ADHERENT' => array(
    +                'sql' => "
    +                    SELECT a.rowid FROM ".MAIN_DB_PREFIX."adherent as a
    +                    WHERE a.entity = %d
    +                    AND a.tms < DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                    AND a.rowid NOT IN (
    +                        SELECT DISTINCT a.fk_element
    +                        FROM ".MAIN_DB_PREFIX."actioncomm as a
    +                        WHERE a.tms > DATE_SUB(NOW(), INTERVAL %d MONTH)
    +                        AND a.elementtype LIKE 'member'
    +                        AND a.fk_element IS NOT NULL
    +                    )
    +                ",
    +                "class" => "Adherent",
    +                "file" => DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php',
    +                'fields_anonym' => array(
    +                    'lastname' => $langs->trans('ANONYME'),
    +                    'firstname' => $langs->trans('ANONYME'),
    +                    'civility_id' => '',
    +                    'societe' => '',
    +                    'address' => '',
    +                    'town' => '',
    +                    'zip' => '',
    +                    'phone' => '',
    +                    'phone_perso' => '',
    +                    'phone_mobile' => '',
    +                    'email' => '',
    +                    'url' => '',
    +                    'fax' => '',
    +                    'state' => '',
    +                    'country' => '',
    +                    'state_id' => '',
    +                    'skype' => '',
    +                    'country_id' => '',
    +                )
    +            ),
    +        );
    +
    +        foreach ($arrayofparameters as $key => $params) {
    +            if ($conf->global->$key != '' && is_numeric($conf->global->$key) && (int) $conf->global->$key > 0) {
    +
    +                $sql = sprintf($params['sql'], (int) $conf->entity, (int) $conf->global->$key, (int) $conf->global->$key);
    +
    +                $resql = $db->query($sql);
    +
    +                if ($resql && $db->num_rows($resql) > 0) {
    +
    +                    $num = $db->num_rows($resql);
    +                    $i = 0;
    +
    +                    require_once $params['file'];
    +                    $object = new $params['class']($db);
    +
    +                    while ($i < $num)
    +                    {
    +                        $obj = $db->fetch_object($resql);
    +
    +                        $object->fetch($obj->rowid);
    +                        $object->id = $obj->rowid;
    +
    +                        if ($object->isObjectUsed($obj->rowid) > 0) {
    +                            foreach ($params['fields_anonym'] as $fields => $val) {
    +                                $object->$fields = $val;
    +                            }
    +                            $object->update($obj->rowid, $user);
    +                            if ($params['class'] == 'Societe') {
    +                                // On supprime les contacts associé
    +                                $sql = "DELETE FROM ".MAIN_DB_PREFIX."socpeople WHERE fk_soc = " . $obj->rowid;
    +                                $db->query($sql);
    +                            }
    +                        } else {
    +                            if (DOL_VERSION < 8) {
    +                                $ret = $object->delete($obj->rowid, $user);
    +                            } else {
    +                                if ($object->element == 'adherent') {
    +                                    $ret = $object->delete($obj->rowid);
    +                                } else {
    +                                    $ret = $object->delete();
    +                                }
    +                            }
    +                        }
    +
    +                        $i++;
    +                    }
    +                }
    +            }
    +        }
    +        return true;
    +    }
    +
    +
    +    /**
    +     * sendMailing
    +     *
    +     * @return boolean
    +     */
    +    public function sendMailing()
    +    {
    +        global $conf, $db, $langs, $user;
    +
    +        $langs->load('datapolicy@datapolicy');
    +
    +        require_once DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +
    +        $contacts = new DataPolicy($db);
    +        $contacts->getAllContactNotInformed();
    +        $contacts->getAllCompaniesNotInformed();
    +        $contacts->getAllAdherentsNotInformed();
    +        return true;
    +    }
    +}
    \ No newline at end of file
    diff --git a/htdocs/datapolicy/img/datapolicy.png b/htdocs/datapolicy/img/datapolicy.png
    new file mode 100644
    index 00000000000..2681ccc1d3a
    Binary files /dev/null and b/htdocs/datapolicy/img/datapolicy.png differ
    diff --git a/htdocs/datapolicy/img/gfdl.png b/htdocs/datapolicy/img/gfdl.png
    new file mode 100644
    index 00000000000..f2bacfd179a
    Binary files /dev/null and b/htdocs/datapolicy/img/gfdl.png differ
    diff --git a/htdocs/datapolicy/img/gplv3.png b/htdocs/datapolicy/img/gplv3.png
    new file mode 100644
    index 00000000000..ba78d4c4941
    Binary files /dev/null and b/htdocs/datapolicy/img/gplv3.png differ
    diff --git a/htdocs/datapolicy/img/object_datapolicy.png b/htdocs/datapolicy/img/object_datapolicy.png
    new file mode 100644
    index 00000000000..5d65c309cca
    Binary files /dev/null and b/htdocs/datapolicy/img/object_datapolicy.png differ
    diff --git a/htdocs/datapolicy/img/object_inoveaconseil.png b/htdocs/datapolicy/img/object_inoveaconseil.png
    new file mode 100644
    index 00000000000..292a9c75ef2
    Binary files /dev/null and b/htdocs/datapolicy/img/object_inoveaconseil.png differ
    diff --git a/htdocs/datapolicy/langs/en_US/datapolicy.lang b/htdocs/datapolicy/langs/en_US/datapolicy.lang
    new file mode 100644
    index 00000000000..ddcd2180cb0
    --- /dev/null
    +++ b/htdocs/datapolicy/langs/en_US/datapolicy.lang
    @@ -0,0 +1,92 @@
    +# Copyright (C) 2018 Nicolas ZABOURI    <info@inovea-conseil.com>
    +#
    +# 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 <http://www.gnu.org/licenses/>.
    +
    +# Module label 'ModuledatapolicyName'
    +Module4100Name = Data Privacy Policy
    +# Module description 'ModuledatapolicyDesc'
    +Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR)
    +
    +#
    +# Page d'administration
    +#
    +datapolicySetup = Module Data Privacy Policy Setup
    +Deletion = Deletion of data
    +datapolicySetupPage = Depending of laws of your countries (Example <a href="http://www.privacy-regulation.eu/en/5.htm" target="_blank">Article 5</a> of the GDPR), personal data must be kept for a period not exceeding that necessary for the purposes for which they were collected, except for archival purposes.<br>The deletion will be done automatically after a certain duration without event (the duration which you will have indicated below).
    +NB_MONTHS = %s months
    +ONE_YEAR = 1 year
    +NB_YEARS = %s years
    +DATAPOLICY_TIERS_CLIENT = Customer
    +DATAPOLICY_TIERS_PROSPECT = Prospect
    +DATAPOLICY_TIERS_PROSPECT_CLIENT = Prospect/Customer
    +DATAPOLICY_TIERS_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
    +DATAPOLICY_TIERS_FOURNISSEUR = Supplier
    +DATAPOLICY_CONTACT_CLIENT = Customer
    +DATAPOLICY_CONTACT_PROSPECT = Prospect
    +DATAPOLICY_CONTACT_PROSPECT_CLIENT = Prospect/Customer
    +DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
    +DATAPOLICY_CONTACT_FOURNISSEUR = Supplier
    +DATAPOLICY_ADHERENT = Member
    +DATAPOLICY_Tooltip_SETUP = Type of contact - Indicate your choices for each type.
    +DATAPOLICYMail=Emails Setup
    +DATAPOLICYSUBJECTMAIL=Subject of email
    +DATAPOLICYCONTENTMAIL=Content of the email
    +DATAPOLICYSUBSITUTION=You can use the following variables in your email (LINKACCEPT allows to create a link recording the agreement of the person, LINKREFUSED makes it possible to record the refusal of the person):
    +DATAPOLICYACCEPT=Message after agreement
    +DATAPOLICYREFUSE=Message after desagreement
    +SendAgreementText=You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button.
    +SendAgreement=Send emails
    +AllAgreementSend = All emails have been sent
    +TXTLINKDATAPOLICYACCEPT= Text for the link "agreement" 
    +TXTLINKDATAPOLICYREFUSE= Text for the link "desagreement" 
    +
    +
    +#
    +# Extrafield
    +#
    +DATAPOLICY_BLOCKCHECKBOX = GDPR : Processing of personal data
    +DATAPOLICY_consentement = Consent obtained for the processing of personal data 
    +DATAPOLICY_opposition_traitement = Opposes the processing of his personal data
    +DATAPOLICY_opposition_prospection = Opposes the processing of his personal data for the purposes of prospecting
    +
    +#
    +# Popup
    +#
    +DATAPOLICY_POPUP_ANONYME_TITLE = Anonymize a thirdparty
    +DATAPOLICY_POPUP_ANONYME_TEXTE = You can not delete this contact from Dolibarr because there are related items. In accordance with the GDPR, you will make all this data anonymous to respect your obligations. Would you like to continue ?
    +
    +#
    +# Bouton portabilité
    +# 
    +DATAPOLICY_PORTABILITE = Portability GDPR
    +DATAPOLICY_PORTABILITE_TITLE = Export of personal data
    +DATAPOLICY_PORTABILITE_CONFIRMATION = You want to export the personal data of this contact. Are you sure ?
    +
    +#
    +# Note ajoutés lors d'une anonymisation
    +#
    +ANONYMISER_AT = Anonymised the %s
    +
    +#V2
    +DATAPOLICYReturn=GDPR Validation
    +DATAPOLICY_date = Date of agreement/desagreement GDPR
    +DATAPOLICY_send = Date sending agreement email
    +DATAPOLICYReturn = GDPR Return
    +DATAPOLICY_SEND = Send GDPR email
    +MailSent = Email has been sent
    +
    +#ERROR
    +ErrorSubjectIsRequired= Error : The subject of email is required. Indicate it in the module setup
    +=Due to a technical problem, we were unable to register your choice. We apologize for that. Contact us to send us your choice.
    +NUMBER_MONTH_BEFORE_DELETION = Number of month before deletion
    diff --git a/htdocs/datapolicy/langs/fr_FR/datapolicy.lang b/htdocs/datapolicy/langs/fr_FR/datapolicy.lang
    new file mode 100644
    index 00000000000..7ee710aae2e
    --- /dev/null
    +++ b/htdocs/datapolicy/langs/fr_FR/datapolicy.lang
    @@ -0,0 +1,97 @@
    +# Copyright (C) 2018  INOVEA CONSEil info@inovea-conseil.com
    +#
    +# 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 <http://www.gnu.org/licenses/>.
    +
    +#
    +# Générique
    +#
    +
    +# Module label 'ModuledatapolicyName'
    +Module4100Name = Protection des Données
    +# Module description 'ModuledatapolicyDesc'
    +Module4100Desc = Module de gestion de la protection des données (RGPD)
    +
    +#
    +# Page d'administration
    +#
    +datapolicySetup = Configuration du module Protection des données
    +Settings_DATAPOLICY = Paramétrage du module Protection des données
    +datapolicySetupPage = Selon la loi de votre pays (Exemple <a href="http://www.privacy-regulation.eu/fr/5.htm" target="_blank">l’article 5</a> du RGPD), les données à caractère personnel doivent être conservées pendant une durée n’excédant pas celle nécessaire au regard des finalités pour lesquelles elles ont été traitées, à l’exception de fins archivistiques. La suppression se fera automatiquement après une certaine durée sans évènement (la durée que vous aurez indiquée ci-dessous).
    +NB_MONTHS = %s mois
    +ONE_YEAR = 1 an
    +NB_YEARS = %s ans
    +DATAPOLICY_TIERS_CLIENT = Client
    +DATAPOLICY_TIERS_PROSPECT = Prospect
    +DATAPOLICY_TIERS_PROSPECT_CLIENT = Prospect/Client
    +DATAPOLICY_TIERS_NIPROSPECT_NICLIENT = Ni prospect / Ni client
    +DATAPOLICY_TIERS_FOURNISSEUR = Fournisseur
    +DATAPOLICY_CONTACT_CLIENT = Client
    +DATAPOLICY_CONTACT_PROSPECT = Prospect
    +DATAPOLICY_CONTACT_PROSPECT_CLIENT = Prospect/Client
    +DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Ni prospect / Ni client
    +DATAPOLICY_CONTACT_FOURNISSEUR = Fournisseur
    +DATAPOLICY_ADHERENT = Adhérent
    +DATAPOLICY_Tooltip_SETUP = Type du contact - Indiquez vos choix pour chaque type.
    +DATAPOLICYMail=Paramétrage des emails
    +DATAPOLICYSUBJECTMAIL=Objet du mail
    +DATAPOLICYCONTENTMAIL=Contenu du mail
    +DATAPOLICYSUBSITUTION=Vous pouvez utiliser les variables suivantes dans votre email (LINKACCEPT permet de créer un lien enregistrant l'acceptation de la personne, LINKREFUSED permet d'enregistrer le refus de la personne) :
    +DATAPOLICYACCEPT=Message suite acceptation
    +DATAPOLICYREFUSE=Message suite opposition
    +SendAgreementText=Vous pouvez envoyer un email DATAPOLICY à tous vos contacts concernés (qui n'ont pas encore reçus de mail et pour lesquels vous n'avez rien enregistré concernant leur accord/désaccord DATAPOLICY). Pour cela, utilisez le bouton suivant.
    +SendAgreement=Envoyer les emails
    +AllAgreementSend = Tous les e-mails de consentement ont été envoyés
    +TXTLINKDATAPOLICYACCEPT= Texte du lien d'acceptation
    +TXTLINKDATAPOLICYREFUSE= Texte du lien d'opposition
    +
    +
    +
    +#
    +# Extrafield
    +#
    +DATAPOLICY_BLOCKCHECKBOX = DATAPOLICY : Traitement des données à caractère personnel
    +DATAPOLICY_consentement = Consentement recueilli pour le traitement des données à caractère personnel le concernant
    +DATAPOLICY_opposition_traitement = S’oppose au traitement de ses données à caractère personnel
    +DATAPOLICY_opposition_prospection = S’oppose au traitement de ses données à caractère personnel à des fins de prospection
    +
    +#
    +# Popup
    +#
    +DATAPOLICY_POPUP_ANONYME_TITLE = Anonymiser un tiers
    +DATAPOLICY_POPUP_ANONYME_TEXTE = Vous ne pouvez pas supprimer ce contact de Dolibarr car des éléments y sont liés. Conformément au DATAPOLICY, vous allez rendre toutes ces données anonymes afin de respecter vos obligations. Souhaitez-vous continuer ?
    +
    +#
    +# Bouton portabilité
    +# 
    +DATAPOLICY_PORTABILITE = Portabilité DATAPOLICY
    +DATAPOLICY_PORTABILITE_TITLE = Export des données à caractère personnel
    +DATAPOLICY_PORTABILITE_CONFIRMATION = Vous souhaitez exporter les données à caractère personnel de ce contact. Etes-vous sûr ?
    +
    +#
    +# Note ajoutés lors d'une anonymisation
    +#
    +ANONYMISER_AT = Anonymisé le %s
    +
    +#V2
    +DATAPOLICYReturn=Validation DATAPOLICY
    +DATAPOLICY_date=Date d'accord/opposition au traitement
    +DATAPOLICY_send=Date envoi consentement
    +DATAPOLICYReturn=Retour DATAPOLICY
    +DATAPOLICY_SEND=Envoyer l'email de consentement
    +MailSent=L'email a bien été envoyé
    +
    +#ERROR
    +ErrorSubjectIsRequired=Erreur : vous n'avez pas indiqué l'objet de l'email dans la configuration
    +=Suite à un problème technique, nous n'avons pas pu enregistrer votre choix. Nous nous en excusons. Contactez-nous pour nous transmettre votre choix.
    +NUMBER_MONTH_BEFORE_DELETION = Nombre de mois avant suppression des données
    diff --git a/htdocs/datapolicy/langs/it_IT/datapolicy.lang b/htdocs/datapolicy/langs/it_IT/datapolicy.lang
    new file mode 100644
    index 00000000000..d8858b56c5b
    --- /dev/null
    +++ b/htdocs/datapolicy/langs/it_IT/datapolicy.lang
    @@ -0,0 +1,78 @@
    +# Copyright (C) 2018 INOVEA CONSEIl info@inovea-conseil.com - Thanks to Claudio Aschieri
    +#
    +# # Module label 'ModuledatapolicyName'
    +Module4100Name = Data Policy
    +# Module description 'ModuledatapolicyDesc'
    +Module4100Desc = Conformità con GDPR
    +
    +#
    +# Page d'administration
    +#
    +datapolicySetup = Module Setup
    +Settings_DATAPOLICY = Configurazione modulo GDPR 
    +datapolicySetupPage = In accordo con <a href="http://www.privacy-regulation.eu/it/5.htm" target="_blank">l'art 5 del GDPR </a> i dati personali devono essere conservati per un periodo di tempo che .... ed eliminati se non sono più utili agli scopi per cui sono stati processati.
    +NB_MONTHS = %s mesi
    +ONE_YEAR = 1 anno
    +NB_YEARS = %s anni
    +DATAPOLICY_TIERS_CLIENT = Cliente
    +DATAPOLICY_TIERS_PROSPECT = Fornitore
    +DATAPOLICY_TIERS_PROSPECT_CLIENT = Potenziale Cliente / Cliente
    +DATAPOLICY_TIERS_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
    +DATAPOLICY_TIERS_FOURNISSEUR = Fornitore
    +DATAPOLICY_CONTACT_CLIENT = Cliente
    +DATAPOLICY_CONTACT_PROSPECT = Potenziale cliente
    +DATAPOLICY_CONTACT_PROSPECT_CLIENT = Potenziale Cliente / Cliente
    +DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
    +DATAPOLICY_CONTACT_FOURNISSEUR = Fornitore
    +DATAPOLICY_ADHERENT = Membri
    +DATAPOLICY_Tooltip_SETUP = Tipo di contatto - Indica la scelta per ogni tipologia
    +DATAPOLICYMail=Configurazione Email
    +DATAPOLICYSUBJECTMAIL=Subject dell'e-mail
    +DATAPOLICYCONTENTMAIL=Contenuto dell'e-mail
    +DATAPOLICYSUBSITUTION=Puoi utilizzare le seguenti variabili nella tua email (LINKACCEPT consente di creare un link per registrare l'accettazione della persona, LINKREFUSED consente di registrare il rifiuto della persona):
    +DATAPOLICYACCEPT= Messaggio dopo il consenso
    +DATAPOLICYREFUSE=Messaggio dopo il rifiuto
    +SendAgreementText=Puoi inviare un'email GDPR a tutti i tuoi contatti rilevanti (che non hanno ancora ricevuto un'e-mail e per i quali non hai registrato nulla sul loro accordo GDPR). Per fare ciò, utilizzare il seguente pulsante.
    +SendAgreement=Invia emails
    +AllAgreementSend = Tutte le email sono state inviate
    +TXTLINKDATAPOLICYACCEPT= Testo per il link "Consenso" 
    +TXTLINKDATAPOLICYREFUSE= Testo per il link "Consenso negato" 
    +
    +#
    +# Extrafield
    +#
    +DATAPOLICY_BLOCKCHECKBOX = GDPR : Trattamento dei dati personali
    +DATAPOLICY_consentement = Consenso ottenuto al Trattamento dei dati personali
    +DATAPOLICY_opposition_traitement = Consenso negato al trattamento dei dati personali
    +DATAPOLICY_opposition_prospection = Consenso negato al trattamento dei dati personali a fini commerciali
    +
    +#
    +# Popup
    +#
    +DATAPOLICY_POPUP_ANONYME_TITLE = Anonimizza un soggetto terzo
    +DATAPOLICY_POPUP_ANONYME_TEXTE = Impossibile eliminare questo contatto da Dolibarr perchè vi sono elementi collegati. In conformità con il GDPR, renderai tutti questi dati anonimi per rispettare i tuoi obblighi. Vuoi continuare?
    +
    +
    +#
    +# Bouton portabilité
    +# 
    +DATAPOLICY_PORTABILITE = Portabilità GDPR
    +DATAPOLICY_PORTABILITE_TITLE = Esporta i dati personali
    +DATAPOLICY_PORTABILITE_CONFIRMATION = Vuoi davvero esportare i dati personali di questo contatto?
    +
    +#
    +# Note ajoutée lors d'une anonymisation
    +#
    +ANONYMISER_AT = Anonimizzato il %s
    +
    +#V2
    +DATAPOLICYReturn=GDPR Validazione
    +DATAPOLICY_date = Data di accordo / disaccordo GDPR
    +DATAPOLICY_send = Data di invio del consenso (e-mail)
    +DATAPOLICYReturn = GDPR ritorno
    +DATAPOLICY_SEND = Inviare GDPR e-mail
    +MailSent=L'email è stata inviata
    +
    +#ERROR
    +ErrorSubjectIsRequired= Errore: L'oggetto della mail è obbligatorio. Inserisci l'oggetto nella configurazione del modulo.
    +=A causa di un problema tecnico, non siamo stati in grado di registrare la tua scelta. Ci scusiamo per questo. Contattaci per inviarci la tua scelta.
    diff --git a/htdocs/datapolicy/lib/datapolicy.lib.php b/htdocs/datapolicy/lib/datapolicy.lib.php
    new file mode 100644
    index 00000000000..41c92299989
    --- /dev/null
    +++ b/htdocs/datapolicy/lib/datapolicy.lib.php
    @@ -0,0 +1,54 @@
    +<?php
    +/* Copyright (C) 2018 Nicolas ZABOURI   <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/lib/datapolicy.lib.php
    + * \ingroup datapolicy
    + * \brief   Library files with common functions for datapolicy
    + */
    +
    +/**
    + * Prepare admin pages header
    + *
    + * @return array
    + */
    +function datapolicyAdminPrepareHead()
    +{
    +	global $langs, $conf;
    +
    +	$langs->load("datapolicy@datapolicy");
    +
    +	$h = 0;
    +	$head = array();
    +
    +	$head[$h][0] = dol_buildpath("/datapolicy/admin/setup.php", 1);
    +	$head[$h][1] = $langs->trans("Deletion");
    +	$head[$h][2] = 'settings';
    +	$h++;
    +
    +	if (! empty($conf->global->DATAPOLICIES_ENABLE_EMAILS))
    +	{
    +		$head[$h][0] = dol_buildpath("/datapolicy/admin/setupmail.php", 1);
    +		$head[$h][1] = $langs->trans("DATAPOLICIESMail");
    +		$head[$h][2] = 'settings';
    +		$h++;
    +	}
    +
    +	complete_head_from_modules($conf, $langs, $object, $head, $h, 'datapolicy');
    +
    +	return $head;
    +}
    diff --git a/htdocs/datapolicy/mailing.php b/htdocs/datapolicy/mailing.php
    new file mode 100644
    index 00000000000..e3f38b269be
    --- /dev/null
    +++ b/htdocs/datapolicy/mailing.php
    @@ -0,0 +1,41 @@
    +<?php
    +/* Copyright (C) 2018      Nicolas ZABOURI      <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/mailing.php
    + * \ingroup datapolicy
    + * \brief   datapolicy mailing page.
    + */
    +
    +require '../../main.inc.php';
    +dol_include_once('/contact/class/contact.class.php');
    +dol_include_once('/datapolicy/class/datapolicy.class.php');
    +
    +$idcontact = GETPOST('idc');
    +
    +if(!empty($idcontact)){
    +    $contact = new Contact($db);
    +    $contact->fetch($idcontact);
    +    DataPolicy::sendMailDataPolicyContact($contact);
    +}else{
    +
    +    $contacts = new DataPolicy($db);
    +    $contacts->getAllContactNotInformed();
    +    $contacts->getAllCompaniesNotInformed();
    +    $contacts->getAllAdherentsNotInformed();
    +    echo $langs->trans('AllAgreementSend');
    +}
    diff --git a/htdocs/datapolicy/modulebuilder.txt b/htdocs/datapolicy/modulebuilder.txt
    new file mode 100644
    index 00000000000..24ea0d6eac5
    --- /dev/null
    +++ b/htdocs/datapolicy/modulebuilder.txt
    @@ -0,0 +1,3 @@
    +# DO NOT DELETE THIS FILE MANUALLY
    +# File to flag module built using official module template.
    +# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module. 
    \ No newline at end of file
    diff --git a/htdocs/datapolicy/public/index.php b/htdocs/datapolicy/public/index.php
    new file mode 100644
    index 00000000000..58f7968f05d
    --- /dev/null
    +++ b/htdocs/datapolicy/public/index.php
    @@ -0,0 +1,144 @@
    +<?php
    +
    +/* Copyright (C) 2018      Nicolas ZABOURI      <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    datapolicy/admin/setup.php
    + * \ingroup datapolicy
    + * \brief   datapolicy setup page.
    + */
    +
    +if (!defined('NOLOGIN'))
    +    define("NOLOGIN", 1);   // This means this output page does not require to be logged.
    +if (!defined('NOCSRFCHECK'))
    +    define('NOCSRFCHECK', '1');  // Do not check anti CSRF attack test
    +if (!defined('NOREQUIREMENU'))
    +    define('NOREQUIREMENU', '1');
    +
    +require '../../main.inc.php';
    +dol_include_once('/contact/class/contact.class.php');
    +dol_include_once('/societe/class/societe.class.php');
    +dol_include_once('/adherents/class/adherent.class.php');
    +dol_include_once('/user/class/user.class.php');
    +dol_include_once('/datapolicy/class/datapolicy.class.php');
    +
    +$idc = GETPOST('c', 'int');
    +$ids = GETPOST('s', 'int');
    +$ida = GETPOST('a', 'int');
    +$action = GETPOST('action', 'alpha');
    +$lang = GETPOST('l', 'alpha');
    +$code = GETPOST('key', 'alpha');
    +
    +$acc = "DATAPOLICIESACCEPT_" . $lang;
    +$ref = "DATAPOLICIESREFUSE_" . $lang;
    +$langs->load('datapolicy@datapolicy',0,0,$lang);
    +
    +if (empty($action) || (empty($idc) && empty($ids) && empty($ida))) {
    +    return 0;
    +} elseif (!empty($idc)) {
    +    $contact = new Contact($db);
    +    $contact->fetch($idc);
    +    $check = md5($contact->email);
    +    if ($check != $code) {
    +        $return = $langs->trans('ErrorEmailDATAPOLICIES');
    +    } elseif ($action == 1) {
    +        $contact->array_options['options_datapolicy_consentement'] = 1;
    +        $contact->array_options['options_datapolicy_opposition_traitement'] = 0;
    +        $contact->array_options['options_datapolicy_opposition_prospection'] = 0;
    +        $contact->array_options['options_datapolicy_date'] = date('Y-m-d', time());
    +
    +        $return = $conf->global->$acc;
    +    } elseif ($action == 2) {
    +        $contact->no_email = 1;
    +        $contact->array_options['options_datapolicy_consentement'] = 0;
    +        $contact->array_options['options_datapolicy_opposition_traitement'] = 1;
    +        $contact->array_options['options_datapolicy_opposition_prospection'] = 1;
    +        $contact->array_options['options_datapolicy_date'] = date('Y-m-d', time());
    +
    +        $return = $conf->global->$ref;
    +    }
    +    $contact->update($idc);
    +} elseif (!empty($ids)) {
    +    $societe = new Societe($db);
    +    $societe->fetch($ids);
    +    $check = md5($societe->email);
    +    if ($check != $code) {
    +        $return = $langs->trans('ErrorEmailDATAPOLICIES');
    +    } elseif ($action == 1) {
    +        $societe->array_options['options_datapolicy_consentement'] = 1;
    +        $societe->array_options['options_datapolicy_opposition_traitement'] = 0;
    +        $societe->array_options['options_datapolicy_opposition_prospection'] = 0;
    +        $societe->array_options['options_datapolicy_date'] = date('Y-m-d', time());
    +        $return = $conf->global->$acc;
    +    } elseif ($action == 2) {
    +        $societe->array_options['options_datapolicy_consentement'] = 0;
    +        $societe->array_options['options_datapolicy_opposition_traitement'] = 1;
    +        $societe->array_options['options_datapolicy_opposition_prospection'] = 1;
    +        $societe->array_options['options_datapolicy_date'] = date('Y-m-d', time());
    +
    +        $return = $conf->global->$ref;
    +    }
    +    $societe->update($ids);
    +} elseif (!empty($ida)) {
    +    $adherent = new Adherent($db);
    +    $adherent->fetch($ida);
    +    $check = md5($adherent->email);
    +    if ($check != $code) {
    +        $return = $langs->trans('ErrorEmailDATAPOLICIES');
    +    } elseif ($action == 1) {
    +        $adherent->array_options['options_datapolicy_consentement'] = 1;
    +        $adherent->array_options['options_datapolicy_opposition_traitement'] = 0;
    +        $adherent->array_options['options_datapolicy_opposition_prospection'] = 0;
    +        //$adherent->array_options['options_datapolicy_date'] = date('Y-m-d', time());
    +        $return = $conf->global->$acc;
    +    } elseif ($action == 2) {
    +        $adherent->array_options['options_datapolicy_consentement'] = 0;
    +        $adherent->array_options['options_datapolicy_opposition_traitement'] = 1;
    +        $adherent->array_options['options_datapolicy_opposition_prospection'] = 1;
    +        //$adherent->array_options['options_datapolicy_date'] = date('Y-m-d', time());
    +
    +        $return = $conf->global->$ref;
    +    }
    +    $newuser = new User($db);
    +    $adherent->update($newuser);
    +}
    +
    +header("Content-type: text/html; charset=" . $conf->file->character_set_client);
    +
    +print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
    +print "\n";
    +print "<html>\n";
    +print "<head>\n";
    +print '<meta name="robots" content="noindex,nofollow">' . "\n";
    +print '<meta name="keywords" content="dolibarr">' . "\n";
    +print '<meta name="description" content="Dolibarr DATAPOLICIES">' . "\n";
    +print "<title>" . $langs->trans("DATAPOLICIESReturn") . "</title>\n";
    +print '<link rel="stylesheet" type="text/css" href="' . DOL_URL_ROOT . $conf->css . '?lang=' . $lang . '">' . "\n";
    +print '<style type="text/css">';
    +print '.CTableRow1      { margin: 1px; padding: 3px; font: 12px verdana,arial; background: #e6E6eE; color: #000000; -moz-border-radius-topleft:6px; -moz-border-radius-topright:6px; -moz-border-radius-bottomleft:6px; -moz-border-radius-bottomright:6px;}';
    +print '.CTableRow2      { margin: 1px; padding: 3px; font: 12px verdana,arial; background: #FFFFFF; color: #000000; -moz-border-radius-topleft:6px; -moz-border-radius-topright:6px; -moz-border-radius-bottomleft:6px; -moz-border-radius-bottomright:6px;}';
    +print '</style>';
    +
    +print "</head>\n";
    +print '<body style="margin: 10% 40%">' . "\n";
    +print '<table class="CTableRow1" ><tr><td style="text_align:center;">';
    +print $return . "<br>\n";
    +print '</td></tr></table>';
    +print "</body>\n";
    +print "</html>\n";
    +
    +$db->close();
    diff --git a/htdocs/dav/dav.class.php b/htdocs/dav/dav.class.php
    index 9e5121112d0..b8c38773538 100644
    --- a/htdocs/dav/dav.class.php
    +++ b/htdocs/dav/dav.class.php
    @@ -34,11 +34,18 @@ class CdavLib
     
     	private $langs;
     
    +    /**
    +     * Constructor
    +     *
    +     * @param   User        $user   user
    +     * @param   DoliDB      $db     Database handler
    +     * @param   Translate   $langs  translation
    +     */
     	function __construct($user, $db, $langs)
     	{
    -		$this->user 	= $user;
    -		$this->db 		= $db;
    -		$this->langs 	= $langs;
    +		$this->user = $user;
    +		$this->db = $db;
    +		$this->langs = $langs;
     	}
     
     	/**
    @@ -106,7 +113,6 @@ class CdavLib
     		}
     
     		return $sql;
    -
     	}
     
     	/**
    @@ -295,5 +301,4 @@ class CdavLib
     		}
     		return $calevents;
     	}
    -
     }
    diff --git a/htdocs/dav/fileserver.php b/htdocs/dav/fileserver.php
    index a1d145306f5..bfdc81887ff 100644
    --- a/htdocs/dav/fileserver.php
    +++ b/htdocs/dav/fileserver.php
    @@ -28,7 +28,7 @@ if (! defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX','1');
     if (! defined('NOLOGIN'))  		 define("NOLOGIN",1);		// This means this output page does not require to be logged.
     if (! defined('NOCSRFCHECK'))  	 define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
     require_once DOL_DOCUMENT_ROOT.'/dav/dav.class.php';
    @@ -58,8 +58,7 @@ $tmpDir = $conf->dav->dir_temp;
     //var_dump($tmpDir);exit;
     
     // Authentication callback function
    -$authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function ($username, $password)
    -{
    +$authBackend = new \Sabre\DAV\Auth\Backend\BasicCallBack(function ($username, $password) {
     	global $user;
     	global $conf;
     	global $dolibarr_main_authentication;
    diff --git a/htdocs/document.php b/htdocs/document.php
    index 725d079a9f6..735910f47eb 100644
    --- a/htdocs/document.php
    +++ b/htdocs/document.php
    @@ -37,13 +37,6 @@ if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
     if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
     if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
     
    -// For bittorent link, we don't need to load/check we are into a login session
    -if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'bittorrent')
    -{
    -	if (! defined("NOLOGIN"))		define("NOLOGIN",1);
    -	if (! defined("NOCSRFCHECK"))	define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
    -	if (! defined("NOIPCHECK"))		define("NOIPCHECK",1);		// Do not check IP defined into conf $dolibarr_main_restrict_ip
    -}
     // For direct external download link, we don't need to load/check we are into a login session
     if (isset($_GET["hashp"]))
     {
    @@ -64,13 +57,17 @@ if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias'))
      *
      * @return	void
      */
    -function llxHeader() { }
    +function llxHeader()
    +{
    +}
     /**
      * Footer empty
      *
      * @return	void
      */
    -function llxFooter() { }
    +function llxFooter()
    +{
    +}
     
     require 'main.inc.php';	// Load $user and permissions
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    diff --git a/htdocs/don/card.php b/htdocs/don/card.php
    index 5a9e439a9c7..38465de95ca 100644
    --- a/htdocs/don/card.php
    +++ b/htdocs/don/card.php
    @@ -1,9 +1,11 @@
     <?php
    -/* Copyright (C) 2001-2002	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2017	Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013       Florian Henry		  	<florian.henry@open-concept.pro>
    - * Copyright (C) 2015-2016  Alexandre Spangaro	  	<aspangaro.dolibarr@gmail.com>
    +/* Copyright (C) 2001-2002  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2015-2016  Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Thibault FOUCART        <support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -26,23 +28,23 @@
      */
     
     require '../main.inc.php';
    -require_once DOL_DOCUMENT_ROOT.'/core/modules/dons/modules_don.php';
    -require_once DOL_DOCUMENT_ROOT.'/core/lib/donation.lib.php';
    -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
    -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
    -require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
    -require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
    -require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
    -if (! empty($conf->projet->enabled))
    -{
    -	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
    -	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/modules/dons/modules_don.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/donation.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/don/class/don.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmargin.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
    +if (! empty($conf->projet->enabled)) {
    +    require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
    +    require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     }
     require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
     
    -$langs->load("companies");
    -$langs->load("donations");
    -$langs->load("bills");
    +$langs->loadLangs(array("bills", "companies", "donations"));
     
     $id=GETPOST('rowid')?GETPOST('rowid','int'):GETPOST('id','int');
     $action=GETPOST('action','alpha');
    @@ -326,38 +328,91 @@ if ($action == 'create')
     	print '<table class="border" width="100%">';
     	print '<tbody>';
     
    -    // Date
    +	// Ref
    +	print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans('Ref') . '</td><td colspan="2">' . $langs->trans('Draft') . '</td></tr>';
    +
    +	// Company
    +	if (! empty($conf->societe->enabled) && ! empty($conf->global->DONATION_USE_THIRDPARTIES))
    +	{
    +		// Thirdparty
    +		print '<td>' . $langs->trans('Customer') . '</td>';
    +		if ($soc->id > 0 && ! GETPOST('fac_rec','alpha'))
    +		{
    +			print '<td colspan="2">';
    +			print $soc->getNomUrl(1);
    +			print '<input type="hidden" name="socid" value="' . $soc->id . '">';
    +			// Outstanding Bill
    +			$outstandingBills = $soc->get_OutstandingBill();
    +			print ' (' . $langs->trans('CurrentOutstandingBill') . ': ';
    +			print price($outstandingBills, '', $langs, 0, 0, -1, $conf->currency);
    +			if ($soc->outstanding_limit != '')
    +			{
    +				if ($outstandingBills > $soc->outstanding_limit) print img_warning($langs->trans("OutstandingBillReached"));
    +				print ' / ' . price($soc->outstanding_limit, '', $langs, 0, 0, -1, $conf->currency);
    +			}
    +			print ')';
    +			print '</td>';
    +		}
    +		else
    +		{
    +			print '<td colspan="2">';
    +			print $form->select_company($soc->id, 'socid', '(s.client = 1 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
    +			// Option to reload page to retrieve customer informations. Note, this clear other input
    +			if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
    +			{
    +				print '<script type="text/javascript">
    +				$(document).ready(function() {
    +					$("#socid").change(function() {
    +						var socid = $(this).val();
    +				        var fac_rec = $(\'#fac_rec\').val();
    +						// reload page
    +						window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&fac_rec="+fac_rec;
    +					});
    +				});
    +				</script>';
    +			}
    +			print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'.$langs->trans("AddThirdParty").'</a>';
    +			print '</td>';
    +		}
    +		print '</tr>' . "\n";
    +	}
    +
    +	// Date
     	print '<tr><td class="fieldrequired titlefieldcreate">'.$langs->trans("Date").'</td><td>';
    -	$form->select_date($donation_date?$donation_date:-1,'','','','',"add",1,1);
    +	print $form->selectDate($donation_date?$donation_date:-1, '', '', '', '', "add", 1, 1);
     	print '</td>';
     
    -    // Amount
    -    print "<tr>".'<td class="fieldrequired">'.$langs->trans("Amount").'</td><td><input type="text" name="amount" value="'.dol_escape_htmltag(GETPOST("amount")).'" size="10"> '.$langs->trans("Currency".$conf->currency).'</td></tr>';
    +	// Amount
    +	print "<tr>".'<td class="fieldrequired">'.$langs->trans("Amount").'</td><td><input type="text" name="amount" value="'.dol_escape_htmltag(GETPOST("amount")).'" size="10"> '.$langs->trans("Currency".$conf->currency).'</td></tr>';
     
    +	// Public donation
     	print '<tr><td class="fieldrequired">'.$langs->trans("PublicDonation")."</td><td>";
     	print $form->selectyesno("public",isset($_POST["public"])?$_POST["public"]:1,1);
     	print "</td></tr>\n";
     
    -	print "<tr>".'<td>'.$langs->trans("Company").'</td><td><input type="text" name="societe" value="'.dol_escape_htmltag(GETPOST("societe")).'" class="maxwidth200"></td></tr>';
    -	print "<tr>".'<td>'.$langs->trans("Lastname").'</td><td><input type="text" name="lastname" value="'.dol_escape_htmltag(GETPOST("lastname")).'" class="maxwidth200"></td></tr>';
    -	print "<tr>".'<td>'.$langs->trans("Firstname").'</td><td><input type="text" name="firstname" value="'.dol_escape_htmltag(GETPOST("firstname")).'" class="maxwidth200"></td></tr>';
    -	print "<tr>".'<td>'.$langs->trans("Address").'</td><td>';
    -	print '<textarea name="address" wrap="soft" class="quatrevingtpercent" rows="3">'.dol_escape_htmltag(GETPOST("address")).'</textarea></td></tr>';
    +	if (empty($conf->societe->enabled) || empty($conf->global->DONATION_USE_THIRDPARTIES))
    +	{
    +		print "<tr>".'<td>'.$langs->trans("Company").'</td><td><input type="text" name="societe" value="'.dol_escape_htmltag(GETPOST("societe")).'" class="maxwidth200"></td></tr>';
    +		print "<tr>".'<td>'.$langs->trans("Lastname").'</td><td><input type="text" name="lastname" value="'.dol_escape_htmltag(GETPOST("lastname")).'" class="maxwidth200"></td></tr>';
    +		print "<tr>".'<td>'.$langs->trans("Firstname").'</td><td><input type="text" name="firstname" value="'.dol_escape_htmltag(GETPOST("firstname")).'" class="maxwidth200"></td></tr>';
    +		print "<tr>".'<td>'.$langs->trans("Address").'</td><td>';
    +		print '<textarea name="address" wrap="soft" class="quatrevingtpercent" rows="3">'.dol_escape_htmltag(GETPOST("address")).'</textarea></td></tr>';
     
    -    // Zip / Town
    -    print '<tr><td>'.$langs->trans("Zip").' / '.$langs->trans("Town").'</td><td>';
    -	print $formcompany->select_ziptown((isset($_POST["zipcode"])?$_POST["zipcode"]:$object->zip),'zipcode',array('town','selectcountry_id','state_id'),6);
    -    print ' ';
    -    print $formcompany->select_ziptown((isset($_POST["town"])?$_POST["town"]:$object->town),'town',array('zipcode','selectcountry_id','state_id'));
    -    print '</tr>';
    +		// Zip / Town
    +		print '<tr><td>'.$langs->trans("Zip").' / '.$langs->trans("Town").'</td><td>';
    +		print $formcompany->select_ziptown((isset($_POST["zipcode"])?$_POST["zipcode"]:$object->zip),'zipcode',array('town','selectcountry_id','state_id'),6);
    +		print ' ';
    +		print $formcompany->select_ziptown((isset($_POST["town"])?$_POST["town"]:$object->town),'town',array('zipcode','selectcountry_id','state_id'));
    +		print '</tr>';
     
    -	// Country
    -    print '<tr><td><label for="selectcountry_id">'.$langs->trans('Country').'</label></td><td class="maxwidthonsmartphone">';
    -    print $form->select_country(GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id);
    -    if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
    -    print '</td></tr>';
    +		// Country
    +		print '<tr><td><label for="selectcountry_id">'.$langs->trans('Country').'</label></td><td class="maxwidthonsmartphone">';
    +		print $form->select_country(GETPOST('country_id')!=''?GETPOST('country_id'):$object->country_id);
    +		if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
    +		print '</td></tr>';
     
    -	print "<tr>".'<td>'.$langs->trans("EMail").'</td><td><input type="text" name="email" value="'.dol_escape_htmltag(GETPOST("email")).'" class="maxwidth200"></td></tr>';
    +		print "<tr>".'<td>'.$langs->trans("EMail").'</td><td><input type="text" name="email" value="'.dol_escape_htmltag(GETPOST("email")).'" class="maxwidth200"></td></tr>';
    +	}
     
     	// Payment mode
     	print "<tr><td>".$langs->trans("PaymentMode")."</td><td>\n";
    @@ -455,7 +510,7 @@ if (! empty($id) && $action == 'edit')
     
     	// Date
     	print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Date").'</td><td>';
    -	$form->select_date($object->date,'','','','',"update");
    +	print $form->selectDate($object->date,'','','','',"update");
     	print '</td>';
     
     	// Amount
    @@ -791,6 +846,16 @@ if (! empty($id) && $action != 'edit')
     	$linktoelem = $form->showLinkToObjectBlock($object, null, array('don'));
     	$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
     
    +		// Show online payment link
    +		$useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled));
    +
    +		if ($useonlinepayment) //$object->statut != Facture::STATUS_DRAFT &&
    +		{
    +			print '<br><!-- Link to pay -->'."\n";
    +			require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
    +			print showOnlinePaymentUrl('donation', $object->ref).'<br>';
    +		}
    +
     	print '</div><div class="fichehalfright"><div class="ficheaddleft">';
     
     	print '</div></div></div>';
    diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php
    index 2fa0ee44178..6abd093c8c3 100644
    --- a/htdocs/don/class/don.class.php
    +++ b/htdocs/don/class/don.class.php
    @@ -34,34 +34,62 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Don extends CommonObject
     {
    -    public $element='don'; 					// Id that identify managed objects
    -    public $table_element='don';			// Name of table without prefix where object is stored
    -	public $fk_element = 'fk_donation';
    -	public $ismultientitymanaged = 1;  	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    -    var $picto = 'generic';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='don';
     
    -    var $date;
    -    var $amount;
    -    var $societe;
    -    var $address;
    -    var $zip;
    -    var $town;
    -    var $email;
    -    var $public;
    -    var $fk_project;
    -    var $fk_typepayment;
    -	var $num_payment;
    -	var $date_valid;
    -	var $modepaymentid = 0;
    -
    -	var $labelstatut;
    -	var $labelstatutshort;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='don';
     
     	/**
    -	 * @deprecated
    -	 * @see note_private, note_public
    +	 * @var int Field with ID of parent key if this field has a parent
     	 */
    -	var $commentaire;
    +	public $fk_element = 'fk_donation';
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'generic';
    +
    +    public $date;
    +    public $amount;
    +    public $societe;
    +
    +    /**
    +	 * @var string Address
    +	 */
    +	public $address;
    +
    +    public $zip;
    +    public $town;
    +    public $email;
    +    public $public;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_project;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_typepayment;
    +
    +	public $num_payment;
    +	public $date_valid;
    +	public $modepaymentid = 0;
    +
    +	public $labelstatut;
    +	public $labelstatutshort;
     
     
         /**
    @@ -71,9 +99,7 @@ class Don extends CommonObject
          */
         function __construct($db)
         {
    -        global $langs;
    -
    -        $this->db = $db;
    +         $this->db = $db;
         }
     
     
    @@ -88,6 +114,7 @@ class Don extends CommonObject
             return $this->LibStatut($this->statut,$mode);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Renvoi le libelle d'un statut donne
          *
    @@ -97,7 +124,8 @@ class Don extends CommonObject
          */
         function LibStatut($statut,$mode=0)
         {
    -    	if (empty($this->labelstatut) || empty($this->labelstatushort))
    +        // phpcs:enable
    +    	if (empty($this->labelstatut) || empty($this->labelstatutshort))
         	{
     	    	global $langs;
     	    	$langs->load("donations");
    @@ -115,44 +143,44 @@ class Don extends CommonObject
             {
                 return $this->labelstatut[$statut];
             }
    -        if ($mode == 1)
    +        elseif ($mode == 1)
             {
                 return $this->labelstatutshort[$statut];
             }
    -        if ($mode == 2)
    +        elseif ($mode == 2)
             {
                 if ($statut == -1) return img_picto($this->labelstatut[$statut],'statut5').' '.$this->labelstatutshort[$statut];
    -            if ($statut == 0)  return img_picto($this->labelstatut[$statut],'statut0').' '.$this->labelstatutshort[$statut];
    -            if ($statut == 1)  return img_picto($this->labelstatut[$statut],'statut1').' '.$this->labelstatutshort[$statut];
    -            if ($statut == 2)  return img_picto($this->labelstatut[$statut],'statut6').' '.$this->labelstatutshort[$statut];
    +            elseif ($statut == 0)  return img_picto($this->labelstatut[$statut],'statut0').' '.$this->labelstatutshort[$statut];
    +            elseif ($statut == 1)  return img_picto($this->labelstatut[$statut],'statut1').' '.$this->labelstatutshort[$statut];
    +            elseif ($statut == 2)  return img_picto($this->labelstatut[$statut],'statut6').' '.$this->labelstatutshort[$statut];
             }
    -        if ($mode == 3)
    +        elseif ($mode == 3)
             {
                 if ($statut == -1) return img_picto($this->labelstatut[$statut],'statut5');
    -            if ($statut == 0)  return img_picto($this->labelstatut[$statut],'statut0');
    -            if ($statut == 1)  return img_picto($this->labelstatut[$statut],'statut1');
    -            if ($statut == 2)  return img_picto($this->labelstatut[$statut],'statut6');
    +            elseif ($statut == 0)  return img_picto($this->labelstatut[$statut],'statut0');
    +            elseif ($statut == 1)  return img_picto($this->labelstatut[$statut],'statut1');
    +            elseif ($statut == 2)  return img_picto($this->labelstatut[$statut],'statut6');
             }
    -        if ($mode == 4)
    +        elseif ($mode == 4)
             {
                 if ($statut == -1) return img_picto($this->labelstatut[$statut],'statut5').' '.$this->labelstatut[$statut];
    -            if ($statut == 0)  return img_picto($this->labelstatut[$statut],'statut0').' '.$this->labelstatut[$statut];
    -            if ($statut == 1)  return img_picto($this->labelstatut[$statut],'statut1').' '.$this->labelstatut[$statut];
    -            if ($statut == 2)  return img_picto($this->labelstatut[$statut],'statut6').' '.$this->labelstatut[$statut];
    +            elseif ($statut == 0)  return img_picto($this->labelstatut[$statut],'statut0').' '.$this->labelstatut[$statut];
    +            elseif ($statut == 1)  return img_picto($this->labelstatut[$statut],'statut1').' '.$this->labelstatut[$statut];
    +            elseif ($statut == 2)  return img_picto($this->labelstatut[$statut],'statut6').' '.$this->labelstatut[$statut];
             }
    -            if ($mode == 5)
    +        elseif ($mode == 5)
             {
                 if ($statut == -1) return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut5');
    -            if ($statut == 0)  return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut0');
    -            if ($statut == 1)  return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut1');
    -            if ($statut == 2)  return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut6');
    +            elseif ($statut == 0)  return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut0');
    +            elseif ($statut == 1)  return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut1');
    +            elseif ($statut == 2)  return $this->labelstatutshort[$statut].' '.img_picto($this->labelstatut[$statut],'statut6');
             }
    -        if ($mode == 6)
    +        elseif ($mode == 6)
             {
                 if ($statut == -1) return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut5');
    -            if ($statut == 0)  return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut0');
    -            if ($statut == 1)  return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut1');
    -            if ($statut == 2)  return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut6');
    +            elseif ($statut == 0)  return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut0');
    +            elseif ($statut == 1)  return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut1');
    +            elseif ($statut == 2)  return $this->labelstatut[$statut].' '.img_picto($this->labelstatut[$statut],'statut6');
             }
         }
     
    @@ -366,8 +394,8 @@ class Don extends CommonObject
             $sql.= ", '".$this->db->escape($this->address)."'";
             $sql.= ", '".$this->db->escape($this->zip)."'";
             $sql.= ", '".$this->db->escape($this->town)."'";
    -		$sql.= ", ".$this->country_id;
    -        $sql.= ", ".$this->public;
    +        $sql.= ", ".($this->country_id > 0 ? $this->country_id : '0');
    +        $sql.= ", ".((int) $this->public);
             $sql.= ", ".($this->fk_project > 0?$this->fk_project:"null");
            	$sql.= ", ".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL");
     		$sql.= ", ".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL");
    @@ -379,7 +407,6 @@ class Don extends CommonObject
             $sql.= ", '".$this->db->escape($this->phone_mobile)."'";
             $sql.= ")";
     
    -        dol_syslog(get_class($this)."::create", LOG_DEBUG);
             $resql = $this->db->query($sql);
             if ($resql)
             {
    @@ -415,8 +442,8 @@ class Don extends CommonObject
     
     		if (!$error && !empty($conf->global->MAIN_DISABLEDRAFTSTATUS))
             {
    -            $res = $this->setValid($user);
    -            if ($res < 0) $error++;
    +            //$res = $this->setValid($user);
    +            //if ($res < 0) $error++;
             }
     
             if (!$error)
    @@ -670,7 +697,6 @@ class Don extends CommonObject
                     $this->note_private	  = $obj->note_private;
                     $this->note_public	  = $obj->note_public;
                     $this->modelpdf       = $obj->model_pdf;
    -                $this->commentaire    = $obj->note;	// deprecated
     
                     // Retreive all extrafield
                     // fetch optionals attributes and labels
    @@ -683,9 +709,9 @@ class Don extends CommonObject
                 dol_print_error($this->db);
                 return -1;
             }
    -
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Validate a promise of donation
          *
    @@ -696,6 +722,7 @@ class Don extends CommonObject
          */
         function valid_promesse($id, $userid, $notrigger=0)
         {
    +        // phpcs:enable
     		global $langs, $user;
     
     		$error=0;
    @@ -736,6 +763,7 @@ class Don extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Classify the donation as paid, the donation was received
          *
    @@ -745,6 +773,7 @@ class Don extends CommonObject
          */
         function set_paid($id, $modepayment=0)
         {
    +        // phpcs:enable
             $sql = "UPDATE ".MAIN_DB_PREFIX."don SET fk_statut = 2";
             if ($modepayment)
             {
    @@ -771,6 +800,7 @@ class Don extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Set donation to status cancelled
          *
    @@ -779,6 +809,7 @@ class Don extends CommonObject
          */
         function set_cancel($id)
         {
    +        // phpcs:enable
             $sql = "UPDATE ".MAIN_DB_PREFIX."don SET fk_statut = -1 WHERE rowid = ".$id;
     
             $resql=$this->db->query($sql);
    @@ -800,6 +831,7 @@ class Don extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Sum of donations
          *
    @@ -808,6 +840,7 @@ class Don extends CommonObject
          */
         function sum_donations($param)
         {
    +        // phpcs:enable
             global $conf;
     
             $result=0;
    @@ -827,13 +860,15 @@ class Don extends CommonObject
             return $result;
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *	Charge indicateurs this->nb pour le tableau de bord
          *
          *	@return     int         <0 if KO, >0 if OK
          */
         function load_state_board()
         {
    +        // phpcs:enable
             global $conf;
     
             $this->nb=array();
    @@ -1038,5 +1073,4 @@ class Don extends CommonObject
     			return 0;
     		}
     	}
    -
     }
    diff --git a/htdocs/don/class/donstats.class.php b/htdocs/don/class/donstats.class.php
    index dfe74b7f691..ed048dc04a4 100644
    --- a/htdocs/don/class/donstats.class.php
    +++ b/htdocs/don/class/donstats.class.php
    @@ -34,6 +34,9 @@ include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
      */
     class DonationStats extends Stats
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element;
     
     	var $socid;
    @@ -131,4 +134,4 @@ class DonationStats extends Stats
     
     		return $this->_getAllByYear($sql);
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/don/class/paymentdonation.class.php b/htdocs/don/class/paymentdonation.class.php
    index 8d31c292155..b0e3a80b082 100644
    --- a/htdocs/don/class/paymentdonation.class.php
    +++ b/htdocs/don/class/paymentdonation.class.php
    @@ -29,13 +29,31 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class PaymentDonation extends CommonObject
     {
    -	public $element='payment_donation';			//!< Id that identify managed objects
    -	public $table_element='payment_donation';	//!< Name of table without prefix where object is stored
    -    public $picto = 'payment';
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='payment_donation';
     
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='payment_donation';
    +
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'payment';
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_donation;
    +
     	public $datec='';
     	public $tms='';
     	public $datep='';
    @@ -43,8 +61,20 @@ class PaymentDonation extends CommonObject
         public $amounts=array();   // Array of amounts
     	public $typepayment;
     	public $num_payment;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
     
     	/**
    @@ -68,7 +98,7 @@ class PaymentDonation extends CommonObject
          *  Use this->amounts to have list of lines for the payment
          *
     	 *  @param      User		$user			User making payment
    -	 *	@param      bool 		$notrigger 		false=launch triggers after, true=disable triggers
    +	 *  @param      bool 		$notrigger 		false=launch triggers after, true=disable triggers
     	 *  @return     int     					<0 if KO, id of payment if OK
     	 */
     	function create($user, $notrigger=false)
    @@ -445,6 +475,7 @@ class PaymentDonation extends CommonObject
     	    return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -454,7 +485,8 @@ class PaymentDonation extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    -	    global $langs;
    +        // phpcs:enable
    +        global $langs;
     
     	    return '';
     	}
    @@ -482,8 +514,6 @@ class PaymentDonation extends CommonObject
     		$this->fk_bank='';
     		$this->fk_user_creat='';
     		$this->fk_user_modif='';
    -
    -
     	}
     
     
    @@ -570,6 +600,7 @@ class PaymentDonation extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update link between the donation payment and the generated line in llx_bank
     	 *
    @@ -578,6 +609,7 @@ class PaymentDonation extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = "UPDATE ".MAIN_DB_PREFIX."payment_donation SET fk_bank = ".$id_bank." WHERE rowid = ".$this->id;
     
     		dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG);
    diff --git a/htdocs/don/document.php b/htdocs/don/document.php
    index 020272d5bae..01aab513a6a 100644
    --- a/htdocs/don/document.php
    +++ b/htdocs/don/document.php
    @@ -40,9 +40,8 @@ if (! empty($conf->projet->enabled))
         require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     }
     
    -$langs->load("other");
    -$langs->load("donations");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","other","donations"));
     
     $id = GETPOST('id','int');
     $ref = GETPOST('ref', 'alpha');
    @@ -107,7 +106,7 @@ if ($object->id)
     	dol_fiche_head($head, 'documents',  $langs->trans("Donation"), -1, 'generic');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -185,7 +184,6 @@ if ($object->id)
         $permtoedit = $user->rights->don->creer;
         $param = '&id=' . $object->id;
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
    diff --git a/htdocs/don/list.php b/htdocs/don/list.php
    index 1e7d93302d8..782a3afba75 100644
    --- a/htdocs/don/list.php
    +++ b/htdocs/don/list.php
    @@ -28,8 +28,8 @@ require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
     if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     
    -$langs->load("companies");
    -$langs->load("donations");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","donations"));
     
     $sortfield = GETPOST("sortfield",'alpha');
     $sortorder = GETPOST("sortorder",'alpha');
    diff --git a/htdocs/don/note.php b/htdocs/don/note.php
    index d78aa2c7ea5..3a5c55f7c6d 100644
    --- a/htdocs/don/note.php
    +++ b/htdocs/don/note.php
    @@ -35,9 +35,8 @@ if (! empty($conf->projet->enabled))
         require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     }
     
    -$langs->load("companies");
    -$langs->load("bills");
    -$langs->load("donations");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","bills","donations"));
     
     $id=(GETPOST('id','int')?GETPOST('id','int'):GETPOST('facid','int'));  // For backward compatibility
     $ref=GETPOST('ref','alpha');
    diff --git a/htdocs/don/payment/card.php b/htdocs/don/payment/card.php
    index e4a7ef5c5d4..1c3a60e7e78 100644
    --- a/htdocs/don/payment/card.php
    +++ b/htdocs/don/payment/card.php
    @@ -28,9 +28,8 @@ require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php';
     if (! empty($conf->banque->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
    -$langs->load('bills');
    -$langs->load('banks');
    -$langs->load('companies');
    +// Load translation files required by the page
    +$langs->loadLangs(array("bills","banks","companies"));
     
     // Security check
     $id=GETPOST('rowid')?GETPOST('rowid','int'):GETPOST('id','int');
    @@ -134,7 +133,6 @@ dol_fiche_head($head, $hselected, $langs->trans("DonationPayment"), -1, 'payment
     if ($action == 'delete')
     {
     	print $form->formconfirm('card.php?id='.$object->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete','',0,2);
    -
     }
     
     /*
    @@ -144,7 +142,6 @@ if ($action == 'valide')
     {
     	$facid = GETPOST('facid','int');
     	print $form->formconfirm('card.php?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide','',0,2);
    -
     }
     
     
    diff --git a/htdocs/don/payment/payment.php b/htdocs/don/payment/payment.php
    index d1cfaa6f0ad..e016bb80a8e 100644
    --- a/htdocs/don/payment/payment.php
    +++ b/htdocs/don/payment/payment.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2015       Alexandre Spangaro	  	<aspangaro.dolibarr@gmail.com>
    +/* Copyright (C) 2015       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -174,7 +175,7 @@ if (GETPOST('action','aZ09') == 'create')
     	print '<input type="hidden" name="rowid" value="'.$chid.'">';
     	print '<input type="hidden" name="chid" value="'.$chid.'">';
     	print '<input type="hidden" name="action" value="add_payment">';
    -	
    +
         dol_fiche_head();
     
     	print '<table cellspacing="0" class="border" width="100%" cellpadding="2">';
    @@ -205,7 +206,7 @@ if (GETPOST('action','aZ09') == 'create')
     	print '<tr><td class="fieldrequired">'.$langs->trans("Date").'</td><td colspan="2">';
     	$datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
     	$datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaid):0;
    -	$form->select_date($datepayment,'','','','',"add_payment",1,1);
    +	print $form->selectDate($datepayment, '', '', '', '', "add_payment", 1, 1);
     	print "</td>";
     	print '</tr>';
     
    diff --git a/htdocs/don/stats/index.php b/htdocs/don/stats/index.php
    index cb574da939a..e71212e806a 100644
    --- a/htdocs/don/stats/index.php
    +++ b/htdocs/don/stats/index.php
    @@ -47,9 +47,8 @@ $year = GETPOST('year')>0?GETPOST('year'):$nowyear;
     $startyear=$year-1;
     $endyear=$year;
     
    -$langs->load("sendings");
    -$langs->load("other");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("companies","other","sendings"));
     
     
     /*
    @@ -260,6 +259,7 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
     	print '<br><br>';
     //}
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="border" width="100%">';
     print '<tr height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -294,6 +294,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    diff --git a/htdocs/don/tpl/linkedobjectblock.tpl.php b/htdocs/don/tpl/linkedobjectblock.tpl.php
    index d7ad6587845..f8d51bb6e35 100644
    --- a/htdocs/don/tpl/linkedobjectblock.tpl.php
    +++ b/htdocs/don/tpl/linkedobjectblock.tpl.php
    @@ -36,7 +36,7 @@ $total=0; $ilink=0;
     foreach($linkedObjectBlock as $key => $objectlink)
     {
         $ilink++;
    -    
    +
         $trclass='oddeven';
         if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total';
     ?>
    @@ -66,7 +66,7 @@ if (count($linkedObjectBlock) > 1)
         	<td align="right"></td>
         	<td align="right"></td>
         </tr>
    -    <?php  
    +    <?php
     }
     ?>
     
    diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php
    index a3669f909e9..d3fdd115ffa 100644
    --- a/htdocs/ecm/class/ecmdirectory.class.php
    +++ b/htdocs/ecm/class/ecmdirectory.class.php
    @@ -27,32 +27,77 @@
      */
     class EcmDirectory // extends CommonObject
     {
    -	public $element='ecm_directories';			//!< Id that identify managed objects
    -	//public $table_element='ecm_directories';	//!< Name of table without prefix where object is stored
    -	var $picto = 'dir';
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='ecm_directories';
     
    -	var $id;
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	//public $table_element='ecm_directories';
     
    -	var $label;
    -	var $fk_parent;
    -	var $description;
    -	var $cachenbofdoc=-1;	// By default cache initialized with value 'not calculated'
    -	var $date_c;
    -	var $date_m;
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'dir';
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +     * @var string ECM directories label
    +     */
    +    public $label;
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_parent;
    +
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +	public $cachenbofdoc=-1;	// By default cache initialized with value 'not calculated'
    +	public $date_c;
    +	public $date_m;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_m;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_c;
    +
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
     
    -	var $cats=array();
    -	var $motherof=array();
    +	public $cats=array();
    +	public $motherof=array();
     
    -	var $forbiddenchars = array('<','>',':','/','\\','?','*','|','"');
    -	var $forbiddencharsdir = array('<','>',':','?','*','|','"');
    +	public $forbiddenchars = array('<','>',':','/','\\','?','*','|','"');
    +	public $forbiddencharsdir = array('<','>',':','?','*','|','"');
     
     	public $full_arbo_loaded;
     
    +	/**
    +	 * @var string Error code (or message)
    +	 */
     	public $error;
    -	public $errors;
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
     
     	/**
    @@ -490,6 +535,7 @@ class EcmDirectory // extends CommonObject
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Load this->motherof that is array(id_son=>id_parent, ...)
     	 *
    @@ -497,6 +543,7 @@ class EcmDirectory // extends CommonObject
     	 */
     	function load_motherof()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$this->motherof=array();
    @@ -537,6 +584,7 @@ class EcmDirectory // extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -546,11 +594,13 @@ class EcmDirectory // extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		return '';
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Reconstruit l'arborescence des categories sous la forme d'un tableau à partir de la base de donnée
     	 *	Renvoi un tableau de tableau('id','id_mere',...) trie selon arbre et avec:
    @@ -572,6 +622,7 @@ class EcmDirectory // extends CommonObject
     	 */
     	function get_full_arbo($force=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (empty($force) && ! empty($this->full_arbo_loaded))
    @@ -629,7 +680,6 @@ class EcmDirectory // extends CommonObject
     					}
     				}
     				$i++;
    -
     			}
     		}
     		else
    @@ -651,6 +701,7 @@ class EcmDirectory // extends CommonObject
     		return $this->cats;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define properties fullpath, fullrelativename, fulllabel of a directory of array this->cats and all its childs.
     	 *  Separator between directories is always '/', whatever is OS.
    @@ -661,6 +712,7 @@ class EcmDirectory // extends CommonObject
     	 */
     	function build_path_from_id_categ($id_categ,$protection=0)
     	{
    +        // phpcs:enable
     		// Define fullpath
     		if (! empty($this->cats[$id_categ]['id_mere']))
     		{
    @@ -735,6 +787,7 @@ class EcmDirectory // extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          * Call trigger based on this instance
          *
    @@ -748,6 +801,7 @@ class EcmDirectory // extends CommonObject
          */
         function call_trigger($trigger_name, $user)
         {
    +        // phpcs:enable
             global $langs,$conf;
     
             include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    @@ -764,8 +818,5 @@ class EcmDirectory // extends CommonObject
                 }
             }
             return $result;
    -
         }
    -
    -
     }
    diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php
    index df76bac3e9b..42af7f92635 100644
    --- a/htdocs/ecm/class/ecmfiles.class.php
    +++ b/htdocs/ecm/class/ecmfiles.class.php
    @@ -40,22 +40,44 @@ class EcmFiles extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'ecmfiles';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'ecm_files';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'generic';
     
     	/**
    +	 * @var string Ref hash of file path
     	 */
    -	public $ref;					// hash of file path
    -	public $label;					// hash of file content (md5_file(dol_osencode($destfull))
    +	public $ref;
    +
    +	/**
    +	 * hash of file content (md5_file(dol_osencode($destfull))
    +     * @var string Ecm Files label
    +     */
    +    public $label;
    +
     	public $share;					// hash for file sharing, empty by default (example: getRandomPassword(true))
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    +
     	public $filename;
     	public $filepath;
     	public $fullpath_orig;
    +
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
    +
     	public $keywords;
     	public $cover;
     	public $position;
    @@ -63,15 +85,21 @@ class EcmFiles extends CommonObject
     	public $extraparams;
     	public $date_c = '';
     	public $date_m = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_c;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_m;
    +
     	public $acl;
     	public $src_object_type;
     	public $src_object_id;
     
    -	/**
    -	 */
    -
     
     	/**
     	 * Constructor
    @@ -342,7 +370,7 @@ class EcmFiles extends CommonObject
     		else {
     			$sql .= ' AND t.rowid = '.$this->db->escape($id);					// rowid already unique
     		}
    -		
    +
     		$this->db->plimit(1);	// When we search on src or on hash of content (hashforfile) to solve hash conflict when several files has same content, we take first one only
     		$this->db->order('t.rowid', 'ASC');
     
    @@ -782,6 +810,7 @@ class EcmFiles extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -791,6 +820,7 @@ class EcmFiles extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		return '';
     	}
    @@ -832,12 +862,25 @@ class EcmFiles extends CommonObject
     
     class EcmfilesLine
     {
    -	public $label;
    +	/**
    +     * @var string ECM files line label
    +     */
    +    public $label;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    +
     	public $filename;
     	public $filepath;
     	public $fullpath_orig;
    +
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
    +
     	public $keywords;
     	public $cover;
     	public $position;
    @@ -845,8 +888,17 @@ class EcmfilesLine
     	public $extraparams;
     	public $date_c = '';
     	public $date_m = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_c;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_m;
    +
     	public $acl;
     	public $src_object_type;
     	public $src_object_id;
    diff --git a/htdocs/ecm/class/htmlecm.form.class.php b/htdocs/ecm/class/htmlecm.form.class.php
    index 3139c5f9986..b6000cad923 100644
    --- a/htdocs/ecm/class/htmlecm.form.class.php
    +++ b/htdocs/ecm/class/htmlecm.form.class.php
    @@ -27,8 +27,15 @@ require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
      */
     class FormEcm
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +	
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    diff --git a/htdocs/ecm/dir_add_card.php b/htdocs/ecm/dir_add_card.php
    index 5dab56b29a0..922c06f0cc2 100644
    --- a/htdocs/ecm/dir_add_card.php
    +++ b/htdocs/ecm/dir_add_card.php
    @@ -290,7 +290,6 @@ if (empty($action) || $action == 'delete_section')
     	if ($action == 'delete_section')
     	{
     		print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section, $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$ecmdir->label), 'confirm_deletesection');
    -
     	}
     
     	// Construit fiche  rubrique
    diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php
    index 982fa045d32..7c3473117fc 100644
    --- a/htdocs/ecm/dir_card.php
    +++ b/htdocs/ecm/dir_card.php
    @@ -271,7 +271,6 @@ if ($action == 'update' && ! GETPOST('cancel','alpha'))
         		$upload_dir = $conf->medias->multidir_output[$conf->entity].'/'.$relativepath;
         		$section = $relativepath;
         	}
    -
         }
     }
     
    diff --git a/htdocs/ecm/file_card.php b/htdocs/ecm/file_card.php
    index b1b45141f4f..959a4bc5b8d 100644
    --- a/htdocs/ecm/file_card.php
    +++ b/htdocs/ecm/file_card.php
    @@ -390,7 +390,6 @@ if ($action == 'edit')
     if ($action == 'delete_file')
     {
         print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.urlencode($section), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile',$urlfile), 'confirm_deletefile', '', 1, 1);
    -
     }
     
     if ($action != 'edit')
    diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php
    index ae11ebbd479..faac5eba10d 100644
    --- a/htdocs/ecm/index.php
    +++ b/htdocs/ecm/index.php
    @@ -77,6 +77,10 @@ $error=0;
      *	Actions
      */
     
    +// TODO Replace sendit and confirm_deletefile with
    +//$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid;	// used after a confirm_deletefile into actions_linkedfiles.inc.php
    +//include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
    +
     // Upload file (code similar but different than actions_linkedfiles.inc.php)
     if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     {
    @@ -105,7 +109,8 @@ if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     
     	if (! $error)
     	{
    -	    $res = dol_add_file_process($upload_dir, 0, 1, 'userfile', '', '', '', 0);
    +		$generatethumbs = 0;
    +		$res = dol_add_file_process($upload_dir, 0, 1, 'userfile', '', null, '', $generatethumbs);
     	    if ($res > 0)
     	    {
     	       $result=$ecmdir->changeNbOfFiles('+');
    @@ -113,6 +118,33 @@ if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     	}
     }
     
    +// Remove file (code similar but different than actions_linkedfiles.inc.php)
    +if ($action == 'confirm_deletefile')
    +{
    +	if (GETPOST('confirm') == 'yes')
    +	{
    +		// GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
    +		//var_dump(GETPOST('urlfile'));exit;
    +
    +		$upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:'');
    +		$file = $upload_dir . "/" . GETPOST('urlfile','alpha');
    +
    +		$ret=dol_delete_file($file);	// This include also the delete from file index in database.
    +		if ($ret)
    +		{
    +			setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile','alpha')), null, 'mesgs');
    +			$result=$ecmdir->changeNbOfFiles('-');
    +		}
    +		else
    +		{
    +			setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile','alpha')), null, 'errors');
    +		}
    +
    +		clearstatcache();
    +	}
    +	$action='file_manager';
    +}
    +
     // Add directory
     if ($action == 'add' && $user->rights->ecm->setup)
     {
    @@ -135,33 +167,6 @@ if ($action == 'add' && $user->rights->ecm->setup)
     	clearstatcache();
     }
     
    -// Remove file (code similar but different than actions_linkedfiles.inc.php)
    -if ($action == 'confirm_deletefile')
    -{
    -    if (GETPOST('confirm') == 'yes')
    -    {
    -    	// GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
    -		//var_dump(GETPOST('urlfile'));exit;
    -
    -    	$upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:'');
    -    	$file = $upload_dir . "/" . GETPOST('urlfile','alpha');	// Do not use urldecode here ($_GET and $_POST are already decoded by PHP).
    -
    -    	$ret=dol_delete_file($file);	// This include also the delete from file index in database.
    -    	if ($ret)
    -    	{
    -    		setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile','alpha')), null, 'mesgs');
    -    		$result=$ecmdir->changeNbOfFiles('-');
    -    	}
    -    	else
    -    	{
    -    		setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile','alpha')), null, 'errors');
    -    	}
    -
    -    	clearstatcache();
    -    }
    -   	$action='file_manager';
    -}
    -
     // Remove directory
     if ($action == 'confirm_deletesection' && GETPOST('confirm') == 'yes')
     {
    diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php
    index 382312e4434..ea5e5c13ff2 100644
    --- a/htdocs/ecm/index_auto.php
    +++ b/htdocs/ecm/index_auto.php
    @@ -343,7 +343,6 @@ dol_fiche_head($head, 'index_auto', $langs->trans("ECMArea").' - '.$langs->trans
     if ($action == 'delete' && empty($conf->use_javascript_ajax))
     {
     	print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1);
    -
     }
     
     // Start container of all panels
    diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    index 0a51e8cc73d..5fe466803fb 100644
    --- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    +++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2012	Regis Houssin	<regis.houssin@capnetworks.com>
    +/* Copyright (C) 2012	Regis Houssin			<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018	Laurent Destailleur 	<eldy@users.sourceforge.net>
      *
      * 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
    @@ -27,7 +28,7 @@ if (empty($conf) || ! is_object($conf))
     ?>
     
     <!-- BEGIN PHP TEMPLATE ecm/tpl/enablefiletreeajax.tpl.php -->
    -<!-- Doc of fileTree plugin at http://www.abeautifulsite.net/blog/2008/03/jquery-file-tree/ -->
    +<!-- Doc of fileTree plugin at https://www.abeautifulsite.net/jquery-file-tree -->
     
     <script type="text/javascript">
     
    @@ -35,7 +36,9 @@ if (empty($conf) || ! is_object($conf))
     if (empty($module)) $module='ecm';
     $paramwithoutsection=preg_replace('/&?section=(\d+)/', '', $param);
     
    -$openeddir='/';
    +$openeddir='/';		// The root directory shown
    +// $preopened		// The dir to have preopened
    +
     ?>
     
     $(document).ready(function() {
    @@ -43,7 +46,7 @@ $(document).ready(function() {
     	$('#filetree').fileTree({
     		root: '<?php print dol_escape_js($openeddir); ?>',
     		// Ajax called if we click to expand a dir (not a file). Parameter 'dir' is provided as a POST parameter by fileTree code to this following URL.
    -		script: '<?php echo DOL_URL_ROOT.'/core/ajax/ajaxdirtree.php?modulepart='.$module.'&openeddir='.urlencode($openeddir).(empty($paramwithoutsection)?'':$paramwithoutsection); ?>',
    +		script: '<?php echo DOL_URL_ROOT.'/core/ajax/ajaxdirtree.php?modulepart='.$module.(empty($preopened)?'':'&preopened='.urlencode($preopened)).'&openeddir='.urlencode($openeddir).(empty($paramwithoutsection)?'':$paramwithoutsection); ?>',
     		folderEvent: 'click',	// 'dblclick'
     		multiFolder: false  },
     		// Called if we click on a file (not a dir)
    diff --git a/htdocs/emailcollector/index.html b/htdocs/emailcollector/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/emailcollector/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
    index 0f45ca61804..292bf5e1de8 100644
    --- a/htdocs/expedition/card.php
    +++ b/htdocs/expedition/card.php
    @@ -11,6 +11,7 @@
      * Copyright (C) 2015		Claudio Aschieri		<c.aschieri@19.coop>
      * Copyright (C) 2016-2018	Ferran Marcet			<fmarcet@2byte.es>
      * Copyright (C) 2016		Yasser Carreón			<yacasia@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -276,7 +277,7 @@ if (empty($reshook))
     			            // We try to set an amount
         			        // Case we dont use the list of available qty for each warehouse/lot
         			        // GUI does not allow this yet
    -    			        setEventMessage('StockIsRequiredToChooseWhichLotToUse', 'errors');
    +    			        setEventMessages($langs->trans("StockIsRequiredToChooseWhichLotToUse"), null, 'errors');
     			        }
     			    }
     			}
    @@ -315,7 +316,6 @@ if (empty($reshook))
     					unset($_POST["options_" . $key]);
     				}
     			}
    -
     	    }
     
     	    //var_dump($batch_line[2]);
    @@ -858,7 +858,6 @@ if (empty($reshook))
     	$mode='emailfromshipment';
     	$trackid='shi'.$object->id;
     	include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
    -
     }
     
     
    @@ -974,7 +973,7 @@ if ($action == 'create')
                 print '<td colspan="3">';
                 //print dol_print_date($object->date_livraison,"day");	// date_livraison come from order and will be stored into date_delivery planed.
                 $date_delivery = ($date_delivery?$date_delivery:$object->date_livraison); // $date_delivery comes from GETPOST
    -            print $form->select_date($date_delivery?$date_delivery:-1,'date_delivery',1,1,1);
    +            print $form->selectDate($date_delivery?$date_delivery:-1, 'date_delivery', 1, 1, 1);
                 print "</td>\n";
                 print '</tr>';
     
    @@ -1420,7 +1419,6 @@ if ($action == 'create')
     
     										print '<!-- Show details of stock -->';
     										print '('.$stock.')';
    -
     									}
     									else
     									{
    @@ -1521,7 +1519,6 @@ if ($action == 'create')
     								}
     							}
     						}
    -
     					}
     					if ($subj == 0) // Line not shown yet, we show it
     					{
    @@ -1668,21 +1665,18 @@ else if ($id || $ref)
     			}
     
     			$formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('ValidateSending'),$text,'confirm_valid','',0,1);
    -
     		}
     		// Confirm cancelation
     		if ($action == 'annuler')
     		{
     			$formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('CancelSending'),$langs->trans("ConfirmCancelSending",$object->ref),'confirm_cancel','',0,1);
    -
     		}
     
    -		if (! $formconfirm) {
    -		    $parameters = array();
    -		    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -		    if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -		    elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -		}
    +		// Call Hook formConfirm
    +		$parameters = array();
    +		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     		// Print form confirm
     		print $formconfirm;
    @@ -1799,7 +1793,7 @@ else if ($id || $ref)
     			print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
     			print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     			print '<input type="hidden" name="action" value="setdate_livraison">';
    -			print $form->select_date($object->date_delivery?$object->date_delivery:-1,'liv_',1,1,'',"setdate_livraison",1,0,1);
    +			print $form->selectDate($object->date_delivery?$object->date_delivery:-1, 'liv_', 1, 1, '', "setdate_livraison", 1, 0);
     			print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
     			print '</form>';
     		}
    @@ -1826,7 +1820,6 @@ else if ($id || $ref)
     			print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
     			print ' <input class="button" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
     			print '</form>';
    -
     		}
     		else
     		{
    @@ -1864,7 +1857,6 @@ else if ($id || $ref)
     			print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
     			print ' <input class="button" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
     			print '</form>';
    -
     		}
     		else
     		{
    @@ -2011,7 +2003,7 @@ else if ($id || $ref)
             print '<div class="div-table-responsive-no-min">';
     		print '<table class="noborder" width="100%">';
     		print '<tr class="liste_titre">';
    -		// #
    +		// Adds a line numbering column
     		if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
     		{
     			print '<td width="5" align="center">&nbsp;</td>';
    @@ -2143,7 +2135,7 @@ else if ($id || $ref)
     		    print '<!-- origin line id = '.$lines[$i]->origin_line_id.' -->'; // id of order line
     			print '<tr class="oddeven">';
     
    -			// #
    +			// Adds a line numbering column
     			if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER))
     			{
     				print '<td align="center">'.($i+1).'</td>';
    @@ -2536,7 +2528,6 @@ else if ($id || $ref)
     			{
     				print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete">'.$langs->trans("Delete").'</a>';
     			}
    -
     		}
     
     		print '</div>';
    @@ -2596,7 +2587,6 @@ else if ($id || $ref)
     	include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php
    index 844a6c95305..834c0bf2bda 100644
    --- a/htdocs/expedition/class/api_shipments.class.php
    +++ b/htdocs/expedition/class/api_shipments.class.php
    @@ -35,7 +35,7 @@ class Shipments extends DolibarrApi
         static $FIELDS = array(
             'socid',
         	'origin_id',
    -    	'origin_type'
    +    	'origin_type',
         );
     
         /**
    @@ -99,7 +99,8 @@ class Shipments extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -192,13 +193,13 @@ class Shipments extends DolibarrApi
             foreach($request_data as $field => $value) {
                 $this->shipment->$field = $value;
             }
    -        /*if (isset($request_data["lines"])) {
    +        if (isset($request_data["lines"])) {
               $lines = array();
               foreach ($request_data["lines"] as $line) {
                 array_push($lines, (object) $line);
               }
               $this->shipment->lines = $lines;
    -        }*/
    +        }
     
             if ($this->shipment->create(DolibarrApiAccess::$user) < 0) {
                 throw new RestException(500, "Error creating shipment", array_merge(array($this->shipment->error), $this->shipment->errors));
    @@ -217,7 +218,8 @@ class Shipments extends DolibarrApi
          * @return int
          */
         /*
    -    function getLines($id) {
    +    function getLines($id)
    +    {
           if(! DolibarrApiAccess::$user->rights->expedition->lire) {
     		  	throw new RestException(401);
     		  }
    @@ -250,7 +252,8 @@ class Shipments extends DolibarrApi
          * @return int
          */
         /*
    -    function postLine($id, $request_data = null) {
    +    function postLine($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->expedition->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -312,7 +315,8 @@ class Shipments extends DolibarrApi
          * @return object
          */
         /*
    -    function putLine($id, $lineid, $request_data = null) {
    +    function putLine($id, $lineid, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->expedition->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -372,7 +376,8 @@ class Shipments extends DolibarrApi
          * @throws 401
          * @throws 404
          */
    -    function deleteLine($id, $lineid) {
    +    function deleteLine($id, $lineid)
    +    {
         	if(! DolibarrApiAccess::$user->rights->expedition->creer) {
         		throw new RestException(401);
         	}
    @@ -407,7 +412,8 @@ class Shipments extends DolibarrApi
          *
          * @return int
          */
    -    function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
           if (! DolibarrApiAccess::$user->rights->expedition->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -466,7 +472,6 @@ class Shipments extends DolibarrApi
                     'message' => 'Shipment deleted'
                 )
             );
    -
         }
     
         /**
    @@ -537,7 +542,8 @@ class Shipments extends DolibarrApi
          * @throws 404
          * @throws 405
          */
    -/*    function setinvoiced($id) {
    +/*    function setinvoiced($id)
    +    {
     
             if(! DolibarrApiAccess::$user->rights->expedition->creer) {
                     throw new RestException(401);
    @@ -573,7 +579,8 @@ class Shipments extends DolibarrApi
          * @throws 405
          */
         /*
    -    function createShipmentFromOrder($orderid) {
    +    function createShipmentFromOrder($orderid)
    +    {
     
             require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
     
    @@ -608,7 +615,8 @@ class Shipments extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -653,7 +661,6 @@ class Shipments extends DolibarrApi
                 if (!isset($data[$field]))
                     throw new RestException(400, "$field field missing");
                 $shipment[$field] = $data[$field];
    -
             }
             return $shipment;
         }
    diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php
    index 5848c1b9d9d..99b288e3703 100644
    --- a/htdocs/expedition/class/expedition.class.php
    +++ b/htdocs/expedition/class/expedition.class.php
    @@ -10,7 +10,8 @@
      * Copyright (C) 2014-2017  Francis Appels          <francis.appels@yahoo.com>
      * Copyright (C) 2015       Claudio Aschieri        <c.aschieri@19.coop>
      * Copyright (C) 2016		Ferran Marcet			<fmarcet@2byte.es>
    - * Copyright (C) 2018      Nicolas ZABOURI			<info@inovea-conseil.com>
    + * Copyright (C) 2018       Nicolas ZABOURI			<info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -44,60 +45,123 @@ if (! empty($conf->productbatch->enabled)) require_once DOL_DOCUMENT_ROOT.'/expe
      */
     class Expedition extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element="shipping";
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element="fk_expedition";
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element="expedition";
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line="expeditiondet";
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'sending';
     
    -	var $socid;
    -	var $ref_customer;
    -	var $ref_int;
    -	var $brouillon;
    -	var $entrepot_id;
    -	var $lines=array();
    -	var $tracking_number;
    -	var $tracking_url;
    -	var $billed;
    -	var $model_pdf;
    +	public $socid;
     
    -	var $trueWeight;
    -	var $weight_units;
    -	var $trueWidth;
    -	var $width_units;
    -	var $trueHeight;
    -	var $height_units;
    -	var $trueDepth;
    -	var $depth_units;
    +	/**
    +	 * @var string Customer ref
    +	 */
    +	public $ref_customer;
    +
    +	/**
    +	 * @var string internal ref
    +	 */
    +	public $ref_int;
    +
    +	public $brouillon;
    +
    +	/**
    +	 * @var int warehouse id
    +	 */
    +	public $entrepot_id;
    +	public $lines=array();
    +
    +	/**
    +	 * @var string Tracking number
    +	 */
    +	public $tracking_number;
    +
    +	/**
    +	 * @var string Tracking url
    +	 */
    +	public $tracking_url;
    +	public $billed;
    +
    +	/**
    +	 * @var string name of pdf model
    +	 */
    +	public $model_pdf;
    +
    +	public $trueWeight;
    +	public $weight_units;
    +	public $trueWidth;
    +	public $width_units;
    +	public $trueHeight;
    +	public $height_units;
    +	public $trueDepth;
    +	public $depth_units;
     	// A denormalized value
    -	var $trueSize;
    +	public $trueSize;
    +
    +	public $date_delivery;		// Date delivery planed
     
    -	var $date_delivery;		// Date delivery planed
     	/**
     	 * @deprecated
     	 * @see date_shipping
     	 */
    -	var $date;
    +	public $date;
    +
     	/**
     	 * @deprecated
     	 * @see date_shipping
     	 */
    -	var $date_expedition;
    +	public $date_expedition;
    +
     	/**
     	 * Effective delivery date
     	 * @var int
     	 */
     	public $date_shipping;
    -	var $date_creation;
    -	var $date_valid;
     
    -	var $meths;
    -	var $listmeths;			// List of carriers
    +	public $date_creation;
    +	public $date_valid;
     
    +	public $meths;
    +	public $listmeths;			// List of carriers
     
    +    /**
    +	 * Draft status
    +	 */
     	const STATUS_DRAFT = 0;
    +
    +	/**
    +	 * Validated status
    +	 */
     	const STATUS_VALIDATED = 1;
    +
    +	/**
    +	 * Closed status
    +	 */
     	const STATUS_CLOSED = 2;
     
     
    @@ -344,7 +408,6 @@ class Expedition extends CommonObject
     						$this->db->rollback();
     						return -1*$error;
     					}
    -
     				}
     				else
     				{
    @@ -371,6 +434,7 @@ class Expedition extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create a expedition line
     	 *
    @@ -382,6 +446,7 @@ class Expedition extends CommonObject
     	 */
     	function create_line($entrepot_id, $origin_line_id, $qty,$array_options=0)
     	{
    +        //phpcs:enable
     		$expeditionline = new ExpeditionLigne($this->db);
     		$expeditionline->fk_expedition = $this->id;
     		$expeditionline->entrepot_id = $entrepot_id;
    @@ -397,6 +462,7 @@ class Expedition extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create the detail (eat-by date) of the expedition line
     	 *
    @@ -406,6 +472,7 @@ class Expedition extends CommonObject
     	 */
     	function create_line_batch($line_ext,$array_options=0)
     	{
    +        // phpcs:enable
     		$error = 0;
     		$stockLocationQty = array(); // associated array with batch qty in stock location
     
    @@ -467,10 +534,12 @@ class Expedition extends CommonObject
     		$sql.= ", e.note_private, e.note_public";
     		$sql.= ', e.fk_incoterms, e.location_incoterms';
     		$sql.= ', i.libelle as libelle_incoterms';
    +		$sql.= ', s.libelle as shipping_method';
     		$sql.= ", el.fk_source as origin_id, el.sourcetype as origin";
     		$sql.= " FROM ".MAIN_DB_PREFIX."expedition as e";
     		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->db->escape($this->element)."'";
     		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON e.fk_incoterms = i.rowid';
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_shipment_mode as s ON e.fk_shipping_method = s.rowid';
     		$sql.= " WHERE e.entity IN (".getEntity('expedition').")";
     		if ($id)   	  $sql.= " AND e.rowid=".$id;
     		if ($ref)     $sql.= " AND e.ref='".$this->db->escape($ref)."'";
    @@ -488,9 +557,9 @@ class Expedition extends CommonObject
     				$this->id                   = $obj->rowid;
     				$this->ref                  = $obj->ref;
     				$this->socid                = $obj->socid;
    -				$this->ref_customer			= $obj->ref_customer;
    -				$this->ref_ext				= $obj->ref_ext;
    -				$this->ref_int				= $obj->ref_int;
    +				$this->ref_customer	    = $obj->ref_customer;
    +				$this->ref_ext		    = $obj->ref_ext;
    +				$this->ref_int		    = $obj->ref_int;
     				$this->statut               = $obj->fk_statut;
     				$this->user_author_id       = $obj->fk_user_author;
     				$this->date_creation        = $this->db->jdate($obj->date_creation);
    @@ -500,12 +569,13 @@ class Expedition extends CommonObject
     				$this->date_delivery        = $this->db->jdate($obj->date_delivery);	// Date planed
     				$this->fk_delivery_address  = $obj->fk_address;
     				$this->modelpdf             = $obj->model_pdf;
    -				$this->shipping_method_id	= $obj->fk_shipping_method;
    +				$this->shipping_method_id   = $obj->fk_shipping_method;
    +				$this->shipping_method	    = $obj->shipping_method;
     				$this->tracking_number      = $obj->tracking_number;
     				$this->origin               = ($obj->origin?$obj->origin:'commande'); // For compatibility
     				$this->origin_id            = $obj->origin_id;
     				$this->billed               = $obj->billed;
    -				$this->fk_project			= $obj->fk_projet;
    +				$this->fk_project	    = $obj->fk_projet;
     
     				$this->trueWeight           = $obj->weight;
     				$this->weight_units         = $obj->weight_units;
    @@ -521,13 +591,13 @@ class Expedition extends CommonObject
     				$this->note_private         = $obj->note_private;
     
     				// A denormalized value
    -				$this->trueSize           	= $obj->size."x".$obj->width."x".$obj->height;
    +				$this->trueSize             = $obj->size."x".$obj->width."x".$obj->height;
     				$this->size_units           = $obj->size_units;
     
     				//Incoterms
    -				$this->fk_incoterms = $obj->fk_incoterms;
    -				$this->location_incoterms = $obj->location_incoterms;
    -				$this->libelle_incoterms = $obj->libelle_incoterms;
    +				$this->fk_incoterms         = $obj->fk_incoterms;
    +				$this->location_incoterms   = $obj->location_incoterms;
    +				$this->libelle_incoterms    = $obj->libelle_incoterms;
     
     				$this->db->free($result);
     
    @@ -714,7 +784,6 @@ class Expedition extends CommonObject
     				$this->error=$this->db->error();
     				return -2;
     			}
    -
     		}
     
     		// Change status of order to "shipment in process"
    @@ -793,6 +862,7 @@ class Expedition extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a delivery receipt from a shipment
     	 *
    @@ -801,6 +871,7 @@ class Expedition extends CommonObject
     	 */
     	function create_delivery($user)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if ($conf->livraison_bon->enabled)
    @@ -900,6 +971,7 @@ class Expedition extends CommonObject
     		$this->lines[$num] = $line;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Add a shipment line with batch record
     	 *
    @@ -909,6 +981,7 @@ class Expedition extends CommonObject
     	 */
     	function addline_batch($dbatch,$array_options=0)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$num = count($this->lines);
    @@ -1113,7 +1186,7 @@ class Expedition extends CommonObject
     		// Stock control
     		if (! $error && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > 0)
     		{
    -			require_once(DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php");
    +			require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php";
     
     			$langs->load("agenda");
     
    @@ -1285,9 +1358,9 @@ class Expedition extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load lines
     	 *
    @@ -1295,6 +1368,7 @@ class Expedition extends CommonObject
     	 */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		global $conf, $mysoc;
     		// TODO: recuperer les champs du document associe a part
     
    @@ -1574,6 +1648,7 @@ class Expedition extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return label of a status
     	 *
    @@ -1583,37 +1658,38 @@ class Expedition extends CommonObject
     	 */
     	function LibStatut($statut,$mode)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode==0)
     		{
     			if ($statut==0) return $langs->trans($this->statuts[$statut]);
    -			if ($statut==1) return $langs->trans($this->statuts[$statut]);
    -			if ($statut==2) return $langs->trans($this->statuts[$statut]);
    +			elseif ($statut==1) return $langs->trans($this->statuts[$statut]);
    +			elseif ($statut==2) return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode==1)
    +		elseif ($mode==1)
     		{
     			if ($statut==0) return $langs->trans($this->statutshorts[$statut]);
    -			if ($statut==1) return $langs->trans($this->statutshorts[$statut]);
    -			if ($statut==2) return $langs->trans($this->statutshorts[$statut]);
    +			elseif ($statut==1) return $langs->trans($this->statutshorts[$statut]);
    +			elseif ($statut==2) return $langs->trans($this->statutshorts[$statut]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0');
    -			if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4');
    -			if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut6');
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4');
    +			elseif ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut==0) return $langs->trans($this->statutshorts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut0');
    -			if ($statut==1) return $langs->trans($this->statutshorts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut4');
    -			if ($statut==2) return $langs->trans($this->statutshorts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut6');
    +			elseif ($statut==1) return $langs->trans($this->statutshorts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut4');
    +			elseif ($statut==2) return $langs->trans($this->statutshorts[$statut]).' '.img_picto($langs->trans($this->statuts[$statut]),'statut6');
     		}
     	}
     
    @@ -1694,9 +1770,9 @@ class Expedition extends CommonObject
     			$this->lines[]=$line;
     			$xnbp++;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set the planned delivery date
     	 *
    @@ -1706,6 +1782,7 @@ class Expedition extends CommonObject
     	 */
     	function set_date_livraison($user, $date_livraison)
     	{
    +        // phpcs:enable
     		if ($user->rights->expedition->creer)
     		{
     			$sql = "UPDATE ".MAIN_DB_PREFIX."expedition";
    @@ -1731,6 +1808,7 @@ class Expedition extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Fetch deliveries method and return an array. Load array this->meths(rowid=>label).
     	 *
    @@ -1738,6 +1816,7 @@ class Expedition extends CommonObject
     	 */
     	function fetch_delivery_methods()
     	{
    +        // phpcs:enable
     		global $langs;
     		$this->meths = array();
     
    @@ -1757,6 +1836,7 @@ class Expedition extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Fetch all deliveries method and return an array. Load array this->listmeths.
     	 *
    @@ -1765,6 +1845,7 @@ class Expedition extends CommonObject
     	 */
     	function list_delivery_methods($id='')
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$this->listmeths = array();
    @@ -1791,6 +1872,7 @@ class Expedition extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update/create delivery method.
     	 *
    @@ -1800,6 +1882,7 @@ class Expedition extends CommonObject
     	 */
     	function update_delivery_method($id='')
     	{
    +        // phpcs:enable
     		if ($id=='')
     		{
     			$sql = "INSERT INTO ".MAIN_DB_PREFIX."c_shipment_mode (code, libelle, description, tracking)";
    @@ -1819,6 +1902,7 @@ class Expedition extends CommonObject
     		if ($resql < 0) dol_print_error($this->db,'');
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Activate delivery method.
     	 *
    @@ -1828,13 +1912,14 @@ class Expedition extends CommonObject
     	 */
     	function activ_delivery_method($id)
     	{
    +        // phpcs:enable
     		$sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=1';
     		$sql.= ' WHERE rowid='.$id;
     
     		$resql = $this->db->query($sql);
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  DesActivate delivery method.
     	 *
    @@ -1844,14 +1929,15 @@ class Expedition extends CommonObject
     	 */
     	function disable_delivery_method($id)
     	{
    +        // phpcs:enable
     		$sql = 'UPDATE '.MAIN_DB_PREFIX.'c_shipment_mode SET active=0';
     		$sql.= ' WHERE rowid='.$id;
     
     		$resql = $this->db->query($sql);
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Forge an set tracking url
     	 *
    @@ -1860,6 +1946,7 @@ class Expedition extends CommonObject
     	 */
     	function GetUrlTrackingStatus($value='')
     	{
    +        // phpcs:enable
     		if (! empty($this->shipping_method_id))
     		{
     			$sql = "SELECT em.code, em.tracking";
    @@ -2037,6 +2124,7 @@ class Expedition extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Classify the shipping as invoiced (used when WORKFLOW_BILL_ON_SHIPMENT is on)
     	 *
    @@ -2044,6 +2132,7 @@ class Expedition extends CommonObject
     	 */
     	function set_billed()
     	{
    +        // phpcs:enable
     		global $user;
     		$error=0;
     
    @@ -2063,7 +2152,6 @@ class Expedition extends CommonObject
     			if ($result < 0) {
     				$error++;
     			}
    -
     		} else {
     			$error++;
     			$this->errors[]=$this->db->lasterror;
    @@ -2190,7 +2278,6 @@ class Expedition extends CommonObject
     					$error++;
     				}
        			}
    -
     		} else {
     			$error++;
     			$this->errors[]=$this->db->lasterror();
    @@ -2216,7 +2303,7 @@ class Expedition extends CommonObject
     	 *  @param      int			$hidedetails    Hide details of lines
     	 *  @param      int			$hidedesc       Hide description
     	 *  @param      int			$hideref        Hide ref
    -         *  @param   null|array  $moreparams     Array to provide more information
    +     *  @param      null|array  $moreparams     Array to provide more information
     	 *  @return     int         				0 if KO, 1 if OK
     	 */
     	public function generateDocument($modele, $outputlangs,$hidedetails=0, $hidedesc=0, $hideref=0,$moreparams=null)
    @@ -2267,64 +2354,151 @@ class Expedition extends CommonObject
      */
     class ExpeditionLigne extends CommonObjectLine
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='expeditiondet';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='expeditiondet';
     
    -	public $fk_origin_line;
    -
    -	/**
    -	 * Id of shipment
    -	 * @var int
    -	 */
    -	public $fk_expedition;
    -
    -	var $db;
    -
    -	// From llx_expeditiondet
    -	var $qty;
    -	var $qty_shipped;
    -	var $fk_product;
    -	var $detail_batch;
    -	/**
    -	 * Id of warehouse
    -	 * @var int
    -	 */
    -	public $entrepot_id;
    -
    -
    -	// From llx_commandedet or llx_propaldet
    -	var $qty_asked;
    -	public $product_ref;
    -	public $product_label;
    -	public $product_desc;
    -
    -
    -	// Invoicing
    -	var $remise_percent;
    -	var $total_ht;			// Total net of tax
    -	var $total_ttc;			// Total with tax
    -	var $total_tva;			// Total VAT
    -	var $total_localtax1;   // Total Local tax 1
    -	var $total_localtax2;   // Total Local tax 2
    -
    -
    -
    -	// Deprecated
     	/**
     	 * @deprecated
     	 * @see fk_origin_line
     	 */
    -	var $origin_line_id;
    +	public $origin_line_id;
    +
     	/**
    -	 * @deprecated
    -	 * @see product_ref
    +     * @var int ID
    +     */
    +	public $fk_origin_line;
    +
    +	/**
    +	 * @var int Id of shipment
     	 */
    -	var $ref;
    +	public $fk_expedition;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +     * @var float qty asked From llx_expeditiondet
    +     */
    +    public $qty;
    +
    +    /**
    +     * @var float qty shipped
    +     */
    +    public $qty_shipped;
    +
    +    /**
    +     * @var int Id of product
    +     */
    +    public $fk_product;
    +    public $detail_batch;
    +
    +    /**
    +     * @var int Id of warehouse
    +     */
    +	public $entrepot_id;
    +
    +
    +    /**
    +     * @var float qty asked From llx_commandedet or llx_propaldet
    +     */
    +	public $qty_asked;
    +
    +    /**
    +     * @deprecated
    +     * @see product_ref
    +     */
    +    public $ref;
    +
    +	/**
    +	 * @var string product ref
    +	 */
    +	public $product_ref;
    +
     	/**
     	 * @deprecated
     	 * @see product_label
     	 */
    -	var $libelle;
    +	public $libelle;
    +
    +    /**
    +     * @var string product label
    +     */
    +	public $product_label;
    +
    +    /**
    +     * @var string product description
    +     * @deprecated
    +     * @see product_desc
    +     */
    +    public $desc;
    +
    +    /**
    +     * @var string product description
    +     */
    +	public $product_desc;
    +
    +    /**
    +     * @var float weight
    +     */
    +    public $weight;
    +    public $weight_units;
    +
    +    /**
    +     * @var float weight
    +     */
    +    public $length;
    +    public $length_units;
    +
    +    /**
    +     * @var float weight
    +     */
    +    public $surface;
    +    public $surface_units;
    +
    +    /**
    +     * @var float weight
    +     */
    +    public $volume;
    +    public $volume_units;
    +
    +	// Invoicing
    +	public $remise_percent;
    +    public $tva_tx;
    +
    +    /**
    +     * @var float total without tax
    +     */
    +    public $total_ht;
    +
    +    /**
    +     * @var float total with tax
    +     */
    +    public $total_ttc;
    +
    +    /**
    +     * @var float total vat
    +     */
    +    public $total_tva;
    +
    +    /**
    +     * @var float total localtax 1
    +     */
    +    public $total_localtax1;
    +
    +    /**
    +     * @var float total localtax 2
    +     */
    +    public $total_localtax2;
    +
     
         /**
          *	Constructor
    @@ -2375,7 +2549,7 @@ class ExpeditionLigne extends CommonObjectLine
     	 *
     	 *	@param      User	$user			User that modify
     	 *	@param      int		$notrigger		1 = disable triggers
    -	 *	@return		int						<0 if KO, line id >0 if OK
    +	 *	@return     int						<0 if KO, line id >0 if OK
     	 */
     	function insert($user=null, $notrigger=0)
     	{
    @@ -2728,4 +2902,3 @@ class ExpeditionLigne extends CommonObjectLine
     		}
     	}
     }
    -
    diff --git a/htdocs/expedition/class/expeditionbatch.class.php b/htdocs/expedition/class/expeditionbatch.class.php
    index 520f760aee0..850e4c0dda3 100644
    --- a/htdocs/expedition/class/expeditionbatch.class.php
    +++ b/htdocs/expedition/class/expeditionbatch.class.php
    @@ -28,7 +28,11 @@
      */
     class ExpeditionLineBatch extends CommonObject
     {
    -	var $element='expeditionlignebatch';			//!< Id that identify managed objects
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='expeditionlignebatch';
    +
     	private static $_table_element='expeditiondet_batch';		//!< Name of table without prefix where object is stored
     
     	var $sellby;
    @@ -48,7 +52,6 @@ class ExpeditionLineBatch extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     	/**
    @@ -234,5 +237,4 @@ class ExpeditionLineBatch extends CommonObject
     			return -1;
     		}
     	}
    -
     }
    diff --git a/htdocs/expedition/class/expeditionstats.class.php b/htdocs/expedition/class/expeditionstats.class.php
    index 5303d6d8b7b..dcdf9c97617 100644
    --- a/htdocs/expedition/class/expeditionstats.class.php
    +++ b/htdocs/expedition/class/expeditionstats.class.php
    @@ -34,6 +34,9 @@ include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
      */
     class ExpeditionStats extends Stats
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element;
     
     	var $socid;
    diff --git a/htdocs/expedition/contact.php b/htdocs/expedition/contact.php
    index 3f557059600..ce31e760b7f 100644
    --- a/htdocs/expedition/contact.php
    +++ b/htdocs/expedition/contact.php
    @@ -265,9 +265,8 @@ if ($id > 0 || ! empty($ref))
     	    $res=@include dol_buildpath($reldir.'/contacts.tpl.php');
     	    if ($res) break;
     	}
    -
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expedition/document.php b/htdocs/expedition/document.php
    index 4f9616df5ed..2be84cf26b7 100644
    --- a/htdocs/expedition/document.php
    +++ b/htdocs/expedition/document.php
    @@ -96,7 +96,7 @@ if ($id > 0 || ! empty($ref)){
     		dol_fiche_head($head, 'documents', $langs->trans("Shipment"), -1, 'sending');
     	
     
    -		// Construit liste des fichiers
    +		// Build file list
     		$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     		$totalsize=0;
     		foreach($filearray as $key => $file){
    @@ -185,7 +185,6 @@ else{
     	exit;
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expedition/index.php b/htdocs/expedition/index.php
    index 042d107b58e..8dde7bf0125 100644
    --- a/htdocs/expedition/index.php
    +++ b/htdocs/expedition/index.php
    @@ -291,6 +291,6 @@ else dol_print_error($db);
     
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php
    index 14f9eb41f44..c3632ca57fd 100644
    --- a/htdocs/expedition/list.php
    +++ b/htdocs/expedition/list.php
    @@ -160,7 +160,6 @@ if (empty($reshook))
     		setEventMessages($langs->trans('TooManyRecordForMassAction',$maxformassaction), null, 'errors');
     		$error++;
     	}
    -
     }
     
     
    @@ -632,5 +631,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/expedition/note.php b/htdocs/expedition/note.php
    index fafaf10fe1f..f276b2d0cb4 100644
    --- a/htdocs/expedition/note.php
    +++ b/htdocs/expedition/note.php
    @@ -152,7 +152,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php
    index cb058e44598..920b5508e59 100644
    --- a/htdocs/expedition/shipment.php
    +++ b/htdocs/expedition/shipment.php
    @@ -3,6 +3,8 @@
      * Copyright (C) 2005-2012	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2012-2015	Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + * Copyright (C) 2018       Philippe Grand          <philippe.grand@atoo-net.com>
      *
      * 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
    @@ -213,7 +215,6 @@ if (empty($reshook))
         }
     
         include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
    -
     }
     
     /*
    @@ -255,15 +256,13 @@ if ($id > 0 || ! empty($ref))
     		if ($action == 'cloture')
     		{
     			$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$id,$langs->trans("CloseShipment"),$langs->trans("ConfirmCloseShipment"),"confirm_cloture");
    -
     		}
     
    -		if (! $formconfirm) {
    -		    $parameters = array();
    -		    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -		    if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -		    elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -		}
    +		// Call Hook formConfirm
    +		$parameters = array();
    +		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     		// Print form confirm
     		print $formconfirm;
    @@ -371,7 +370,7 @@ if ($id > 0 || ! empty($ref))
     			print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
     			print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     			print '<input type="hidden" name="action" value="setdatedelivery">';
    -			$form->select_date($object->date_livraison>0?$object->date_livraison:-1,'liv_','','','',"setdatedelivery");
    +			print $form->selectDate($object->date_livraison>0?$object->date_livraison:-1, 'liv_', '', '', '', "setdatedelivery");
     			print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
     			print '</form>';
     		}
    @@ -907,7 +906,6 @@ if ($id > 0 || ! empty($ref))
     				print '</div>';
     
     				$somethingshown=1;
    -
     			}
     			else
     			{
    @@ -921,12 +919,11 @@ if ($id > 0 || ! empty($ref))
     	}
     	else
     	{
    -		/* Commande non trouvee */
    -		print "Commande inexistante";
    +		/* Order not found */
    +		setEventMessages($langs->trans("NonExistentOrder"), null, 'errors');
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expedition/stats/index.php b/htdocs/expedition/stats/index.php
    index 651be627b78..43cf63cd3b3 100644
    --- a/htdocs/expedition/stats/index.php
    +++ b/htdocs/expedition/stats/index.php
    @@ -259,6 +259,8 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
     	print '<br><br>';
     //}
     
    +
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -298,6 +300,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    @@ -358,6 +361,6 @@ print '</table>';
     print '<br>';
     print '<i>'.$langs->trans("StatsOnShipmentsOnlyValidated").'</i>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expedition/stats/month.php b/htdocs/expedition/stats/month.php
    index b7d217217c2..f716e06a5b2 100644
    --- a/htdocs/expedition/stats/month.php
    +++ b/htdocs/expedition/stats/month.php
    @@ -27,6 +27,8 @@ require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
     require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionstats.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
     
    +$year = GETPOST('year', 'int');
    +
     
     /*
      * View
    @@ -39,10 +41,10 @@ $HEIGHT=DolGraph::getDefaultGraphSizeForStats('height');
     
     $mesg = '';
     
    -print load_fiche_titre($langs->trans("StatisticsOfSendings").' '.$_GET["year"], $mesg);
    +print load_fiche_titre($langs->trans("StatisticsOfSendings").' '.$year, $mesg);
     
     $stats = new ExpeditionStats($db);
    -$data = $stats->getNbExpeditionByMonth($_GET["year"]);
    +$data = $stats->getNbExpeditionByMonth($year);
     
     dol_mkdir($conf->expedition->dir_temp);
     
    @@ -71,6 +73,6 @@ print $px->show();
     print '</td></tr>';
     print '</table>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
    index 141260d36f3..d16674f67d0 100644
    --- a/htdocs/expensereport/card.php
    +++ b/htdocs/expensereport/card.php
    @@ -1,9 +1,10 @@
     <?php
    -/* Copyright (C) 2003      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2015-2017 Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2017      Ferran Marcet        <fmarcet@2byte.es>
    +/* Copyright (C) 2003       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2015-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2017       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -355,7 +356,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
         			// SUBJECT
    -    			$subject = $langs->transnoentities("ExpenseReportWaitingForApproval");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForApproval");
     
         			// CONTENT
         			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -374,7 +378,7 @@ if (empty($reshook))
         			*/
     
         			// PREPARE SEND
    -    			$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +    			$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
         			if ($mailfile)
         			{
    @@ -471,7 +475,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
        			    // SUBJECT
    -    			$subject = $langs->transnoentities("ExpenseReportWaitingForReApproval");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForReApproval");
     
         			// CONTENT
         			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -495,7 +502,7 @@ if (empty($reshook))
     
     
         			// PREPARE SEND
    -    			$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +    			$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
         			if ($mailfile)
         			{
    @@ -593,7 +600,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
        			    // SUBJECT
    -       			$subject = $langs->transnoentities("ExpenseReportApproved");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportApproved");
     
            			// CONTENT
            			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -614,7 +624,7 @@ if (empty($reshook))
         			}
         			*/
     
    -        		$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +        		$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
            			if ($mailfile)
            			{
    @@ -712,7 +722,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
         		    // SUBJECT
    -       			$subject = $langs->transnoentities("ExpenseReportRefused");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportRefused");
     
            			// CONTENT
            			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -734,7 +747,7 @@ if (empty($reshook))
         			*/
     
             		// PREPARE SEND
    -        		$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +        		$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
             		if ($mailfile)
             		{
    @@ -787,126 +800,136 @@ if (empty($reshook))
         }
     
         //var_dump($user->id == $object->fk_user_validator);exit;
    -    if ($action == "confirm_cancel" && GETPOST('confirm', 'alpha')=="yes" && GETPOST('detail_cancel', 'alpha') && $id > 0 && $user->rights->expensereport->creer)
    +    if ($action == "confirm_cancel" && GETPOST('confirm', 'alpha')=="yes" && $id > 0 && $user->rights->expensereport->creer)
         {
    -    	$object = new ExpenseReport($db);
    -    	$object->fetch($id);
    -
    -    	if ($user->id == $object->fk_user_valid || $user->id == $object->fk_user_author)
    +    	if (! GETPOST('detail_cancel', 'alpha'))
         	{
    -    		$result = $object->set_cancel($user, GETPOST('detail_cancel', 'alpha'));
    -
    -    		if ($result > 0)
    -    		{
    -    			// Define output language
    -    			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
    -    			{
    -    				$outputlangs = $langs;
    -    				$newlang = '';
    -    				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
    -    				if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
    -    				if (! empty($newlang)) {
    -    					$outputlangs = new Translate("", $conf);
    -    					$outputlangs->setDefaultLang($newlang);
    -    				}
    -    				$model=$object->modelpdf;
    -    				$ret = $object->fetch($id); // Reload to get new records
    -
    -    				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
    -    			}
    -    		}
    -
    -    		if ($result > 0)
    -    		{
    -    			// Send mail
    -
    -    			// TO
    -    			$destinataire = new User($db);
    -    			$destinataire->fetch($object->fk_user_author);
    -    			$emailTo = $destinataire->email;
    -
    -    			// FROM
    -    			$expediteur = new User($db);
    -    			$expediteur->fetch($object->fk_user_cancel);
    -    			$emailFrom = $expediteur->email;
    -
    -    			if ($emailFrom && $emailTo)
    -    			{
    -    			    $filename=array(); $filedir=array(); $mimetype=array();
    -
    -    			    // SUBJECT
    -    				$subject = $langs->transnoentities("ExpenseReportCanceled");
    -
    -    				// CONTENT
    -    				$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    -    				$message = $langs->transnoentities("ExpenseReportCanceledMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $_POST['detail_cancel'], $link);
    -
    -    				// Rebuilt pdf
    -    				/*
    -    				$object->setDocModel($user,"");
    -    				$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
    -
    -    				if($resultPDF
    -    				{
    -    					// ATTACHMENT
    -    					$filename=array(); $filedir=array(); $mimetype=array();
    -    					array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
    -    					array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
    -    					array_push($mimetype,"application/pdf");
    -    				}
    -    				*/
    -
    -        			// PREPARE SEND
    -        			$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    -
    -        			if ($mailfile)
    -        			{
    -        				// SEND
    -        				$result=$mailfile->sendfile();
    -        				if ($result)
    -        				{
    -        					$mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($emailFrom,2),$mailfile->getValidAddress($emailTo,2));
    -        					setEventMessages($mesg, null, 'mesgs');
    -        					header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
    -        					exit;
    -        				}
    -        				else
    -        				{
    -        					$langs->load("other");
    -        					if ($mailfile->error)
    -        					{
    -        						$mesg='';
    -        						$mesg.=$langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
    -        						$mesg.='<br>'.$mailfile->error;
    -        						setEventMessages($mesg, null, 'errors');
    -        					}
    -        					else
    -        					{
    -        						setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
    -        					}
    -        				}
    -        			}
    -        			else
    -        			{
    -        				setEventMessages($mailfile->error,$mailfile->errors,'errors');
    -        				$action='';
    -        			}
    -    			}
    -    			else
    -    			{
    -    			    setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
    -    			    $action='';
    -    			}
    -    		}
    -    		else
    -    		{
    -    			setEventMessages($langs->trans("FailedToSetToCancel"), null, 'warnings');
    -    			$action='';
    -    		}
    +    		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Comment")), null, 'errors');
         	}
         	else
         	{
    -    		setEventMessages($object->error, $object->errors, 'errors');
    +	    	$object = new ExpenseReport($db);
    +	    	$object->fetch($id);
    +
    +	    	if ($user->id == $object->fk_user_valid || $user->id == $object->fk_user_author)
    +	    	{
    +	    		$result = $object->set_cancel($user, GETPOST('detail_cancel', 'alpha'));
    +
    +	    		if ($result > 0)
    +	    		{
    +	    			// Define output language
    +	    			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
    +	    			{
    +	    				$outputlangs = $langs;
    +	    				$newlang = '';
    +	    				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
    +	    				if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
    +	    				if (! empty($newlang)) {
    +	    					$outputlangs = new Translate("", $conf);
    +	    					$outputlangs->setDefaultLang($newlang);
    +	    				}
    +	    				$model=$object->modelpdf;
    +	    				$ret = $object->fetch($id); // Reload to get new records
    +
    +	    				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
    +	    			}
    +	    		}
    +
    +	    		if ($result > 0)
    +	    		{
    +	    			// Send mail
    +
    +	    			// TO
    +	    			$destinataire = new User($db);
    +	    			$destinataire->fetch($object->fk_user_author);
    +	    			$emailTo = $destinataire->email;
    +
    +	    			// FROM
    +	    			$expediteur = new User($db);
    +	    			$expediteur->fetch($object->fk_user_cancel);
    +	    			$emailFrom = $expediteur->email;
    +
    +	    			if ($emailFrom && $emailTo)
    +	    			{
    +	    			    $filename=array(); $filedir=array(); $mimetype=array();
    +
    +	    			    // SUBJECT
    +	    			    $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +	    			    if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +	    			    $subject = $societeName." - ".$langs->transnoentities("ExpenseReportCanceled");
    +
    +	    				// CONTENT
    +	    				$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    +	    				$message = $langs->transnoentities("ExpenseReportCanceledMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), GETPOST('detail_cancel','alpha'), $link);
    +
    +	    				// Rebuilt pdf
    +	    				/*
    +	    				$object->setDocModel($user,"");
    +	    				$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
    +
    +	    				if($resultPDF
    +	    				{
    +	    					// ATTACHMENT
    +	    					$filename=array(); $filedir=array(); $mimetype=array();
    +	    					array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
    +	    					array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
    +	    					array_push($mimetype,"application/pdf");
    +	    				}
    +	    				*/
    +
    +	        			// PREPARE SEND
    +	        			$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
    +
    +	        			if ($mailfile)
    +	        			{
    +	        				// SEND
    +	        				$result=$mailfile->sendfile();
    +	        				if ($result)
    +	        				{
    +	        					$mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($emailFrom,2),$mailfile->getValidAddress($emailTo,2));
    +	        					setEventMessages($mesg, null, 'mesgs');
    +	        					header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
    +	        					exit;
    +	        				}
    +	        				else
    +	        				{
    +	        					$langs->load("other");
    +	        					if ($mailfile->error)
    +	        					{
    +	        						$mesg='';
    +	        						$mesg.=$langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
    +	        						$mesg.='<br>'.$mailfile->error;
    +	        						setEventMessages($mesg, null, 'errors');
    +	        					}
    +	        					else
    +	        					{
    +	        						setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
    +	        					}
    +	        				}
    +	        			}
    +	        			else
    +	        			{
    +	        				setEventMessages($mailfile->error,$mailfile->errors,'errors');
    +	        				$action='';
    +	        			}
    +	    			}
    +	    			else
    +	    			{
    +	    			    setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
    +	    			    $action='';
    +	    			}
    +	    		}
    +	    		else
    +	    		{
    +	    			setEventMessages($langs->trans("FailedToSetToCancel"), null, 'warnings');
    +	    			$action='';
    +	    		}
    +	    	}
    +	    	else
    +	    	{
    +	    		setEventMessages($object->error, $object->errors, 'errors');
    +	    	}
         	}
         }
     
    @@ -1000,25 +1023,21 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
         		    // SUBJECT
    -    			$subject = $langs->transnoentities("ExpenseReportPaid");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportPaid");
     
         			// CONTENT
         			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
         			$message = $langs->transnoentities("ExpenseReportPaidMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link);
     
    -        		// CONTENT
    -        		$message = "Bonjour {$destinataire->firstname},\n\n";
    -        		$message.= "Votre note de frais \"{$object->ref}\" vient d'être payée.\n";
    -        		$message.= "- Payeur : {$expediteur->firstname} {$expediteur->lastname}\n";
    -        		$message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n";
    -        		$message.= "Bien cordialement,\n' SI";
    -
             		// Generate pdf before attachment
             		$object->setDocModel($user,"");
             		$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
     
             		// PREPARE SEND
    -        		$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +        		$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
             		if ($mailfile)
             		{
    @@ -1159,7 +1178,6 @@ if (empty($reshook))
     				unset($fk_projet);
     
     				unset($date);
    -
     			} else {
     				setEventMessages($object->error, $object->errors, 'errors');
     			}
    @@ -1211,7 +1229,7 @@ if (empty($reshook))
         	}
         }
     
    -    if ($action == "updateligne" && $user->rights->expensereport->creer)
    +    if ($action == "updateline" && $user->rights->expensereport->creer)
         {
         	$object = new ExpenseReport($db);
         	$object->fetch($id);
    @@ -1335,7 +1353,7 @@ if ($action == 'create')
     	print '<tr>';
     	print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("DateStart").'</td>';
     	print '<td>';
    -	$form->select_date($date_start?$date_start:-1,'date_debut',0,0,0,'',1,1);
    +	print $form->selectDate($date_start?$date_start:-1, 'date_debut', 0, 0, 0, '', 1, 1);
     	print '</td>';
     	print '</tr>';
     
    @@ -1343,7 +1361,7 @@ if ($action == 'create')
     	print '<tr>';
     	print '<td class="fieldrequired">'.$langs->trans("DateEnd").'</td>';
     	print '<td>';
    -	$form->select_date($date_end?$date_end:-1,'date_fin',0,0,0,'',1,1);
    +	print $form->selectDate($date_end?$date_end:-1, 'date_fin', 0, 0, 0, '', 1, 1);
     	print '</td>';
     	print '</tr>';
     
    @@ -1450,8 +1468,9 @@ else
     					print $langs->trans('NotUserRightToView');
     					print '</div>';
     
    -					llxFooter();
    -					$db->close();
    +					// End of page
    +                    llxFooter();
    +                    $db->close();
     
     					exit;
     				}
    @@ -1499,13 +1518,13 @@ else
     				print '<tr>';
     				print '<td>'.$langs->trans("DateStart").'</td>';
     				print '<td>';
    -				$form->select_date($object->date_debut,'date_debut');
    +				print $form->selectDate($object->date_debut, 'date_debut');
     				print '</td>';
     				print '</tr>';
     				print '<tr>';
     				print '<td>'.$langs->trans("DateEnd").'</td>';
     				print '<td>';
    -				$form->select_date($object->date_fin,'date_fin');
    +				print $form->selectDate($object->date_fin, 'date_fin');
     				print '</td>';
     				print '</tr>';
     
    @@ -1550,7 +1569,6 @@ else
     					$userfee->fetch($user->id);
     					print $userfee->getNomUrl(-1);
     					print '</td></tr>';
    -
     				}
     
     				// Other attributes
    @@ -1587,49 +1605,49 @@ else
     
     				if ($action == 'save')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_validate","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_validate","","",1);
     				}
     
     				if ($action == 'save_from_refuse')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1);
     				}
     
     				if ($action == 'delete')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1);
     				}
     
     				if ($action == 'validate')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_approve","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_approve","","",1);
     				}
     
     				if ($action == 'paid')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1);
     				}
     
     				if ($action == 'cancel')
     				{
    -					$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_cancel",'size'=>"50",'value'=>""));
    -					$formconfirm=$form->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("Cancel"),"","confirm_cancel",$array_input,"",1);
    +					$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>'<strong>'.$langs->trans("Comment").'</strong>','name'=>"detail_cancel",'size'=>"50",'value'=>""));
    +					$formconfirm=$form->formconfirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("Cancel"),"","confirm_cancel",$array_input,"",1);
     				}
     
     				if ($action == 'brouillonner')
     				{
    -				    $formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("BrouillonnerTrip"),$langs->trans("ConfirmBrouillonnerTrip"),"confirm_brouillonner","","",1);
    +				    $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("BrouillonnerTrip"),$langs->trans("ConfirmBrouillonnerTrip"),"confirm_brouillonner","","",1);
     				}
     
     				if ($action == 'refuse')		// Deny
     				{
     					$array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_refuse",'size'=>"50",'value'=>""));
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("Deny"),'',"confirm_refuse",$array_input,"yes",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("Deny"),'',"confirm_refuse",$array_input,"yes",1);
     				}
     
     				if ($action == 'delete_line')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid','int'),$langs->trans("DeleteLine"),$langs->trans("ConfirmDeleteLine"),"confirm_delete_line",'','yes',1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid','int'),$langs->trans("DeleteLine"),$langs->trans("ConfirmDeleteLine"),"confirm_delete_line",'','yes',1);
     				}
     
     				// Print form confirm
    @@ -1962,7 +1980,7 @@ else
     
     				print '<div style="clear: both;"></div>';
     
    -				$actiontouse='updateligne';
    +				$actiontouse='updateline';
     				if (($object->fk_statut==0 || $object->fk_statut==99) && $action != 'editline') $actiontouse='addline';
     
     				print '<form name="expensereport" action="'.$_SERVER["PHP_SELF"].'" method="post">';
    @@ -2077,7 +2095,7 @@ else
     
     								// Select date
     								print '<td class="center">';
    -								$form->select_date($line->date,'date');
    +								print $form->selectDate($line->date,'date');
     								print '</td>';
     
     								// Select project
    @@ -2160,7 +2178,7 @@ else
     
     					// Select date
     					print '<td align="center">';
    -					$form->select_date($date?$date:-1,'date');
    +					print $form->selectDate($date?$date:-1, 'date');
     					print '</td>';
     
     					// Select project
    @@ -2223,17 +2241,13 @@ else
     				print '</form>';
     
     				dol_fiche_end();
    -
     			} // end edit or not edit
    -
     		}	// end of if result
     		else
     		{
     			dol_print_error($db);
     		}
    -
     	} //fin si id > 0
    -
     }
     
     /*
    @@ -2447,7 +2461,6 @@ if ($action != 'presend')
     	$somethingshown = $formactions->showactions($object, 'expensereport', null);
     
     	print '</div></div></div>';
    -
     }
     
     // Presend form
    diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php
    index 726aa158413..e6475665fb8 100644
    --- a/htdocs/expensereport/class/api_expensereports.class.php
    +++ b/htdocs/expensereport/class/api_expensereports.class.php
    @@ -94,7 +94,8 @@ class ExpenseReports extends DolibarrApi
          * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
          * @return  array               Array of Expense Report objects
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -195,7 +196,8 @@ class ExpenseReports extends DolibarrApi
          * @return int
          */
     /*
    -    function getLines($id) {
    +    function getLines($id)
    +    {
           if(! DolibarrApiAccess::$user->rights->expensereport->lire) {
     		  	throw new RestException(401);
     		  }
    @@ -228,7 +230,8 @@ class ExpenseReports extends DolibarrApi
          * @return int
          */
     /*
    -    function postLine($id, $request_data = null) {
    +    function postLine($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -290,7 +293,8 @@ class ExpenseReports extends DolibarrApi
          * @return object
          */
         /*
    -    function putLine($id, $lineid, $request_data = null) {
    +    function putLine($id, $lineid, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -348,7 +352,8 @@ class ExpenseReports extends DolibarrApi
          * @return int
          */
         /*
    -    function deleteLine($id, $lineid) {
    +    function deleteLine($id, $lineid)
    +    {
           if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -380,7 +385,8 @@ class ExpenseReports extends DolibarrApi
          *
          * @return int
          */
    -    function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->expensereport->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -439,7 +445,6 @@ class ExpenseReports extends DolibarrApi
                     'message' => 'Expense Report deleted'
                 )
             );
    -
         }
     
         /**
    @@ -490,7 +495,8 @@ class ExpenseReports extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
         	$object = parent::_cleanObjectDatas($object);
     
    @@ -516,7 +522,6 @@ class ExpenseReports extends DolibarrApi
                 if (!isset($data[$field]))
                     throw new RestException(400, "$field field missing");
                 $expensereport[$field] = $data[$field];
    -
             }
             return $expensereport;
         }
    diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php
    index 7ec20f00b61..2b343dd0074 100644
    --- a/htdocs/expensereport/class/expensereport.class.php
    +++ b/htdocs/expensereport/class/expensereport.class.php
    @@ -33,8 +33,16 @@ require_once DOL_DOCUMENT_ROOT .'/expensereport/class/expensereport_rule.class.p
      */
     class ExpenseReport extends CommonObject
     {
    -    var $element='expensereport';
    -    var $table_element='expensereport';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='expensereport';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='expensereport';
    +
         var $table_element_line = 'expensereport_det';
         var $fk_element = 'fk_expensereport';
         var $picto = 'trip';
    @@ -96,8 +104,8 @@ class ExpenseReport extends CommonObject
             END ACTIONS
         */
     
    -   /**
    -	 * Draft
    +    /**
    +	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
     
    @@ -140,8 +148,6 @@ class ExpenseReport extends CommonObject
             $this->statuts_short = array(0 => 'Draft', 2 => 'Validated', 4 => 'Canceled', 5 => 'Approved', 6 => 'Paid', 99 => 'Refused');
             $this->statuts = array(0 => 'Draft', 2 => 'ValidatedWaitingApproval', 4 => 'Canceled', 5 => 'Approved', 6 => 'Paid', 99 => 'Refused');
             $this->statuts_logo = array(0 => 'statut0', 2 => 'statut1', 4 => 'statut5', 5 => 'statut3', 6 => 'statut6', 99 => 'statut5');
    -
    -        return 1;
         }
     
         /**
    @@ -539,6 +545,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Classify the expense report as paid
          *
    @@ -549,6 +556,7 @@ class ExpenseReport extends CommonObject
          */
         function set_paid($id, $fuser, $notrigger = 0)
         {
    +        // phpcs:enable
     		$error = 0;
     		$this->db->begin();
     
    @@ -610,6 +618,7 @@ class ExpenseReport extends CommonObject
             return $this->LibStatut($this->status,$mode);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Returns the label of a statut
          *
    @@ -619,27 +628,28 @@ class ExpenseReport extends CommonObject
          */
         function LibStatut($status,$mode=0)
         {
    +        // phpcs:enable
             global $langs;
     
             if ($mode == 0)
                 return $langs->transnoentities($this->statuts[$status]);
     
    -        if ($mode == 1)
    +        elseif ($mode == 1)
                 return $langs->transnoentities($this->statuts_short[$status]);
     
    -        if ($mode == 2)
    +        elseif ($mode == 2)
                 return img_picto($langs->transnoentities($this->statuts_short[$status]), $this->statuts_logo[$status]).' '.$langs->transnoentities($this->statuts_short[$status]);
     
    -        if ($mode == 3)
    +        elseif ($mode == 3)
                 return img_picto($langs->transnoentities($this->statuts_short[$status]), $this->statuts_logo[$status]);
     
    -        if ($mode == 4)
    +        elseif ($mode == 4)
                 return img_picto($langs->transnoentities($this->statuts_short[$status]),$this->statuts_logo[$status]).' '.$langs->transnoentities($this->statuts[$status]);
     
    -        if ($mode == 5)
    +        elseif ($mode == 5)
                 return '<span class="hideonsmartphone">'.$langs->transnoentities($this->statuts_short[$status]).' </span>'.img_picto($langs->transnoentities($this->statuts_short[$status]),$this->statuts_logo[$status]);
     
    -        if ($mode == 6)
    +        elseif ($mode == 6)
                 return $langs->transnoentities($this->statuts[$status]).' '.img_picto($langs->transnoentities($this->statuts_short[$status]),$this->statuts_logo[$status]);
         }
     
    @@ -709,7 +719,6 @@ class ExpenseReport extends CommonObject
                         $auser->fetch($obj->fk_user_approve);
                         $this->user_approve   = $auser;
                     }
    -
                 }
                 $this->db->free($resql);
             }
    @@ -784,6 +793,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * fetch_line_by_project
          *
    @@ -793,6 +803,7 @@ class ExpenseReport extends CommonObject
          */
         function fetch_line_by_project($projectid,$user='')
         {
    +        // phpcs:enable
             global $conf,$db,$langs;
     
             $langs->load('trips');
    @@ -879,7 +890,6 @@ class ExpenseReport extends CommonObject
                     print '<td align="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_TTC).'</td>';
                     print '<td>&nbsp;</td>';
                     print '</tr>';
    -
                 }
                 else
                 {
    @@ -887,7 +897,6 @@ class ExpenseReport extends CommonObject
                     return -1;
                 }
             }
    -
         }
     
         /**
    @@ -941,6 +950,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * fetch_lines
          *
    @@ -948,6 +958,7 @@ class ExpenseReport extends CommonObject
          */
         function fetch_lines()
         {
    +        // phpcs:enable
             $this->lines=array();
     
             $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,';
    @@ -1184,6 +1195,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * set_save_from_refuse
          *
    @@ -1192,6 +1204,7 @@ class ExpenseReport extends CommonObject
          */
         function set_save_from_refuse($fuser)
         {
    +        // phpcs:enable
             global $conf,$langs;
     
             // Sélection de la date de début de la NDF
    @@ -1297,6 +1310,7 @@ class ExpenseReport extends CommonObject
          * @param User      $fuser      User
          * @param Details   $details    Details
     	 * @param int       $notrigger  Disable triggers
    +     * @return int
          */
         function setDeny($fuser,$details,$notrigger=0)
         {
    @@ -1355,6 +1369,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * set_unpaid
          *
    @@ -1364,6 +1379,7 @@ class ExpenseReport extends CommonObject
          */
         function set_unpaid($fuser, $notrigger = 0)
         {
    +        // phpcs:enable
     		$error = 0;
     
             if ($this->fk_c_deplacement_statuts != 5)
    @@ -1414,6 +1430,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * set_cancel
          *
    @@ -1424,6 +1441,7 @@ class ExpenseReport extends CommonObject
          */
         function set_cancel($fuser,$detail, $notrigger=0)
         {
    +        // phpcs:enable
     		$error = 0;
             $this->date_cancel = $this->db->idate(gmmktime());
             if ($this->fk_statut != 4)
    @@ -1598,6 +1616,7 @@ class ExpenseReport extends CommonObject
             return $result;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Update total of an expense report when you add a line.
          *
    @@ -1607,6 +1626,7 @@ class ExpenseReport extends CommonObject
          */
         function update_totaux_add($ligne_total_ht,$ligne_total_tva)
         {
    +        // phpcs:enable
             $this->total_ht = $this->total_ht + $ligne_total_ht;
             $this->total_tva = $this->total_tva + $ligne_total_tva;
             $this->total_ttc = $this->total_ht + $this->total_tva;
    @@ -1626,6 +1646,7 @@ class ExpenseReport extends CommonObject
             endif;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Update total of an expense report when you delete a line.
          *
    @@ -1635,6 +1656,7 @@ class ExpenseReport extends CommonObject
          */
         function update_totaux_del($ligne_total_ht,$ligne_total_tva)
         {
    +        // phpcs:enable
             $this->total_ht = $this->total_ht - $ligne_total_ht;
             $this->total_tva = $this->total_tva - $ligne_total_tva;
             $this->total_ttc = $this->total_ht + $this->total_tva;
    @@ -1747,8 +1769,6 @@ class ExpenseReport extends CommonObject
     			$this->error = 'ErrorExpenseNotDraft';
                 return -3;
             }
    -
    -
     	}
     
     	/**
    @@ -2043,6 +2063,7 @@ class ExpenseReport extends CommonObject
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * periode_existe
          *
    @@ -2053,6 +2074,7 @@ class ExpenseReport extends CommonObject
          */
         function periode_existe($fuser, $date_debut, $date_fin)
         {
    +        // phpcs:enable
             $sql = "SELECT rowid, date_debut, date_fin";
             $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element;
             $sql.= " WHERE fk_user_author = '{$fuser->id}'";
    @@ -2099,6 +2121,7 @@ class ExpenseReport extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Return list of people with permission to validate expense reports.
          * Search for permission "approve expense report"
    @@ -2107,6 +2130,7 @@ class ExpenseReport extends CommonObject
          */
         function fetch_users_approver_expensereport()
         {
    +        // phpcs:enable
             $users_validator=array();
     
             $sql = "SELECT DISTINCT ur.fk_user";
    @@ -2205,13 +2229,15 @@ class ExpenseReport extends CommonObject
             return $ret;
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *      Charge indicateurs this->nb pour le tableau de bord
          *
          *      @return     int         <0 if KO, >0 if OK
          */
         function load_state_board()
         {
    +        // phpcs:enable
             global $conf;
     
             $this->nb=array();
    @@ -2239,6 +2265,7 @@ class ExpenseReport extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
    @@ -2248,6 +2275,7 @@ class ExpenseReport extends CommonObject
          */
         function load_board($user, $option='topay')
         {
    +        // phpcs:enable
             global $conf, $langs;
     
             if ($user->societe_id) return -1;   // protection pour eviter appel par utilisateur externe
    @@ -2368,7 +2396,6 @@ class ExpenseReport extends CommonObject
         	}
         	return 0;
         }
    -
     }
     
     
    @@ -2377,25 +2404,51 @@ class ExpenseReport extends CommonObject
      */
     class ExpenseReportLine
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    var $rowid;
    -    var $comments;
    -    var $qty;
    -    var $value_unit;
    -    var $date;
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -    var $fk_c_type_fees;
    -    var $fk_c_exp_tax_cat;
    -    var $fk_projet;
    -    var $fk_expensereport;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $rowid;
     
    -    var $type_fees_code;
    -    var $type_fees_libelle;
    +    public $comments;
    +    public $qty;
    +    public $value_unit;
    +    public $date;
     
    -    var $projet_ref;
    -    var $projet_title;
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_c_type_fees;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_c_exp_tax_cat;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_projet;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_expensereport;
    +
    +    public $type_fees_code;
    +    public $type_fees_libelle;
    +
    +    public $projet_ref;
    +    public $projet_title;
     
         var $vatrate;
         var $total_ht;
    @@ -2671,6 +2724,7 @@ class ExpenseReportLine
     }
     
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *    Retourne la liste deroulante des differents etats d'une note de frais.
      *    Les valeurs de la liste sont les id de la table c_expensereport_statuts
    @@ -2683,6 +2737,7 @@ class ExpenseReportLine
      */
     function select_expensereport_statut($selected='',$htmlname='fk_statut',$useempty=1, $useshortlabel=0)
     {
    +    // phpcs:enable
         global $db, $langs;
     
         $tmpep=new ExpenseReport($db);
    @@ -2707,6 +2762,7 @@ function select_expensereport_statut($selected='',$htmlname='fk_statut',$useempt
         print '</select>';
     }
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     /**
      *  Return list of types of notes with select value = id
      *
    @@ -2718,6 +2774,7 @@ function select_expensereport_statut($selected='',$htmlname='fk_statut',$useempt
      */
     function select_type_fees_id($selected='',$htmlname='type',$showempty=0, $active=1)
     {
    +    // phpcs:enable
         global $db,$langs,$user;
         $langs->load("trips");
     
    diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php
    index a93d4e9062c..9eaa8970a5b 100644
    --- a/htdocs/expensereport/class/expensereport_ik.class.php
    +++ b/htdocs/expensereport/class/expensereport_ik.class.php
    @@ -29,8 +29,19 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php';
      */
     class ExpenseReportIk extends CoreObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='expenseik';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='expensereport_ik';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_expense_ik';
     
     	/**
    @@ -120,8 +131,15 @@ class ExpenseReportIk extends CoreObject
     		return $categories;
     	}
     
    -	public static function getRangeByUser(User $userauthor, $fk_c_exp_tax_cat)
    -	{
    +    /**
    +     * Return an array of ranges for a user
    +     *
    +     * @param User  $userauthor         user author id
    +     * @param int   $fk_c_exp_tax_cat   category
    +     * @return boolean|array
    +     */
    +    public static function getRangeByUser(User $userauthor, $fk_c_exp_tax_cat)
    +    {
     		$default_range = (int) $userauthor->default_range; // if not defined, then 0
     		$ranges = self::getRangesByCategory($fk_c_exp_tax_cat);
     
    diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php
    index 11bc480bf4f..6d2a99d2101 100644
    --- a/htdocs/expensereport/class/expensereport_rule.class.php
    +++ b/htdocs/expensereport/class/expensereport_rule.class.php
    @@ -29,8 +29,19 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/coreobject.class.php';
      */
     class ExpenseReportRule extends CoreObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='expenserule';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='expensereport_rules';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_expense_rule';
     
     	/**
    diff --git a/htdocs/expensereport/class/expensereportstats.class.php b/htdocs/expensereport/class/expensereportstats.class.php
    index 07396663f42..bc306d27e4b 100644
    --- a/htdocs/expensereport/class/expensereportstats.class.php
    +++ b/htdocs/expensereport/class/expensereportstats.class.php
    @@ -22,15 +22,18 @@
      *       \ingroup    expensereport
      *       \brief      Fichier de la classe de gestion des stats des expensereport et notes de frais
      */
    -include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php';
    -include_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php';
     
     /**
      *  Classe permettant la gestion des stats des expensereports et notes de frais
      */
     class ExpenseReportStats extends Stats
     {
    -    public $table_element;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element;
     
         var $socid;
         var $userid;
    diff --git a/htdocs/expensereport/class/paymentexpensereport.class.php b/htdocs/expensereport/class/paymentexpensereport.class.php
    index 0634ca16b7a..605affed253 100644
    --- a/htdocs/expensereport/class/paymentexpensereport.class.php
    +++ b/htdocs/expensereport/class/paymentexpensereport.class.php
    @@ -30,26 +30,62 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class PaymentExpenseReport extends CommonObject
     {
    -	public $element='payment_expensereport';			//!< Id that identify managed objects
    -	public $table_element='payment_expensereport';	//!< Name of table without prefix where object is stored
    -    public $picto = 'payment';
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='payment_expensereport';
     
    -	var $rowid;
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='payment_expensereport';
     
    -	var $fk_expensereport;
    -	var $datec='';
    -	var $tms='';
    -	var $datep='';
    -    var $amount;            // Total amount of payment
    -    var $amounts=array();   // Array of amounts
    -	var $fk_typepayment;
    -	var $num_payment;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    -        //Unknow field
    -        var $chid;
    -        var $total;
    +    /**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
    +	public $picto = 'payment';
    +
    +	/**
    +	 * @var int ID
    +	 */
    +	public $rowid;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_expensereport;
    +
    +	public $datec='';
    +	public $tms='';
    +	public $datep='';
    +    public $amount;            // Total amount of payment
    +    public $amounts=array();   // Array of amounts
    +
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_typepayment;
    +
    +	public $num_payment;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_modif;
    +
    +    //Unknow field
    +    public $chid;
    +    public $total;
     
     	/**
     	 *	Constructor
    @@ -129,7 +165,6 @@ class PaymentExpenseReport extends CommonObject
     			{
     				$error++;
     			}
    -
     		}
     
     		if ($totalamount != 0 && ! $error)
    @@ -240,7 +275,6 @@ class PaymentExpenseReport extends CommonObject
     		if (isset($this->fk_user_modif))	$this->fk_user_modif=trim($this->fk_user_modif);
     
     
    -
     		// Check parameters
     		// Put here code to add control on parameters values
     
    @@ -443,15 +477,17 @@ class PaymentExpenseReport extends CommonObject
     	    return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    -	 *  @param	int		$statut        	Id statut
    +	 *  @param  int		$statut        	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 			       	Libelle du statut
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     	    global $langs;
     
     	    return '';
    @@ -480,8 +516,6 @@ class PaymentExpenseReport extends CommonObject
     		$this->fk_bank='';
     		$this->fk_user_creat='';
     		$this->fk_user_modif='';
    -
    -
     	}
     
     
    @@ -505,7 +539,7 @@ class PaymentExpenseReport extends CommonObject
     
             if (! empty($conf->banque->enabled))
             {
    -            require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
    +            include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     
                 $acc = new Account($this->db);
                 $acc->fetch($accountid);
    @@ -598,6 +632,7 @@ class PaymentExpenseReport extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update link between the expense report payment and the generated line in llx_bank
     	 *
    @@ -606,6 +641,7 @@ class PaymentExpenseReport extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = "UPDATE ".MAIN_DB_PREFIX."payment_expensereport SET fk_bank = ".$id_bank." WHERE rowid = ".$this->id;
     
     		dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG);
    diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php
    index f0d61d0f80d..6cfb3a2f7bc 100644
    --- a/htdocs/expensereport/document.php
    +++ b/htdocs/expensereport/document.php
    @@ -103,7 +103,7 @@ if ($object->id)
     	dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -132,13 +132,12 @@ if ($object->id)
         $permtoedit = $user->rights->expensereport->creer;
         $param = '&id=' . $object->id;
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/export_csv.php b/htdocs/expensereport/export_csv.php
    index 4bc461b4d13..3a104ca77b4 100644
    --- a/htdocs/expensereport/export_csv.php
    +++ b/htdocs/expensereport/export_csv.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2004-2011	Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -59,7 +60,6 @@ if($num < 1) {
        $insert.= ")";
     
        $req = $db->query($insert);
    -
     }
     
     
    @@ -114,7 +114,7 @@ if (isset($_POST['action']))
     {
     	if($_POST['action'] == 'export')
     	{
    -		$select_date = $_POST['annee'].'-'.$_POST['mois'];
    +		$dateselected = $_POST['annee'].'-'.$_POST['mois'];
     
     		//var_dump($conf->expensereport->dir_output.'/export/');
     		if (!file_exists($conf->expensereport->dir_output.'/export/'))
    @@ -122,7 +122,7 @@ if (isset($_POST['action']))
     			dol_mkdir($conf->expensereport->dir_output.'/export/');
     		}
     
    -		$dir = $conf->expensereport->dir_output.'/export/expensereport-'.$select_date.'.csv';
    +		$dir = $conf->expensereport->dir_output.'/export/expensereport-'.$dateselected.'.csv';
     		$outputlangs = $langs;
     		$outputlangs->charset_output = 'UTF-8';
     
    @@ -175,7 +175,6 @@ if (isset($_POST['action']))
     						$ligne.= "--->, {$objet2->rowid}, {$objet2->libelle}, {$objet2->comments}, {$objet2->total_ht}, {$objet2->total_tva}, {$objet2->total_ttc}\n";
     					}
     				}
    -
     			}
     
     			$ligne = $outputlangs->convToOutputCharset($ligne);
    @@ -183,18 +182,16 @@ if (isset($_POST['action']))
     			fwrite($open,$ligne);
     			fclose($open);
     
    -			print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart=expensereport&file=export%2Fexpensereport-'.$select_date.'.csv" target="_blank">Télécharger le fichier expensereport-'.$select_date.'.csv</a>';
    -
    +			print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart=expensereport&file=export%2Fexpensereport-'.$dateselected.'.csv" target="_blank">Télécharger le fichier expensereport-'.$dateselected.'.csv</a>';
     		} else {
     
     			print '<b>'.$langs->trans('NoTripsToExportCSV').'</b>';
    -
     		}
     	}
     }
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php
    index 0d988e4850d..9a947b8596e 100644
    --- a/htdocs/expensereport/index.php
    +++ b/htdocs/expensereport/index.php
    @@ -219,7 +219,6 @@ if ($result)
     
                 $i++;
             }
    -
         }
         else
         {
    @@ -231,6 +230,6 @@ else dol_print_error($db);
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php
    index 6babfcd647c..67f70f3a984 100644
    --- a/htdocs/expensereport/info.php
    +++ b/htdocs/expensereport/info.php
    @@ -79,6 +79,6 @@ if ($id > 0 || ! empty($ref))
         dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php
    index e576889d363..d328cd21de2 100644
    --- a/htdocs/expensereport/list.php
    +++ b/htdocs/expensereport/list.php
    @@ -26,7 +26,7 @@
      *		\brief      list of expense reports
      */
     
    -require "../main.inc.php";
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
    @@ -861,7 +861,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/note.php b/htdocs/expensereport/note.php
    index 7eb48443901..deb38abe8d6 100644
    --- a/htdocs/expensereport/note.php
    +++ b/htdocs/expensereport/note.php
    @@ -56,7 +56,7 @@ $permissionnote=$user->rights->expensereport->creer;	// Used by the include of a
      * Actions
      */
     
    -include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php';	// Must be include, not includ_once
    +include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php';	// Must be include, not include_once
     
     
     /*
    @@ -97,6 +97,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/expensereport/payment/card.php b/htdocs/expensereport/payment/card.php
    index 29ac7e38862..f75a0f8bb31 100644
    --- a/htdocs/expensereport/payment/card.php
    +++ b/htdocs/expensereport/payment/card.php
    @@ -129,7 +129,6 @@ dol_fiche_head($head, 'payment', $langs->trans("ExpenseReportPayment"), -1, 'pay
     if ($action == 'delete')
     {
     	print $form->formconfirm('card.php?id='.$object->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete','',0,2);
    -
     }
     
     /*
    @@ -139,7 +138,6 @@ if ($action == 'valide')
     {
     	$facid = $_GET['facid'];
     	print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;facid='.$facid, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide','',0,2);
    -
     }
     
     $linkback = '';
    @@ -313,6 +311,6 @@ if ($action == '')
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/expensereport/payment/info.php b/htdocs/expensereport/payment/info.php
    index 97098ef2340..6c7f8dd99c6 100644
    --- a/htdocs/expensereport/payment/info.php
    +++ b/htdocs/expensereport/payment/info.php
    @@ -77,5 +77,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php
    index 23959c06e67..046bb522ae2 100644
    --- a/htdocs/expensereport/payment/payment.php
    +++ b/htdocs/expensereport/payment/payment.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2015       Alexandre Spangaro	 <aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2015       Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2015       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2015       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -149,7 +150,6 @@ if ($action == 'add_payment')
                             $error++;
                         }
                     }
    -
                 }
     
         	    if (! $error)
    @@ -235,7 +235,7 @@ if ($action == 'create' || empty($action))
         print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Date").'</td><td colspan="2">';
     	$datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]);
     	$datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaid):0;
    -	$form->select_date($datepayment,'','','','',"add_payment",1,1);
    +	print $form->selectDate($datepayment, '', '', '', '', "add_payment", 1, 1);
     	print "</td>";
     	print '</tr>';
     
    @@ -336,5 +336,6 @@ if ($action == 'create' || empty($action))
     	print "</form>\n";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php
    index b4f0327cd39..e53757be1db 100644
    --- a/htdocs/expensereport/stats/index.php
    +++ b/htdocs/expensereport/stats/index.php
    @@ -246,6 +246,7 @@ print '</table>';
     print '</form>';
     print '<br><br>';
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -281,7 +282,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    -
    +print '<div>';
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     
    @@ -305,7 +306,6 @@ print '<div style="clear:both"></div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php
    index 050318944d6..46d21eba031 100644
    --- a/htdocs/exports/class/export.class.php
    +++ b/htdocs/exports/class/export.class.php
    @@ -30,7 +30,10 @@
      */
     class Export
     {
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	var $array_export_code=array();             // Tableau de "idmodule_numlot"
     	var $array_export_module=array();           // Tableau de "nom de modules"
    @@ -67,6 +70,7 @@ class Export
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Load an exportable dataset
     	 *
    @@ -76,6 +80,7 @@ class Export
     	 */
     	function load_arrays($user,$filter='')
     	{
    +        // phpcs:enable
     		global $langs,$conf,$mysoc;
     
     		dol_syslog(get_class($this)."::load_arrays user=".$user->id." filter=".$filter);
    @@ -204,6 +209,7 @@ class Export
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Build the sql export request.
     	 *      Arrays this->array_export_xxx are already loaded for required datatoexport
    @@ -215,6 +221,7 @@ class Export
     	 */
     	function build_sql($indice, $array_selected, $array_filterValue)
     	{
    +        // phpcs:enable
     		// Build the sql request
     		$sql=$this->array_export_sql_start[$indice];
     		$i=0;
    @@ -266,6 +273,7 @@ class Export
     		return $sql;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Build the conditionnal string from filter the query
     	 *
    @@ -276,6 +284,7 @@ class Export
     	 */
     	function build_filterQuery($TypeField, $NameField, $ValueField)
     	{
    +        // phpcs:enable
     		//print $TypeField." ".$NameField." ".$ValueField;
     		$InfoFieldList = explode(":", $TypeField);
     		// build the input field on depend of the type of file
    @@ -359,6 +368,7 @@ class Export
     		return $Condition;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Build an input field used to filter the query
     	 *
    @@ -369,6 +379,7 @@ class Export
     	 */
     	function build_filterField($TypeField, $NameField, $ValueField)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$szFilterField='';
    @@ -507,6 +518,7 @@ class Export
     		return $szMsg;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Build export file.
     	 *      File is built into directory $conf->export->dir_temp.'/'.$user->id
    @@ -522,6 +534,7 @@ class Export
     	 */
     	function build_file($user, $model, $datatoexport, $array_selected, $array_filterValue, $sqlquery = '')
      	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$indice=0;
    @@ -817,6 +830,7 @@ class Export
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Output list all export models
     	 *  TODO Move this into a class htmlxxx.class.php
    @@ -825,6 +839,7 @@ class Export
     	 */
     	function list_export_model()
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$sql = "SELECT em.rowid, em.field, em.label, em.type, em.filter";
    @@ -871,6 +886,4 @@ class Export
     			dol_print_error($this->db);
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php
    index 6d65418be3c..f0060ffd029 100644
    --- a/htdocs/exports/export.php
    +++ b/htdocs/exports/export.php
    @@ -208,7 +208,6 @@ if ($action=='selectfield')     // Selection of field at step 2
     
     	    setEventMessages($warnings, null, 'warnings');
         }
    -
     }
     if ($action=='unselectfield')
     {
    @@ -683,7 +682,6 @@ if ($step == 2 && $datatoexport)
     	}
     
         print '</div>';
    -
     }
     
     if ($step == 3 && $datatoexport)
    @@ -858,7 +856,6 @@ if ($step == 3 && $datatoexport)
     	// il n'est pas obligatoire de filtrer les champs
     	print '<a class="butAction" href="javascript:FilterField.submit();">'.$langs->trans("NextStep").'</a>';
     	print '</div>';
    -
     }
     
     if ($step == 4 && $datatoexport)
    @@ -1162,7 +1159,6 @@ if ($step == 5 && $datatoexport)
         if ($action == 'remove_file')
         {
         	print $form->formconfirm($_SERVER["PHP_SELF"].'?step=5&datatoexport='.$datatoexport.'&file='.urlencode(GETPOST("file")), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
    -
         }
     
         print '<div class="fichecenter">';
    diff --git a/htdocs/exports/index.php b/htdocs/exports/index.php
    index bccf25f1be8..81027882b6b 100644
    --- a/htdocs/exports/index.php
    +++ b/htdocs/exports/index.php
    @@ -145,7 +145,6 @@ print '</table>';
     
     //print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/externalsite/frametop.php b/htdocs/externalsite/frametop.php
    index 5abc4e840a3..ee746d745cc 100644
    --- a/htdocs/externalsite/frametop.php
    +++ b/htdocs/externalsite/frametop.php
    @@ -22,7 +22,7 @@
      *		\brief      Top frame to show external web application
      */
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     
     // Load translation files required by the page
     $langs->load("externalsite");
    diff --git a/htdocs/fichinter/admin/fichinter_extrafields.php b/htdocs/fichinter/admin/fichinter_extrafields.php
    index 40fd63d7639..bcda9b4847b 100644
    --- a/htdocs/fichinter/admin/fichinter_extrafields.php
    +++ b/htdocs/fichinter/admin/fichinter_extrafields.php
    @@ -80,7 +80,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -93,8 +93,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    diff --git a/htdocs/fichinter/admin/fichinterdet_extrafields.php b/htdocs/fichinter/admin/fichinterdet_extrafields.php
    index eab70d5d585..8046ef41a18 100644
    --- a/htdocs/fichinter/admin/fichinterdet_extrafields.php
    +++ b/htdocs/fichinter/admin/fichinterdet_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,8 +94,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    diff --git a/htdocs/fichinter/card-rec.php b/htdocs/fichinter/card-rec.php
    new file mode 100644
    index 00000000000..0113f7fbea6
    --- /dev/null
    +++ b/htdocs/fichinter/card-rec.php
    @@ -0,0 +1,959 @@
    +<?php
    +/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012 Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2013	   Florian Henry		<florian.henry@open-concept.pro>
    + * Copyright (C) 2013	   Juanjo Menent		<jmenent@2byte.es>
    + * Copyright (C) 2015	   Jean-François Ferry	<jfefe@aternatik.fr>
    + * Copyright (C) 2012	   Cedric Salvador		<csalvador@gpcsolutions.fr>
    + * Copyright (C) 2015	   Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2016-2018 Charlie Benke		<charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *	\file	   fichinter/card-rec.php
    + *	\ingroup	fichinter
    + *	\brief	  Page to show predefined fichinter
    + */
    +
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinterrec.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php';
    +
    +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    +if (! empty($conf->projet->enabled)) {
    +	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
    +}
    +if (! empty($conf->contrat->enabled)) {
    +	require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcontract.class.php';
    +}
    +
    +// Load translation files required by the page
    +$langs->loadLangs(array("interventions","admin","compta","bills"));
    +
    +// Security check
    +$id=(GETPOST('fichinterid', 'int')?GETPOST('fichinterid', 'int'):GETPOST('id', 'int'));
    +$action=GETPOST('action', 'alpha');
    +if ($user->societe_id) $socid=$user->societe_id;
    +$objecttype = 'fichinter_rec';
    +if ($action == "create" || $action == "add") $objecttype = '';
    +$result = restrictedArea($user, 'ficheinter', $id, $objecttype);
    +
    +if ($page == -1)
    +	$page = 0 ;
    +
    +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
    +$offset = $limit * $page ;
    +
    +if ($sortorder == "")
    +	$sortorder="DESC";
    +
    +if ($sortfield == "")
    +	$sortfield="f.datec";
    +
    +$object = new FichinterRec($db);
    +
    +
    +$arrayfields=array(
    +	'f.titre'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
    +	's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1),
    +	'f.fk_contrat'=>array('label'=>$langs->trans("Contract"), 'checked'=>1),
    +	'f.duree'=>array('label'=>$langs->trans("Duration"), 'checked'=>1),
    +	'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1),
    +	'f.frequency'=>array('label'=>$langs->trans("RecurringInvoiceTemplate"), 'checked'=>1),
    +	'f.nb_gen_done'=>array('label'=>$langs->trans("NbOfGenerationDone"), 'checked'=>1),
    +	'f.date_last_gen'=>array('label'=>$langs->trans("DateLastGeneration"), 'checked'=>1),
    +	'f.date_when'=>array('label'=>$langs->trans("NextDateToExecution"), 'checked'=>1),
    +	'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
    +	'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
    +);
    +
    +
    +/*
    + * Actions
    + */
    +
    +
    +// Create predefined intervention
    +if ($action == 'add') {
    +	if (! GETPOST('titre')) {
    +		setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Title")), null, 'errors');
    +		$action = "create";
    +		$error++;
    +	}
    +
    +	if (! GETPOST('socid')) {
    +		setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Customer")), null, 'errors');
    +		$action = "create";
    +		$error++;
    +	}
    +
    +	// gestion des fréquences et des échéances
    +	$frequency=GETPOST('frequency', 'int');
    +	$reyear=GETPOST('reyear');
    +	$remonth=GETPOST('remonth');
    +	$reday=GETPOST('reday');
    +	$rehour=GETPOST('rehour');
    +	$remin=GETPOST('remin');
    +	$nb_gen_max = (GETPOST('nb_gen_max', 'int')?GETPOST('nb_gen_max', 'int'):0);
    +	if (GETPOST('frequency')) {
    +		if (empty($reyear) || empty($remonth) || empty($reday)) {
    +			setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Date")), null, 'errors');
    +			$action = "create";
    +			$error++;
    +		}
    +		if ($nb_gen_max === '') {
    +			setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("MaxPeriodNumber")), null, 'errors');
    +			$action = "create";
    +			$error++;
    +		}
    +	}
    +
    +	if (! $error) {
    +		$object->id_origin		= $id;
    +		$object->titre			= GETPOST('titre', 'alpha');
    +		$object->description	= GETPOST('description', 'alpha');
    +		$object->socid			= GETPOST('socid', 'alpha');
    +		$object->fk_project		= GETPOST('projectid', 'int');
    +		$object->fk_contract	= GETPOST('contractid', 'int');
    +
    +		$object->frequency = $frequency;
    +		$object->unit_frequency = GETPOST('unit_frequency', 'alpha');
    +		$object->nb_gen_max = $nb_gen_max;
    +		$object->auto_validate = GETPOST('auto_validate', 'int');
    +
    +		$date_next_execution = dol_mktime($rehour, $remin, 0, $remonth, $reday, $reyear);
    +		$object->date_when = $date_next_execution;
    +
    +		if ($object->create($user) > 0) {
    +			$id = $object->id;
    +			$action = '';
    +		} else {
    +			setEventMessages($object->error, $object->errors, 'errors');
    +			$action = "create";
    +		}
    +	}
    +} elseif ($action == 'createfrommodel') {
    +	$newinter = new fichinter($db);
    +
    +	// on récupère les enregistrements
    +	$object->fetch($id);
    +
    +
    +	// on transfert les données de l'un vers l'autre
    +	if ($object->socid > 0) {
    +		$newinter->socid=$object->socid;
    +		$newinter->fk_projet=$object->fk_projet;
    +		$newinter->fk_contrat=$object->fk_contrat;
    +	} else
    +		$newinter->socid=GETPOST("socid");
    +
    +	$newinter->entity=$object->entity;
    +	$newinter->duree=$object->duree;
    +
    +	$newinter->description=$object->description;
    +	$newinter->note_private=$object->note_private;
    +	$newinter->note_public=$object->note_public;
    +
    +	// on créer un nouvelle intervention
    +	$extrafields = new ExtraFields($db);
    +	$extralabels = $extrafields->fetch_name_optionals_label($newinter->table_element);
    +	$array_options = $extrafields->getOptionalsFromPost($extralabels);
    +	$newinter->array_options = $array_options;
    +
    +	$newfichinterid = $newinter->create($user);
    +
    +	if ($newfichinterid > 0) {
    +		// on ajoute les lignes de détail ensuite
    +		foreach ($object->lines as $ficheinterligne)
    +			$newinter->addline($user, $newfichinterid, $ficheinterligne->desc, "", $ficheinterligne->duree, '');
    +
    +		// on update le nombre d'inter crée à partir du modèle
    +		$object->updateNbGenDone();
    +		//on redirige vers la fiche d'intervention nouvellement crée
    +		header('Location: '.DOL_URL_ROOT.'/fichinter/card.php?id='.$newfichinterid);
    +		exit;
    +	} else {
    +		setEventMessages($newinter->error, $newinter->errors, 'errors');
    +		$action='';
    +	}
    +} elseif ($action == 'delete' && $user->rights->ficheinter->supprimer) {
    +		// delete modele
    +	$object->fetch($id);
    +	$object->delete();
    +	$id = 0 ;
    +	header('Location: '.$_SERVER["PHP_SELF"]);
    +	exit;
    +} elseif ($action == 'setfrequency' && $user->rights->ficheinter->creer) {
    +	// Set frequency and unit frequency
    +	$object->fetch($id);
    +	$object->setFrequencyAndUnit(GETPOST('frequency', 'int'), GETPOST('unit_frequency', 'alpha'));
    +} elseif ($action == 'setdate_when' && $user->rights->ficheinter->creer) {
    +	// Set next date of execution
    +	$object->fetch($id);
    +	$date = dol_mktime(
    +					GETPOST('date_whenhour'), GETPOST('date_whenmin'), 0,
    +					GETPOST('date_whenmonth'), GETPOST('date_whenday'), GETPOST('date_whenyear')
    +	);
    +	if (!empty($date)) $object->setNextDate($date);
    +} elseif ($action == 'setnb_gen_max' && $user->rights->ficheinter->creer) {
    +// Set max period
    +	$object->fetch($id);
    +	$object->setMaxPeriod(GETPOST('nb_gen_max', 'int'));
    +}
    +
    +
    +/*
    + *	View
    + */
    +
    +llxHeader('', $langs->trans("RepeatableInterventional"), 'ch-fichinter.html#s-fac-fichinter-rec');
    +
    +$form = new Form($db);
    +$companystatic = new Societe($db);
    +if (! empty($conf->contrat->enabled))
    +	$contratstatic = new Contrat($db);
    +if (! empty($conf->projet->enabled))
    +	$projectstatic = new Project($db);
    +
    +$now = dol_now();
    +$tmparray=dol_getdate($now);
    +$today = dol_mktime(
    +				23, 59, 59,
    +				$tmparray['mon'], $tmparray['mday'], $tmparray['year']
    +);   // Today is last second of current day
    +
    +
    +
    +/*
    + * Create mode
    + */
    +if ($action == 'create') {
    +	print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'title_commercial.png');
    +
    +	$object = new Fichinter($db);   // Source invoice
    +	//$object = new Managementfichinter($db);   // Source invoice
    +
    +	if ($object->fetch($id, $ref) > 0) {
    +		print '<form action="fiche-rec.php" method="post">';
    +		print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +		print '<input type="hidden" name="action" value="add">';
    +		print '<input type="hidden" name="fichinterid" value="'.$object->id.'">';
    +
    +		dol_fiche_head();
    +
    +		$rowspan=4;
    +		if (! empty($conf->projet->enabled) && $object->fk_project > 0) $rowspan++;
    +		if (! empty($conf->contrat->enabled) && $object->fk_contrat > 0) $rowspan++;
    +
    +		print '<table class="border" width="100%">';
    +
    +		$object->fetch_thirdparty();
    +
    +		// Third party
    +		print '<tr><td>'.$langs->trans("Customer").'</td><td>';
    +		print $form->select_company($object->thirdparty->id, 'socid', '', 0, 1);
    +
    +//		.$object->thirdparty->getNomUrl(1,'customer').
    +		print '</td><td>';
    +		print $langs->trans("Comment");
    +		print '</td></tr>';
    +
    +		// Title
    +		print '<tr><td class="fieldrequired">'.$langs->trans("Title").'</td><td>';
    +		print '<input class="flat" type="text" name="titre" size="24" value="'.$_POST["titre"].'">';
    +		print '</td>';
    +
    +		// Note
    +		print '<td rowspan="'.$rowspan.'" valign="top">';
    +		print '<textarea class="flat" name="description" wrap="soft" cols="60" rows="'.ROWS_4.'">';
    +		print $object->description.'</textarea>';
    +		print '</td></tr>';
    +
    +		// Author
    +		print "<tr><td>".$langs->trans("Author")."</td><td>".$user->getFullName($langs)."</td></tr>";
    +
    +		if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) {
    +			// Duration
    +			print '<tr><td>'.$langs->trans("TotalDuration").'</td>';
    +			print '<td colspan="3">'.convertSecondToTime(
    +							$object->duration, 'all',
    +							$conf->global->MAIN_DURATION_OF_WORKDAY
    +			).'</td>';
    +			print '</tr>';
    +		}
    +
    +		// Project
    +		if (! empty($conf->projet->enabled)) {
    +			$formproject = new FormProjets($db);
    +			print "<tr><td>".$langs->trans("Project")."</td><td>";
    +			$projectid = GETPOST('projectid')?GETPOST('projectid'):$object->fk_project;
    +
    +			$numprojet = $formproject->select_projects(
    +							$object->thirdparty->id, $projectid, 'projectid',
    +							0, 0, 1, 0, 0, 0, 0, '', 0, 0, ''
    +			);
    +			print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$object->thirdparty->id;
    +			print '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?action=create';
    +			print '&socid='.$object->thirdparty->id.(!empty($id)?'&id='.$id:'').'">';
    +			print $langs->trans("AddProject").'</a>';
    +			print "</td></tr>";
    +		}
    +
    +		// Contrat
    +		if (! empty($conf->contrat->enabled)) {
    +			$formcontract = new FormContract($db);
    +			print "<tr><td>".$langs->trans("Contract")."</td><td>";
    +			$contractid = GETPOST('contractid')?GETPOST('contractid'):$object->fk_contract;
    +			$numcontract = $formcontract->select_contract($object->thirdparty->id, $contractid, 'contracttid');
    +			print "</td></tr>";
    +		}
    +		print "</table>";
    +
    +		print '<br><br>';
    +
    +		/// frequency & duration
    +		// Autogeneration
    +		$title = $langs->trans("Recurrence");
    +		print load_fiche_titre($title, '', 'calendar');
    +
    +		print '<table class="border" width="100%">';
    +
    +		// Frequency
    +		print '<tr><td class="titlefieldcreate">';
    +		print $form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'));
    +		print "</td><td>";
    +		print "<input type='text' name='frequency' value='".GETPOST('frequency', 'int')."' size='4' />&nbsp;";
    +		print $form->selectarray(
    +						'unit_frequency',
    +						array('d'=>$langs->trans('Day'), 'm'=>$langs->trans('Month'), 'y'=>$langs->trans('Year')),
    +						(GETPOST('unit_frequency')?GETPOST('unit_frequency'):'m')
    +		);
    +		print "</td></tr>";
    +
    +		// First date of execution for cron
    +		print "<tr><td>".$langs->trans('NextDateToExecution')."</td><td>";
    +		if ($date_next_execution != "")
    +			$date_next_execution = (GETPOST('remonth') ? dol_mktime(
    +							12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')
    +			) : -1);
    +		print $form->selectDate($date_next_execution, '', 1, 1, '', "add", 1, 1);
    +		print "</td></tr>";
    +
    +		// Number max of generation
    +		print "<tr><td>".$langs->trans("MaxPeriodNumber")."</td><td>";
    +		print '<input type="text" name="nb_gen_max" value="'.GETPOST('nb_gen_max').'" size="5" />';
    +		print "</td></tr>";
    +
    +		print "</table>";
    +
    +		print '<br>';
    +
    +		$title = $langs->trans("ProductsAndServices");
    +		if (empty($conf->service->enabled))
    +			$title = $langs->trans("Products");
    +		else if (empty($conf->product->enabled))
    +			$title = $langs->trans("Services");
    +
    +		print load_fiche_titre($title, '', '');
    +
    +		/*
    +		 * Invoice lines
    +		 */
    +		print '<table class="notopnoleftnoright" width="100%">';
    +		print '<tr><td colspan="3">';
    +
    +		$sql = 'SELECT l.*';
    +		$sql.= " FROM ".MAIN_DB_PREFIX."fichinterdet as l";
    +		$sql.= " WHERE l.fk_fichinter= ".$object->id;
    +		$sql.= " AND l.fk_product is null ";
    +		$sql.= " ORDER BY l.rang";
    +
    +		$result = $db->query($sql);
    +		if ($result) {
    +			$num = $db->num_rows($result);
    +			$i = 0; $total = 0;
    +
    +			echo '<table class="noborder" width="100%">';
    +			if ($num) {
    +				print '<tr class="liste_titre">';
    +				print '<td>'.$langs->trans("Description").'</td>';
    +				print '<td align="center">'.$langs->trans("Duration").'</td>';
    +				print "</tr>\n";
    +			}
    +			$var=true;
    +			while ($i < $num) {
    +				$objp = $db->fetch_object($result);
    +				print '<tr class="oddeven">';
    +
    +				// Show product and description
    +
    +				print '<td>';
    +				print '<a name="'.$objp->rowid.'"></a>'; // ancre pour retourner sur la ligne
    +
    +				$text = img_object($langs->trans('Service'), 'service');
    +
    +				print $text.' '.nl2br($objp->description);
    +
    +				// Qty
    +				print '<td align="center">'.convertSecondToTime($objp->duree).'</td>';
    +				print "</tr>";
    +
    +				$i++;
    +			}
    +			$db->free($result);
    +		} else
    +			print $db->error();
    +		print "</table>";
    +
    +		print '</td></tr>';
    +
    +		print "</table>\n";
    +
    +		dol_fiche_end();
    +
    +		print '<div align="center"><input type="submit" class="button" value="'.$langs->trans("Create").'">';
    +		print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
    +		print '<input type="button" class="button" value="'.$langs->trans("Cancel").'" onClick="javascript:history.go(-1)">';
    +		print '</div>';
    +		print "</form>\n";
    +	}
    +	else
    +		dol_print_error('', "Error, no invoice ".$object->id);
    +} elseif ($action == 'selsocforcreatefrommodel') {
    +	print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'title_commercial.png');
    +	dol_fiche_head('');
    +
    +	print '<form name="fichinter" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
    +	print '<table class="border" width="100%">';
    +	print '<tr><td class="fieldrequired">'.$langs->trans("ThirdParty").'</td><td>';
    +	print $form->select_company('', 'socid', '', 1, 1);
    +	print '</td></tr>';
    +	print '</table>';
    +
    +	dol_fiche_end();
    +
    +	print '<div class="center">';
    +	print '<input type="hidden" name="action" value="createfrommodel">';
    +	print '<input type="hidden" name="id" value="'.$id.'">';
    +	print '<input type="submit" class="button" value="'.$langs->trans("CreateDraftIntervention").'">';
    +	print '</div>';
    +
    +	print '</form>';
    +} else {
    +	/*
    +	 * View mode
    +	 *
    +	 */
    +	if ($id > 0) {
    +		if ($object->fetch($id) > 0) {
    +			$object->fetch_thirdparty();
    +
    +			$author = new User($db);
    +			$author->fetch($object->user_author);
    +
    +			$head = fichinter_rec_prepare_head($object);
    +
    +			dol_fiche_head($head, 'card', $langs->trans("PredefinedInterventional"), 0, 'intervention');
    +
    +			// Intervention card
    +			$linkback = '<a href="card-rec.php">'.$langs->trans("BackToList").'</a>';
    +
    +			$morehtmlref='<div class="refidno">';
    +			// Thirdparty
    +
    +			$morehtmlref.=$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1);
    +			// Project
    +			if (! empty($conf->projet->enabled)) {
    +				$formproject = new FormProjets($db);
    +				$langs->load("projects");
    +				$morehtmlref.='<br>'.$langs->trans('Project') . ' ';
    +				if ($user->rights->ficheinter->creer) {
    +					if ($action != 'classify') {
    +						$morehtmlref.='<a href="'.$_SERVER['PHP_SELF'].'?action=classify&amp;id='.$object->id.'">';
    +						$morehtmlref.=img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
    +					}
    +					if ($action == 'classify') {
    +
    +						$morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
    +						$morehtmlref.='<input type="hidden" name="action" value="classin">';
    +						$morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +						$morehtmlref.=$formproject->select_projects(
    +										$object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1
    +						);
    +						$morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
    +						$morehtmlref.='</form>';
    +					} else {
    +						$morehtmlref.=$form->form_project(
    +										$_SERVER['PHP_SELF'].'?id='.$object->id,
    +										$object->socid, $object->fk_project,
    +										'none', 0, 0, 0, 1
    +						);
    +					}
    +				} else {
    +					if (! empty($object->fk_project)) {
    +						$proj = new Project($db);
    +						$proj->fetch($object->fk_project);
    +						$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$object->fk_project.'"';
    +						$morehtmlref.='title="'.$langs->trans('ShowProject').'">';
    +						$morehtmlref.=$proj->ref;
    +						$morehtmlref.='</a>';
    +					} else {
    +						$morehtmlref.='';
    +					}
    +				}
    +			}
    +			$morehtmlref.='</div>';
    +
    +			dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
    +
    +			print '<div class="fichecenter">';
    +			print '<div class="fichehalfleft">';
    +			print '<div class="underbanner clearboth"></div>';
    +
    +			print '<table class="border" width="100%">';
    +
    +			print "<tr><td>".$langs->trans("Author").'</td><td colspan="3">'.$author->getFullName($langs)."</td></tr>";
    +
    +			if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) {
    +				// Duration
    +				print '<tr><td class="titlefield">'.$langs->trans("TotalDuration").'</td>';
    +				print '<td colspan="3">';
    +				print convertSecondToTime($object->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
    +				print '</td></tr>';
    +			}
    +
    +			print '<tr><td>'.$langs->trans("Description").'</td><td colspan="3">'.nl2br($object->description)."</td></tr>";
    +
    +			// Contrat
    +			if (! empty($conf->contrat->enabled)) {
    +				$langs->load('contrat');
    +				print '<tr>';
    +				print '<td>';
    +
    +				print '<table class="nobordernopadding" width="100%"><tr><td>';
    +				print $langs->trans('Contract');
    +				print '</td>';
    +				if ($action != 'contrat') {
    +					print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=contrat&amp;id='.$object->id.'">';
    +					print img_edit($langs->trans('SetContract'), 1);
    +					print '</a></td>';
    +				}
    +				print '</tr></table>';
    +				print '</td><td>';
    +				if ($action == 'contrat') {
    +					$formcontract= new Formcontract($db);
    +					$formcontract->formSelectContract(
    +									$_SERVER["PHP_SELF"].'?id='.$object->id, $object->socid,
    +									$object->fk_contrat, 'contratid', 0, 1
    +					);
    +				} else {
    +					if ($object->fk_contrat) {
    +						$contratstatic = new Contrat($db);
    +						$contratstatic->fetch($object->fk_contrat);
    +						print $contratstatic->getNomUrl(0, '', 1);
    +					} else
    +						print "&nbsp;";
    +				}
    +				print '</td>';
    +				print '</tr>';
    +			}
    +			print "</table>";
    +			print '</div>';
    +
    +			print '<div class="fichehalfright">';
    +			print '<div class="ficheaddleft">';
    +			print '<div class="underbanner clearboth"></div>';
    +
    +			print '<table class="border centpercent">';
    +
    +			$title = $langs->trans("Recurrence");
    +			print load_fiche_titre($title, '', 'calendar');
    +
    +			print '<table class="border" width="100%">';
    +
    +			// if "frequency" is empty or = 0, the reccurence is disabled
    +			print '<tr><td style="width: 50%">';
    +			print '<table class="nobordernopadding" width="100%"><tr><td>';
    +			print $langs->trans('Frequency');
    +			print '</td>';
    +			if ($action != 'editfrequency' && $user->rights->ficheinter->creer) {
    +				print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editfrequency&amp;id='.$id.'">';
    +				print img_edit($langs->trans('Edit'), 1) . '</a></td>';
    +			}
    +			print '</tr></table>';
    +			print '</td><td>';
    +			if ($action == 'editfrequency') {
    +				print '<form method="post" action="'.$_SERVER["PHP_SELF"] . '?id=' . $object->id.'">';
    +				print '<input type="hidden" name="action" value="setfrequency">';
    +				print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +				print '<table class="nobordernopadding" cellpadding="0" cellspacing="0">';
    +				print '<tr><td>';
    +				print "<input type='text' name='frequency' value='".$object->frequency."' size='5' />&nbsp;";
    +				print $form->selectarray(
    +								'unit_frequency',
    +								array('d'=>$langs->trans('Day'), 'm'=>$langs->trans('Month'), 'y'=>$langs->trans('Year')),
    +								($object->unit_frequency?$object->unit_frequency:'m')
    +				);
    +				print '</td>';
    +				print '<td align="left"><input type="submit" class="button" value="'.$langs->trans("Modify").'"></td>';
    +				print '</tr></table></form>';
    +			} else {
    +				if ($object->frequency > 0)
    +					print $langs->trans('FrequencyPer_'.$object->unit_frequency, $object->frequency);
    +				else
    +					print $langs->trans("NotARecurringInterventionalTemplate");
    +			}
    +			print '</td></tr>';
    +
    +			// Date when
    +			print '<tr><td>';
    +			if ( $user->rights->ficheinter->creer && ($action == 'date_when' || $object->frequency > 0)) {
    +				print $form->editfieldkey(
    +								$langs->trans("NextDateToExecution"), 'date_when', $object->date_when,
    +								$object, $user->rights->facture->creer, 'day'
    +				);
    +			} else {
    +				print $langs->trans("NextDateToExecution");
    +			}
    +			print '</td><td>';
    +			if ($action == 'date_when' || $object->frequency > 0) {
    +				print $form->editfieldval(
    +								$langs->trans("NextDateToExecution"), 'date_when', $object->date_when,
    +								$object, $user->rights->facture->creer, 'day'
    +				);
    +			}
    +			print '</td>';
    +			print '</tr>';
    +
    +			// Max period / Rest period
    +			print '<tr><td>';
    +			if ($user->rights->ficheinter->creer && ($action == 'nb_gen_max' || $object->frequency > 0)) {
    +				print $form->editfieldkey(
    +								$langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max,
    +								$object, $user->rights->facture->creer
    +				);
    +			} else
    +				print $langs->trans("MaxPeriodNumber");
    +
    +			print '</td><td>';
    +			if ($action == 'nb_gen_max' || $object->frequency > 0) {
    +				print $form->editfieldval(
    +							$langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max?$object->nb_gen_max:'',
    +							$object, $user->rights->facture->creer
    +				);
    +			}
    +			else
    +				print '';
    +
    +			print '</td>';
    +			print '</tr>';
    +
    +			print '</table>';
    +
    +			// Frequencry/Recurring section
    +			if ($object->frequency > 0) {
    +				print '<br>';
    +				if (empty($conf->cron->enabled)) {
    +					$txtinfoadmin=$langs->trans(
    +									"EnableAndSetupModuleCron",
    +									$langs->transnoentitiesnoconv("Module2300Name")
    +					);
    +					print info_admin($txtinfoadmin);
    +				}
    +				print '<div class="underbanner clearboth"></div>';
    +				print '<table class="border centpercent">';
    +
    +				// Nb of generation already done
    +				print '<tr><td style="width: 50%">'.$langs->trans("NbOfGenerationDone").'</td>';
    +				print '<td>';
    +				print $object->nb_gen_done?$object->nb_gen_done:'0';
    +				print '</td>';
    +				print '</tr>';
    +
    +				// Date last
    +				print '<tr><td>';
    +				print $langs->trans("DateLastGeneration");
    +				print '</td><td>';
    +				print dol_print_date($object->date_last_gen, 'dayhour');
    +				print '</td>';
    +				print '</tr>';
    +				print '</table>';
    +				print '<br>';
    +			}
    +
    +			print '</div>';
    +			print '</div>';
    +			print '</div>';
    +
    +			print '<div class="clearboth"></div><br>';
    +
    +			/*
    +			 * Lines
    +			 */
    +
    +			$title = $langs->trans("ProductsAndServices");
    +			if (empty($conf->service->enabled))
    +				$title = $langs->trans("Products");
    +			else if (empty($conf->product->enabled))
    +				$title = $langs->trans("Services");
    +
    +			print load_fiche_titre($title);
    +
    +			print '<table class="noborder" width="100%">';
    +			print '<tr class="liste_titre">';
    +			print '<td>'.$langs->trans("Description").'</td>';
    +			print '<td align="center">'.$langs->trans("Duration").'</td>';
    +			print '</tr>';
    +
    +			$num = count($object->lines);
    +			$i = 0;
    +			while ($i < $num) {
    +
    +				// Show product and description
    +				if (isset($object->lines[$i]->product_type))
    +					$type=$object->lines[$i]->product_type;
    +				else
    +					$object->lines[$i]->fk_product_type;
    +				// Try to enhance type detection using date_start and date_end for free lines when type
    +				// was not saved.
    +				if (! empty($objp->date_start)) $type=1;
    +				if (! empty($objp->date_end)) $type=1;
    +
    +				// Show line
    +				print '<tr class="oddeven">';
    +				print '<td>';
    +				$text = img_object($langs->trans('Service'), 'service');
    +				print $text.' '.nl2br($object->lines[$i]->desc);
    +				print '</td>';
    +
    +				print '<td align="center">'.convertSecondToTime($object->lines[$i]->duree).'</td>';
    +				print "</tr>\n";
    +				$i++;
    +			}
    +			print '</table>';
    +
    +			/**
    +			 * Barre d'actions
    +			 */
    +			print '<div class="tabsAction">';
    +
    +			if ($user->rights->ficheinter->creer) {
    +				print '<div class="inline-block divButAction">';
    +				print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=createfrommodel';
    +				print '&socid='.$object->thirdparty->id.'&id='.$object->id.'">';
    +				print $langs->trans("CreateFichInter").'</a></div>';
    +			}
    +
    +			if ($user->rights->ficheinter->supprimer) {
    +				print '<div class="inline-block divButAction">';
    +				print '<a class="butActionDelete" href="'.$_SERVER['PHP_SELF'].'?action=delete&id='.$object->id.'">';
    +				print $langs->trans('Delete').'</a></div>';
    +			}
    +			print '</div>';
    +		} else
    +			print $langs->trans("ErrorRecordNotFound");
    +	} else {
    +		/*
    +		 *  List mode
    +		 */
    +		$sql = "SELECT f.rowid as fich_rec, s.nom as name, s.rowid as socid, f.rowid as facid, f.titre, ";
    +		$sql.= " f.duree, f.fk_contrat, f.fk_projet, f.frequency, f.nb_gen_done, f.nb_gen_max,";
    +		$sql.= " f.date_last_gen, f.date_when, f.datec";
    +
    +		$sql.= " FROM ".MAIN_DB_PREFIX."fichinter_rec as f";
    +		$sql.= " , ".MAIN_DB_PREFIX."societe as s ";
    +		if (! $user->rights->societe->client->voir && ! $socid) {
    +			$sql .= " , ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    +		}
    +		$sql.= " WHERE f.fk_soc = s.rowid";
    +		$sql.= " AND f.entity = ".$conf->entity;
    +		if ($socid)	$sql .= " AND s.rowid = ".$socid;
    +		if (! $user->rights->societe->client->voir && ! $socid) {
    +			$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
    +		}
    +		if ($search_ref) $sql .= natural_search('f.titre', $search_ref);
    +		if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
    +		if ($search_frequency == '1') $sql.= ' AND f.frequency > 0';
    +		if ($search_frequency == '0') $sql.= ' AND (f.frequency IS NULL or f.frequency = 0)';
    +
    +
    +		//$sql .= " ORDER BY $sortfield $sortorder, rowid DESC ";
    +		//	$sql .= $db->plimit($limit + 1, $offset);
    +
    +		$resql = $db->query($sql);
    +		if ($resql) {
    +			$num = $db->num_rows($resql);
    +			print_barre_liste(
    +							$langs->trans("RepeatableInterventional"), $page,
    +							$_SERVER['PHP_SELF'], "&socid=$socid", $sortfield, $sortorder,
    +							'', $num, '', 'title_commercial.png'
    +			);
    +
    +			print $langs->trans("ToCreateAPredefinedInterventional").'<br><br>';
    +
    +			$i = 0;
    +			print '<table class="noborder" width="100%">';
    +			print '<tr class="liste_titre">';
    +			print_liste_field_titre(
    +							$langs->trans("Ref"), $_SERVER['PHP_SELF'], "f.titre", "", "",
    +							'width="200px" align="left"', $sortfiled, $sortorder
    +			);
    +
    +			print_liste_field_titre(
    +							$langs->trans("Company"), $_SERVER['PHP_SELF'], "s.nom", "", "",
    +							'width="200px" align="left"', $sortfiled, $sortorder
    +			);
    +			if (! empty($conf->contrat->enabled))
    +				print_liste_field_titre(
    +								$langs->trans("Contract"), $_SERVER['PHP_SELF'],
    +								"f.fk_contrat", "", "",
    +								'width="100px" align="left"', $sortfiled, $sortorder
    +				);
    +
    +			if (! empty($conf->projet->enabled))
    +				print_liste_field_titre(
    +								$langs->trans("Project"), $_SERVER['PHP_SELF'],
    +								"f.fk_project", "", "",
    +								'width="100px" align="left"', $sortfiled, $sortorder
    +				);
    +			print_liste_field_titre(
    +							$langs->trans("Duration"), $_SERVER['PHP_SELF'],
    +							'f.duree', '', '',
    +							'width="50px" align="right"', $sortfiled, $sortorder
    +			);
    +			// Recurring or not
    +			print_liste_field_titre(
    +							$langs->trans("Frequency"), $_SERVER['PHP_SELF'],
    +							"f.frequency", "", "",
    +							'width="100px" align="center"', $sortfiled, $sortorder
    +			);
    +			print_liste_field_titre(
    +							$langs->trans("NbOfGenerationDone"), $_SERVER['PHP_SELF'],
    +							"f.nb_gen_done", "", "",
    +							'width="100px" align="center"', $sortfiled, $sortorder
    +			);
    +
    +			print_liste_field_titre(
    +							$langs->trans("DateLastGeneration"), $_SERVER['PHP_SELF'],
    +							"f.date_last_gen", "", "",
    +							'width="100px" align="center"', $sortfiled, $sortorder
    +			);
    +			print_liste_field_titre(
    +							$langs->trans("NextDateToIntervention"), $_SERVER['PHP_SELF'],
    +							"f.date_when", "", "",
    +							'width="100px" align="center"', $sortfiled, $sortorder
    +			);
    +			print '<th width="100px"></th>';
    +			print "</tr>\n";
    +
    +
    +// les filtres à faire ensuite
    +
    +			if ($num > 0) {
    +				while ($i < min($num, $limit)) {
    +					$objp = $db->fetch_object($resql);
    +
    +					print '<tr class="oddeven">';
    +					print '<td><a href="'.$_SERVER['PHP_SELF'].'?id='.$objp->fich_rec.'">';
    +					print img_object($langs->trans("ShowIntervention"), "intervention").' '.$objp->titre;
    +					print "</a></td>\n";
    +					if ($objp->socid) {
    +						$companystatic->id=$objp->socid;
    +						$companystatic->name=$objp->name;
    +						print '<td>'.$companystatic->getNomUrl(1, 'customer').'</td>';
    +					} else
    +						print '<td>'.$langs->trans("None").'</td>';
    +
    +					if (! empty($conf->contrat->enabled)) {
    +						print '<td>';
    +						if ($objp->fk_contrat >0) {
    +							$contratstatic->fetch($objp->fk_contrat);
    +							print $contratstatic->getNomUrl(1);
    +						}
    +						print '</td>';
    +					}
    +					if (! empty($conf->projet->enabled)) {
    +						print '<td>';
    +						if ($objp->fk_project >0) {
    +							$projectstatic->fecth($objp->fk_projet);
    +							print $projectstatic->getNomUrl(1);
    +						}
    +						print '</td>';
    +					}
    +
    +					print '<td align=right>'.convertSecondToTime($objp->duree).'</td>';
    +
    +					print '<td align="center">'.yn($objp->frequency?1:0).'</td>';
    +
    +					print '<td align="center">';
    +					if ($objp->frequency) {
    +						print $objp->nb_gen_done.($objp->nb_gen_max>0?' / '. $objp->nb_gen_max:'') ;
    +						print '</td>';
    +
    +						print '<td align="center">';
    +						print dol_print_date($db->jdate($objp->date_last_gen), 'day') ;
    +						print '</td>';
    +
    +						print '<td align="center">';
    +						print dol_print_date($db->jdate($objp->date_when), 'day');
    +						print '</td>';
    +					} else {
    +						print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
    +						print '</td>';
    +						print '<td align="center">';
    +						print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
    +						print '</td>';
    +						print '<td align="center">';
    +						print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
    +						print '</td>';
    +					}
    +
    +					if ($user->rights->ficheinter->creer) {
    +						// Action column
    +						print '<td align="center">';
    +						if ($user->rights->ficheinter->creer) {
    +							if (empty($objp->frequency) || $db->jdate($objp->date_when) <= $today) {
    +								print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=createfrommodel';
    +								print '&socid='.$objp->socid.'&id='.$objp->fich_rec.'">';
    +								print $langs->trans("CreateFichInter").'</a>';
    +							} else
    +								print $langs->trans("DateIsNotEnough");
    +						} else
    +							print "&nbsp;";
    +
    +						print "</td>";
    +
    +						print "</tr>\n";
    +						$i++;
    +					}
    +				}
    +			} else
    +				print '<tr class="oddeven"><td colspan="6">'.$langs->trans("NoneF").'</td></tr>';
    +
    +			print "</table>";
    +			$db->free($resql);
    +		} else
    +			dol_print_error($db);
    +	}
    +}
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php
    index 15b75495c38..5896a5c5723 100644
    --- a/htdocs/fichinter/card.php
    +++ b/htdocs/fichinter/card.php
    @@ -1,11 +1,11 @@
     <?php
     /* Copyright (C) 2002-2007	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
      * Copyright (C) 2004-2016	Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2015	Regis Houssin			<regis.houssin@capnetworks.com>
    + * Copyright (C) 2005-2018	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2011-2017  Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2014-2018  Ferran Marcet           <fmarcet@2byte.es>
    - * Copyright (C) 2014-2015 	Charlie Benke           <charlies@patas-monkey.com>
    + * Copyright (C) 2014-2018  Charlene Benke          <charlies@patas-monkey.com>
      * Copyright (C) 2015-2016  Abbes Bahfir            <bafbes@gmail.com>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -378,10 +378,8 @@ if (empty($reshook))
     									$error++;
     									break;
     								}
    -
     							}
     						}
    -
     		            }
     		            else
     		            {
    @@ -1099,7 +1097,6 @@ if ($action == 'create')
     
     		print '</form>';
     	}
    -
     }
     else if ($id > 0 || ! empty($ref))
     {
    @@ -1471,8 +1468,6 @@ else if ($id > 0 || ! empty($ref))
     					$line->fetch_optionals();
     
     					print $line->showOptionals($extrafieldsline, 'view', array('style'=>$bc[$var], 'colspan'=>5));
    -
    -
     				}
     
     				// Line in update mode
    @@ -1490,8 +1485,11 @@ else if ($id > 0 || ! empty($ref))
     
     					// Date d'intervention
     					print '<td align="center" class="nowrap">';
    -                                        if (!empty($conf->global->FICHINTER_DATE_WITHOUT_HOUR)) $form->select_date($db->jdate($objp->date_intervention),'di',0,0,0,"date_intervention");
    -                                        else $form->select_date($db->jdate($objp->date_intervention),'di',1,1,0,"date_intervention");
    +                    if (!empty($conf->global->FICHINTER_DATE_WITHOUT_HOUR)) {
    +                        print $form->selectDate($db->jdate($objp->date_intervention),'di',0,0,0,"date_intervention");
    +                    } else {
    +                        print $form->selectDate($db->jdate($objp->date_intervention),'di',1,1,0,"date_intervention");
    +                    }
     					print '</td>';
     
                         // Duration
    @@ -1516,8 +1514,6 @@ else if ($id > 0 || ! empty($ref))
     					$line->fetch_optionals();
     
     					print $line->showOptionals($extrafieldsline, 'edit', array('style'=>$bc[$var], 'colspan'=>5));
    -
    -
     				}
     
     				$i++;
    @@ -1556,18 +1552,25 @@ else if ($id > 0 || ! empty($ref))
                     print '<td align="center" class="nowrap">';
     				$now=dol_now();
     				$timearray=dol_getdate($now);
    -				if (! GETPOST('diday','int')) $timewithnohour=dol_mktime(0,0,0,$timearray['mon'],$timearray['mday'],$timearray['year']);
    -				else $timewithnohour=dol_mktime(GETPOST('dihour','int'),GETPOST('dimin','int'), 0,GETPOST('dimonth','int'),GETPOST('diday','int'),GETPOST('diyear','int'));
    -                                if (!empty($conf->global->FICHINTER_DATE_WITHOUT_HOUR)) $form->select_date($timewithnohour,'di',0,0,0,"addinter");
    -                                else $form->select_date($timewithnohour,'di',1,1,0,"addinter");
    +				if (! GETPOST('diday','int')) {
    +                    $timewithnohour=dol_mktime(0,0,0,$timearray['mon'],$timearray['mday'],$timearray['year']);
    +                } else {
    +                    $timewithnohour=dol_mktime(GETPOST('dihour','int'),GETPOST('dimin','int'), 0,GETPOST('dimonth','int'),GETPOST('diday','int'),GETPOST('diyear','int'));
    +                }
    +                if (!empty($conf->global->FICHINTER_DATE_WITHOUT_HOUR)) {
    +                    print $form->selectDate($timewithnohour,'di',0,0,0,"addinter");
    +                } else {
    +                    print $form->selectDate($timewithnohour,'di',1,1,0,"addinter");
    +                }
     				print '</td>';
     
                     // Duration
                     print '<td align="right">';
                     if (empty($conf->global->FICHINTER_WITHOUT_DURATION)) {
                         $selectmode = 'select';
    -                    if (!empty($conf->global->INTERVENTION_ADDLINE_FREEDUREATION))
    +                    if (!empty($conf->global->INTERVENTION_ADDLINE_FREEDUREATION)) {
                             $selectmode = 'text';
    +                    }
                         $form->select_duration('duration', (!GETPOST('durationhour', 'int') && !GETPOST('durationmin', 'int')) ? 3600 : (60 * 60 * GETPOST('durationhour', 'int') + 60 * GETPOST('durationmin', 'int')), 0, $selectmode);
                     }
                     print '</td>';
    @@ -1643,6 +1646,13 @@ else if ($id > 0 || ! empty($ref))
     					else print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">'.$langs->trans('SendMail').'</a></div>';
     				}
     
    +		    		// create interventional model
    +				if ($object->statut == Fichinter::STATUS_DRAFT && $user->rights->ficheinter->creer && (count($object->lines) > 0)) {
    +					print '<div class="inline-block divButAction">';
    +					print '<a class="butAction" href="'.DOL_URL_ROOT.'/fichinter/card-rec.php?id='.$object->id.'&action=create">'.$langs->trans("ChangeIntoRepeatableInterventional").'</a>';
    +					print '</div>';
    +				}
    +
     				// Proposal
     				if ($conf->service->enabled && ! empty($conf->propal->enabled) && $object->statut > Fichinter::STATUS_DRAFT)
     				{
    @@ -1694,7 +1704,6 @@ else if ($id > 0 || ! empty($ref))
     					print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete"';
     					print '>'.$langs->trans('Delete').'</a></div>';
     				}
    -
     			}
     		}
     	}
    diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php
    index 8b21b534856..3f3315b6028 100644
    --- a/htdocs/fichinter/class/api_interventions.class.php
    +++ b/htdocs/fichinter/class/api_interventions.class.php
    @@ -35,7 +35,7 @@ class Interventions extends DolibarrApi
         static $FIELDS = array(
           'socid',
           'fk_project',
    -      'description'
    +      'description',
         );
     
         /**
    @@ -44,7 +44,7 @@ class Interventions extends DolibarrApi
         static $FIELDSLINE = array(
           'description',
           'date',
    -      'duree'
    +      'duree',
         );
     
         /**
    @@ -106,7 +106,8 @@ class Interventions extends DolibarrApi
          *
          * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -217,7 +218,8 @@ class Interventions extends DolibarrApi
          * @return int
          */
         /* TODO
    -    function getLines($id) {
    +    function getLines($id)
    +    {
         	if(! DolibarrApiAccess::$user->rights->ficheinter->lire) {
         		throw new RestException(401);
         	}
    @@ -315,7 +317,6 @@ class Interventions extends DolibarrApi
     		    	'message' => 'Intervention deleted'
     	    	)
         	);
    -
         }
     
         /**
    @@ -424,7 +425,8 @@ class Interventions extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
         	$object = parent::_cleanObjectDatas($object);
     
    @@ -453,6 +455,4 @@ class Interventions extends DolibarrApi
             }
             return $fichinter;
         }
    -
    -
     }
    diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php
    index 789a351c776..05a139e2a9a 100644
    --- a/htdocs/fichinter/class/fichinter.class.php
    +++ b/htdocs/fichinter/class/fichinter.class.php
    @@ -35,10 +35,29 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobjectline.class.php';
      */
     class Fichinter extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='fichinter';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='fichinter';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_fichinter';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line='fichinterdet';
    +
    +	/**
    +	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
    +	 */
     	public $picto = 'intervention';
     
     	/**
    @@ -46,36 +65,52 @@ class Fichinter extends CommonObject
     	 */
     	protected $table_ref_field = 'ref';
     
    -	var $socid;		// Id client
    +	public $socid;		// Id client
     
    -	var $author;
    -	var $datec;
    -	var $datev;
    -	var $dateo;
    -	var $datee;
    -	var $datet;
    -	var $datem;
    -	var $duration;
    -	var $statut = 0;		// 0=draft, 1=validated, 2=invoiced, 3=Terminate
    -	var $description;
    -	var $fk_contrat = 0;
    -	var $fk_project = 0;
    -	var $extraparams=array();
    +	public $author;
    +	public $datec;
    +	public $datev;
    +	public $dateo;
    +	public $datee;
    +	public $datet;
    +	public $datem;
    +	public $duration;
    +	public $statut = 0;		// 0=draft, 1=validated, 2=invoiced, 3=Terminate
     
    -	var $lines = array();
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_contrat = 0;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_project = 0;
    +
    +	public $extraparams=array();
    +
    +	public $lines = array();
     
     	/**
     	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
    +
     	/**
     	 * Validated status
     	 */
     	const STATUS_VALIDATED = 1;
    +
     	/**
     	 * Billed
     	 */
     	const STATUS_BILLED = 2;
    +
     	/**
     	 * Closed
     	 */
    @@ -93,6 +128,7 @@ class Fichinter extends CommonObject
     		$this->products = array();
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load indicators into this->nb for board
     	 *
    @@ -100,6 +136,7 @@ class Fichinter extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $user;
     
     		$this->nb=array();
    @@ -266,7 +303,6 @@ class Fichinter extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -622,6 +658,7 @@ class Fichinter extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Returns the label of a statut
     	 *
    @@ -631,6 +668,7 @@ class Fichinter extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		// Init/load array of translation of status
     		if (empty($this->statuts) || empty($this->statuts_short))
     		{
    @@ -653,17 +691,17 @@ class Fichinter extends CommonObject
     
     		if ($mode == 0)
     			return $this->statuts[$statut];
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     			return $this->statuts_short[$statut];
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     			return img_picto($this->statuts_short[$statut], $this->statuts_logo[$statut]).' '.$this->statuts_short[$statut];
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     			return img_picto($this->statuts_short[$statut], $this->statuts_logo[$statut]);
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     			return img_picto($this->statuts_short[$statut], $this->statuts_logo[$statut]).' '.$this->statuts[$statut];
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     			return '<span class="hideonsmartphone">'.$this->statuts_short[$statut].' </span>'.img_picto($this->statuts[$statut],$this->statuts_logo[$statut]);
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     			return '<span class="hideonsmartphone">'.$this->statuts[$statut].' </span>'.img_picto($this->statuts[$statut],$this->statuts_logo[$statut]);
     
     		return '';
    @@ -844,7 +882,6 @@ class Fichinter extends CommonObject
     					$muser->fetch($obj->fk_user_modification);
     					$this->user_modification   = $muser;
     				}
    -
     			}
     			$this->db->free($resql);
     		}
    @@ -937,7 +974,8 @@ class Fichinter extends CommonObject
     
     					if (! dol_delete_file($file,0,0,0,$this)) // For triggers
     					{
    -						$this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
    +						$langs->load("errors");
    +						$this->error=$langs->trans("ErrorFailToDeleteFile",$file);
     						return 0;
     					}
     				}
    @@ -945,7 +983,8 @@ class Fichinter extends CommonObject
     				{
     					if (! dol_delete_dir_recursive($dir))
     					{
    -						$this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
    +						$langs->load("errors");
    +						$this->error=$langs->trans("ErrorFailToDeleteDir",$dir);
     						return 0;
     					}
     				}
    @@ -964,6 +1003,7 @@ class Fichinter extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Defines a delivery date of intervention
     	 *
    @@ -973,6 +1013,7 @@ class Fichinter extends CommonObject
     	 */
     	function set_date_delivery($user, $date_delivery)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if ($user->rights->ficheinter->creer)
    @@ -996,6 +1037,7 @@ class Fichinter extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Define the label of the intervention
     	 *
    @@ -1005,6 +1047,7 @@ class Fichinter extends CommonObject
     	 */
     	function set_description($user, $description)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if ($user->rights->ficheinter->creer)
    @@ -1029,6 +1072,7 @@ class Fichinter extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Link intervention to a contract
     	 *
    @@ -1038,6 +1082,7 @@ class Fichinter extends CommonObject
     	 */
     	function set_contrat($user, $contractid)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if ($user->rights->ficheinter->creer)
    @@ -1237,6 +1282,7 @@ class Fichinter extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load array lines ->lines
     	 *
    @@ -1244,6 +1290,7 @@ class Fichinter extends CommonObject
     	 */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		$this->lines = array();
     
     		$sql = 'SELECT rowid, description, duree, date, rang';
    @@ -1309,24 +1356,46 @@ class Fichinter extends CommonObject
      */
     class FichinterLigne extends CommonObjectLine
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	// From llx_fichinterdet
    -	var $fk_fichinter;
    -	var $desc;          	// Description ligne
    -	var $datei;           // Date intervention
    -	var $duration;        // Duree de l'intervention
    -	var $rang = 0;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_fichinter;
     
    +	public $desc;          	// Description ligne
    +	public $datei;           // Date intervention
    +	public $duration;        // Duree de l'intervention
    +	public $rang = 0;
    +
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='fichinterdet';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='fichinterdet';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_fichinter';
     
     	/**
    -	 *	Constructor
    +	 *  Constructor
     	 *
    -	 *	@param	DoliDB	$db		Database handler
    +	 *  @param  DoliDB  $db     Database handler
     	 */
     	function __construct($db)
     	{
    @@ -1533,6 +1602,7 @@ class FichinterLigne extends CommonObjectLine
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Update total duration into llx_fichinter
     	 *
    @@ -1540,6 +1610,7 @@ class FichinterLigne extends CommonObjectLine
     	 */
     	function update_total()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$this->db->begin();
    @@ -1639,6 +1710,4 @@ class FichinterLigne extends CommonObjectLine
     			return -2;
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php
    index b435398fec2..40a1b7eef2f 100644
    --- a/htdocs/fichinter/class/fichinterstats.class.php
    +++ b/htdocs/fichinter/class/fichinterstats.class.php
    @@ -33,6 +33,9 @@ include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
      */
     class FichinterStats extends Stats
     {
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element;
     
     	var $socid;
    @@ -207,6 +210,5 @@ class FichinterStats extends Stats
     
     		return $this->_getAllByProduct($sql);
     	}
    -
     }
     
    diff --git a/htdocs/fichinter/contact.php b/htdocs/fichinter/contact.php
    index d3b2ea6f78e..b69aa5952fa 100644
    --- a/htdocs/fichinter/contact.php
    +++ b/htdocs/fichinter/contact.php
    @@ -185,7 +185,6 @@ if ($id > 0 || ! empty($ref))
     	    $res=@include dol_buildpath($reldir.'/contacts.tpl.php');
     	    if ($res) break;
     	}
    -
     }
     
     
    diff --git a/htdocs/fichinter/document.php b/htdocs/fichinter/document.php
    index 6e84f457eb1..42273785a61 100644
    --- a/htdocs/fichinter/document.php
    +++ b/htdocs/fichinter/document.php
    @@ -94,7 +94,7 @@ if ($object->id)
     	dol_fiche_head($head, 'documents',  $langs->trans("InterventionCard"), -1, 'intervention');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -168,7 +168,6 @@ if ($object->id)
         $permtoedit = $user->rights->ficheinter->creer;
         $param = '&id=' . $object->id;
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
    diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php
    index 6b8ce71bfb5..9e5f1526969 100644
    --- a/htdocs/fichinter/index.php
    +++ b/htdocs/fichinter/index.php
    @@ -148,7 +148,6 @@ if ($resql)
         {
             if (! $conf->use_javascript_ajax)
             {
    -
                 print '<tr class="oddeven">';
                 print '<td>'.$fichinterstatic->LibStatut($status,$bool,0).'</td>';
                 print '<td align="right"><a href="list.php?viewstatut='.$status.'">'.(isset($vals[$status.$bool])?$vals[$status.$bool]:0).' ';
    diff --git a/htdocs/fichinter/stats/index.php b/htdocs/fichinter/stats/index.php
    index 7a68bef34ec..f4df5f3c5f8 100644
    --- a/htdocs/fichinter/stats/index.php
    +++ b/htdocs/fichinter/stats/index.php
    @@ -49,10 +49,8 @@ $endyear=$year;
     
     $object_status=GETPOST('object_status');
     
    -$langs->load('interventions');
    -$langs->load('companies');
    -$langs->load('other');
    -$langs->load('suppliers');
    +// Load translation files required by the page
    +$langs->loadLangs(array("interventions","suppliers","companies","other"));
     
     
     /*
    @@ -273,6 +271,7 @@ print '<div class="fichecenter"><div class="fichethirdleft">';
     	print '<br><br>';
     //}
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -318,6 +317,7 @@ foreach ($data as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
    index 24c0de121db..f886266a701 100644
    --- a/htdocs/filefunc.inc.php
    +++ b/htdocs/filefunc.inc.php
    @@ -31,7 +31,7 @@
      */
     
     if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
    -if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.3');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
    +if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.0-beta');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
     
     if (! defined('EURO')) define('EURO',chr(128));
     
    @@ -130,8 +130,8 @@ $dolibarr_main_url_root_alt=(empty($dolibarr_main_url_root_alt)?'':trim($dolibar
     $dolibarr_main_document_root=trim($dolibarr_main_document_root);
     $dolibarr_main_document_root_alt=(empty($dolibarr_main_document_root_alt)?'':trim($dolibarr_main_document_root_alt));
     
    -if (empty($dolibarr_main_db_port)) $dolibarr_main_db_port=0;		// Pour compatibilite avec anciennes configs, si non defini, on prend 'mysql'
    -if (empty($dolibarr_main_db_type)) $dolibarr_main_db_type='mysqli';	// Pour compatibilite avec anciennes configs, si non defini, on prend 'mysql'
    +if (empty($dolibarr_main_db_port)) $dolibarr_main_db_port=3306;		// For compatibility with old configs, if not defined, we take 'mysql' type
    +if (empty($dolibarr_main_db_type)) $dolibarr_main_db_type='mysqli';	// For compatibility with old configs, if not defined, we take 'mysql' type
     
     // Mysql driver support has been removed in favor of mysqli
     if ($dolibarr_main_db_type == 'mysql') $dolibarr_main_db_type = 'mysqli';
    diff --git a/htdocs/fourn/ajax/getSupplierPrices.php b/htdocs/fourn/ajax/getSupplierPrices.php
    index eeb2c1113f6..ae407d5544d 100644
    --- a/htdocs/fourn/ajax/getSupplierPrices.php
    +++ b/htdocs/fourn/ajax/getSupplierPrices.php
    @@ -34,8 +34,8 @@ $idprod=GETPOST('idprod','int');
     
     $prices = array();
     
    -$langs->load('stocks');
    -$langs->load('margins');
    +// Load translation files required by the page
    +$langs->loadLangs(array("stocks","margins"));
     
     
     /*
    diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php
    index b295355bdc9..92498e99589 100644
    --- a/htdocs/fourn/card.php
    +++ b/htdocs/fourn/card.php
    @@ -374,7 +374,7 @@ if ($object->id > 0)
     	    $link=DOL_URL_ROOT.'/supplier_proposal/list.php?socid='.$object->id;
     	    $icon='bill';
     	    if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -	    $boxstat.='<div class="boxstats">';
    +	    $boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     	    $boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     	    $boxstat.='<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
     	    $boxstat.='</div>';
    @@ -392,7 +392,7 @@ if ($object->id > 0)
     	    $link=DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->id;
     	    $icon='bill';
     	    if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -	    $boxstat.='<div class="boxstats">';
    +	    $boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     	    $boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     	    $boxstat.='<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
     	    $boxstat.='</div>';
    @@ -410,7 +410,7 @@ if ($object->id > 0)
     	    $link=DOL_URL_ROOT.'/fourn/facture/list.php?socid='.$object->id;
     	    $icon='bill';
     	    if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -	    $boxstat.='<div class="boxstats">';
    +	    $boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     	    $boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     	    $boxstat.='<span class="boxstatsindicator">'.price($outstandingTotal, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
     	    $boxstat.='</div>';
    @@ -421,7 +421,7 @@ if ($object->id > 0)
     	    $link=DOL_URL_ROOT.'/fourn/recap-fourn.php?socid='.$object->id;
     	    $icon='bill';
     	    if ($link) $boxstat.='<a href="'.$link.'" class="boxstatsindicator thumbstat nobold nounderline">';
    -	    $boxstat.='<div class="boxstats">';
    +	    $boxstat.='<div class="boxstats" title="'.dol_escape_htmltag($text).'">';
     	    $boxstat.='<span class="boxstatstext">'.img_object("",$icon).' '.$text.'</span><br>';
     	    $boxstat.='<span class="boxstatsindicator'.($outstandingOpened>0?' amountremaintopay':'').'">'.price($outstandingOpened, 1, $langs, 1, -1, -1, $conf->currency).$warn.'</span>';
     	    $boxstat.='</div>';
    @@ -884,6 +884,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php
    index 68bb902b8fb..3b3ac43c496 100644
    --- a/htdocs/fourn/class/api_supplier_invoices.class.php
    +++ b/htdocs/fourn/class/api_supplier_invoices.class.php
    @@ -33,7 +33,7 @@ class SupplierInvoices extends DolibarrApi
          * @var array   $FIELDS     Mandatory fields, checked when create and update object
          */
         static $FIELDS = array(
    -        'socid'
    +        'socid',
         );
     
         /**
    @@ -96,7 +96,8 @@ class SupplierInvoices extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -152,8 +153,7 @@ class SupplierInvoices extends DolibarrApi
             }
     
             $result = $db->query($sql);
    -        if ($result)
    -        {
    +        if ($result) {
                 $i = 0;
                 $num = $db->num_rows($result);
                 $min = min($num, ($limit <= 0 ? $num : $limit));
    @@ -170,10 +170,10 @@ class SupplierInvoices extends DolibarrApi
             else {
                 throw new RestException(503, 'Error when retrieve supplier invoice list : '.$db->lasterror());
             }
    -        if( ! count($obj_ret)) {
    +        if ( ! count($obj_ret)) {
                 throw new RestException(404, 'No supplier invoice found');
             }
    -		return $obj_ret;
    +        return $obj_ret;
         }
     
         /**
    @@ -332,7 +332,8 @@ class SupplierInvoices extends DolibarrApi
          * @param   Object  $object    Object to clean
          * @return  array              Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php
    index d9596bf3958..ac5c825856c 100644
    --- a/htdocs/fourn/class/api_supplier_orders.class.php
    +++ b/htdocs/fourn/class/api_supplier_orders.class.php
    @@ -46,8 +46,8 @@ class SupplierOrders extends DolibarrApi
          */
         function __construct()
         {
    -		global $db, $conf;
    -		$this->db = $db;
    +        global $db, $conf;
    +        $this->db = $db;
             $this->order = new CommandeFournisseur($this->db);
         }
     
    @@ -68,11 +68,11 @@ class SupplierOrders extends DolibarrApi
     		}
     
             $result = $this->order->fetch($id);
    -        if( ! $result ) {
    +        if ( ! $result ) {
                 throw new RestException(404, 'Supplier order not found');
             }
     
    -		if( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) {
    +		if ( ! DolibarrApi::_checkAccessToResource('fournisseur',$this->order->id,'','commande')) {
     			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
     		}
     
    @@ -96,7 +96,8 @@ class SupplierOrders extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids='', $status='', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -336,7 +337,8 @@ class SupplierOrders extends DolibarrApi
          * @param   Object  $object    Object to clean
          * @return  array              Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/fourn/class/fournisseur.class.php b/htdocs/fourn/class/fournisseur.class.php
    index ba486e066cc..878f4bee67e 100644
    --- a/htdocs/fourn/class/fournisseur.class.php
    +++ b/htdocs/fourn/class/fournisseur.class.php
    @@ -102,6 +102,7 @@ class Fournisseur extends Societe
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load statistics indicators
     	 *
    @@ -109,6 +110,7 @@ class Fournisseur extends Societe
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		$this->nb=array();
    @@ -141,9 +143,9 @@ class Fournisseur extends Societe
     			$this->error=$this->db->error();
     			return -1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Create a supplier category
     	 *
    @@ -153,6 +155,7 @@ class Fournisseur extends Societe
     	 */
     	function CreateCategory($user, $name)
     	{
    +        // phpcs:enable
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie (label,visible,type)";
     		$sql.= " VALUES ";
     		$sql.= " ('".$this->db->escape($name)."',1,1)";
    @@ -172,6 +175,7 @@ class Fournisseur extends Societe
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Return the suppliers list
     	 *
    @@ -179,6 +183,7 @@ class Fournisseur extends Societe
     	 */
     	function ListArray()
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -207,6 +212,4 @@ class Fournisseur extends Societe
     		}
     		return $arr;
     	}
    -
     }
    -
    diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php
    index dfceb8d4e73..ced75842606 100644
    --- a/htdocs/fourn/class/fournisseur.commande.class.php
    +++ b/htdocs/fourn/class/fournisseur.commande.class.php
    @@ -4,11 +4,11 @@
      * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2007		Franky Van Liedekerke	<franky.van.liedekerke@telenet.be>
      * Copyright (C) 2010-2014	Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2010-2016	Philippe Grand			<philippe.grand@atoo-net.com>
    + * Copyright (C) 2010-2018	Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2012-2015  Marcos García           <marcosgdf@gmail.com>
      * Copyright (C) 2013       Florian Henry		  	<florian.henry@open-concept.pro>
      * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2018      Nicolas ZABOURI			<info@inovea-conseil.com>
    + * Copyright (C) 2018       Nicolas ZABOURI			<info@inovea-conseil.com>
      *
      * 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
    @@ -40,16 +40,34 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
      */
     class CommandeFournisseur extends CommonOrder
     {
    -    public $element='order_supplier';
    -    public $table_element='commande_fournisseur';
    -    public $table_element_line = 'commande_fournisseurdet';
    -    public $fk_element = 'fk_commande';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='order_supplier';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='commande_fournisseur';
    +
    +    /**
    +	 * @var int    Name of subtable line
    +	 */
    +	public $table_element_line = 'commande_fournisseurdet';
    +
    +    /**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element = 'fk_commande';
    +
         public $picto='order';
    +
         /**
          * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
          * @var int
          */
         public $ismultientitymanaged = 1;
    +
         /**
          * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
          * @var integer
    @@ -61,13 +79,17 @@ class CommandeFournisseur extends CommonOrder
          */
         protected $table_ref_field = 'ref';
     
    -    public $id;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
     	/**
     	 * Supplier order reference
     	 * @var string
     	 */
         public $ref;
    +
         public $ref_supplier;
         public $brouillon;
         public $statut;			// 0=Draft -> 1=Validated -> 2=Approved -> 3=Ordered/Process runing -> 4=Received partially -> 5=Received totally -> (reopen) 4=Received partially
    @@ -89,24 +111,37 @@ class CommandeFournisseur extends CommonOrder
          * Delivery date
          */
         public $date_livraison;
    +
         public $total_ht;
         public $total_tva;
         public $total_localtax1;   // Total Local tax 1
         public $total_localtax2;   // Total Local tax 2
         public $total_ttc;
         public $source;
    +
     	/**
     	 * @deprecated
     	 * @see note_private, note_public
     	 */
         public $note;
    +
     	public $note_private;
         public $note_public;
         public $model_pdf;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_project;
    +
         public $cond_reglement_id;
         public $cond_reglement_code;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_account;
    +
         public $mode_reglement_id;
         public $mode_reglement_code;
         public $user_author_id;
    @@ -125,13 +160,18 @@ class CommandeFournisseur extends CommonOrder
     	 * @var CommandeFournisseurLigne[]
     	 */
     	public $lines = array();
    +
     	//Add for supplier_proposal
         public $origin;
         public $origin_id;
         public $linked_objects=array();
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
         public $fk_multicurrency;
    +
         public $multicurrency_code;
         public $multicurrency_tx;
         public $multicurrency_total_ht;
    @@ -142,34 +182,42 @@ class CommandeFournisseur extends CommonOrder
     	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
    +
     	/**
     	 * Validated status
     	 */
     	const STATUS_VALIDATED = 1;
    +
     	/**
     	 * Accepted
     	 */
     	const STATUS_ACCEPTED = 2;
    +
     	/**
     	 * Order sent, shipment on process
     	 */
     	const STATUS_ORDERSENT = 3;
    +
     	/**
     	 * Received partially
     	 */
     	const STATUS_RECEIVED_PARTIALLY = 4;
    +
     	/**
     	 * Received completely
     	 */
     	const STATUS_RECEIVED_COMPLETELY = 5;
    +
     	/**
     	 * Order canceled
     	 */
     	const STATUS_CANCELED = 6;
    +
     	/**
     	 * Order canceled/never received
     	 */
     	const STATUS_CANCELED_AFTER_ORDER = 7;
    +
     	/**
     	 * Refused
     	 */
    @@ -198,7 +246,7 @@ class CommandeFournisseur extends CommonOrder
          * 	@param	string	$ref		Ref of object
          *	@return int 		        >0 if OK, <0 if KO, 0 if not found
          */
    -    public function fetch($id,$ref='')
    +    public function fetch($id, $ref='')
         {
             global $conf;
     
    @@ -325,6 +373,7 @@ class CommandeFournisseur extends CommonOrder
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Load array lines
          *
    @@ -333,6 +382,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function fetch_lines($only_product=0)
         {
    +        // phpcs:enable
         	//$result=$this->fetch_lines();
         	$this->lines=array();
     
    @@ -564,6 +614,7 @@ class CommandeFournisseur extends CommonOrder
             return $this->LibStatut($this->statut,$mode,$this->billed);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return label of a status
          *
    @@ -574,6 +625,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function LibStatut($statut,$mode=0,$billed=0)
         {
    +        // phpcs:enable
         	global $conf, $langs;
     
         	if (empty($this->statuts) || empty($this->statutshort))
    @@ -612,46 +664,46 @@ class CommandeFournisseur extends CommonOrder
             {
                 return $langs->trans($this->statuts[$statut]);
             }
    -        if ($mode == 1)
    +        elseif ($mode == 1)
             {
             	return $langs->trans($this->statutshort[$statut]);
             }
    -        if ($mode == 2)
    +        elseif ($mode == 2)
             {
                 return $langs->trans($this->statuts[$statut]);
             }
    -        if ($mode == 3)
    +        elseif ($mode == 3)
             {
                 if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0');
    -            if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1');
    -            if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
    -            if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
    -            if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
    -            if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6');
    -            if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5');
    -            if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5');
    +            elseif ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1');
    +            elseif ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
    +            elseif ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
    +            elseif ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3');
    +            elseif ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6');
    +            elseif ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5');
    +            elseif ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5');
             }
    -        if ($mode == 4)
    +        elseif ($mode == 4)
             {
                 if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    -            if ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==3) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==4) return img_picto($langs->trans($this->statuts[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==5) return img_picto($langs->trans($this->statuts[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==6 || $statut==7) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
    +            elseif ($statut==9) return img_picto($langs->trans($this->statuts[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]).($billedtext?' - '.$billedtext:'');
             }
    -        if ($mode == 5)
    +        elseif ($mode == 5)
             {
             	if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut0');
    -        	if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut1');
    -        	if ($statut==2) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3');
    -        	if ($statut==3) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3');
    -        	if ($statut==4) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3');
    -        	if ($statut==5) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6');
    -        	if ($statut==6 || $statut==7) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5');
    -        	if ($statut==9) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5');
    +        	elseif ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut1');
    +        	elseif ($statut==2) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3');
    +        	elseif ($statut==3) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3');
    +        	elseif ($statut==4) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut3');
    +        	elseif ($statut==5) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut6');
    +        	elseif ($statut==6 || $statut==7) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5');
    +        	elseif ($statut==9) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut5');
             }
         }
     
    @@ -1026,6 +1078,7 @@ class CommandeFournisseur extends CommonOrder
             return $result ;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Cancel an approved order.
          *	The cancellation is done after approval
    @@ -1036,6 +1089,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function Cancel($user, $idwarehouse=-1)
         {
    +        // phpcs:enable
             global $langs,$conf;
     
     		$error=0;
    @@ -1086,7 +1140,6 @@ class CommandeFournisseur extends CommonOrder
             }
         }
     
    -
         /**
          * 	Submit a supplier order to supplier
          *
    @@ -1945,6 +1998,7 @@ class CommandeFournisseur extends CommonOrder
     		}
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Get list of order methods
          *
    @@ -1952,6 +2006,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function get_methodes_commande()
         {
    +        // phpcs:enable
             $sql = "SELECT rowid, libelle";
             $sql.= " FROM ".MAIN_DB_PREFIX."c_input_method";
             $sql.= " WHERE active = 1";
    @@ -2030,6 +2085,7 @@ class CommandeFournisseur extends CommonOrder
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Set a delivery in database for this supplier order
          *
    @@ -2041,6 +2097,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function Livraison($user, $date, $type, $comment)
         {
    +        // phpcs:enable
         	global $conf, $langs;
     
             $result = 0;
    @@ -2075,7 +2132,6 @@ class CommandeFournisseur extends CommonOrder
     		    			$this->errors[]='ErrorCantSetReceptionToTotalDoneWithReceptionToApprove';
     		    			dol_syslog('ErrorCantSetReceptionToTotalDoneWithReceptionToApprove', LOG_DEBUG);
     		    		}
    -
     		    	}
     	    		if (! $error && ! empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS_NEED_APPROVE) && ($type == 'tot'))	// Accept to move to reception done, only if status of all line are ok (refuse denied)
     	    		{
    @@ -2146,7 +2202,8 @@ class CommandeFournisseur extends CommonOrder
             return $result ;
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *	Set the planned delivery date
          *
          *	@param      User			$user        		Objet user making change
    @@ -2156,6 +2213,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function set_date_livraison($user, $date_livraison, $notrigger=0)
         {
    +        // phpcs:enable
             if ($user->rights->fournisseur->commande->creer)
             {
             	$error=0;
    @@ -2210,6 +2268,7 @@ class CommandeFournisseur extends CommonOrder
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *	Set the id projet
          *
    @@ -2220,6 +2279,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function set_id_projet($user, $id_projet, $notrigger=0)
         {
    +        // phpcs:enable
             if ($user->rights->fournisseur->commande->creer)
             {
             	$error=0;
    @@ -2669,6 +2729,7 @@ class CommandeFournisseur extends CommonOrder
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Charge indicateurs this->nb de tableau de bord
          *
    @@ -2676,6 +2737,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function load_state_board()
         {
    +        // phpcs:enable
             global $conf, $user;
     
             $this->nb=array();
    @@ -2710,6 +2772,7 @@ class CommandeFournisseur extends CommonOrder
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
    @@ -2718,6 +2781,7 @@ class CommandeFournisseur extends CommonOrder
          */
         function load_board($user)
         {
    +        // phpcs:enable
             global $conf, $langs;
     
             $clause = " WHERE";
    @@ -2812,7 +2876,7 @@ class CommandeFournisseur extends CommonOrder
     	 *  @param      int			$hidedetails    Hide details of lines
     	 *  @param      int			$hidedesc       Hide description
     	 *  @param      int			$hideref        Hide ref
    -         *  @param   null|array  $moreparams     Array to provide more information
    +     *  @param      null|array  $moreparams     Array to provide more information
     	 *  @return     int          				0 if KO, 1 if OK
     	 */
     	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
    @@ -3023,7 +3087,6 @@ class CommandeFournisseur extends CommonOrder
     							{
     								$close++;
     							}
    -
     						}
     					}
     
    @@ -3047,8 +3110,6 @@ class CommandeFournisseur extends CommonOrder
     							}
     							return 4;
     						}
    -
    -
     					}
     					else
     					{//all the products are not received
    @@ -3058,7 +3119,6 @@ class CommandeFournisseur extends CommonOrder
     						}
     						return 4;
     					}
    -
     				}
         				else
         				{
    @@ -3084,7 +3144,14 @@ class CommandeFournisseur extends CommonOrder
      */
     class CommandeFournisseurLigne extends CommonOrderLine
     {
    -    public $element='commande_fournisseurdet';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='commande_fournisseurdet';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='commande_fournisseurdet';
     
         public $oldline;
    @@ -3096,9 +3163,21 @@ class CommandeFournisseurLigne extends CommonOrderLine
         public $fk_commande;
     
         // From llx_commande_fournisseurdet
    +    /**
    +     * @var int ID
    +     */
         public $fk_parent_line;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_facture;
    +
    +    /**
    +     * @var string supplier order line label
    +     */
         public $label;
    +
         public $rang = 0;
         public $special_code = 0;
     
    @@ -3475,4 +3554,3 @@ class CommandeFournisseurLigne extends CommonOrderLine
             }
         }
     }
    -
    diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php
    index a72e225b535..c7b5d00c797 100644
    --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php
    +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php
    @@ -24,9 +24,9 @@
      */
     
     // Put here all includes required by your class file
    -require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
    -//require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    -//require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    +require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
    +//require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
    +//require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
     
     
     /**
    @@ -34,24 +34,72 @@ require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
      */
     class CommandeFournisseurDispatch extends CommonObject
     {
    -	public $db;							//!< To store db handler
    -	public $error;							//!< To return error code (or message)
    -	public $errors=array();				//!< To return several error codes (or messages)
    -	public $element='commandefournisseurdispatch';			//!< Id that identify managed objects
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error;
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='commandefournisseurdispatch';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='commande_fournisseur_dispatch';		//!< Name of table without prefix where object is stored
     	public $lines=array();
     
    -    public $id;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_commande;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_commandefourndet;
    +
     	public $qty;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_entrepot;
    +
    +	/**
    +	 * @var int User ID
    +	 */
     	public $fk_user;
    +
     	public $datec='';
     	public $comment;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	public $tms='';
     	public $batch;
     	public $eatby='';
    @@ -76,8 +124,6 @@ class CommandeFournisseurDispatch extends CommonObject
             $this->statutshort[0] = 'Received';
             $this->statutshort[1] = 'Verified';
             $this->statutshort[2] = 'Denied';
    -
    -        return 1;
         }
     
     
    @@ -233,8 +279,6 @@ class CommandeFournisseurDispatch extends CommonObject
     				$this->batch = $obj->batch;
     				$this->eatby = $this->db->jdate($obj->eatby);
     				$this->sellby = $this->db->jdate($obj->sellby);
    -
    -
                 }
                 $this->db->free($resql);
     
    @@ -460,6 +504,7 @@ class CommandeFournisseurDispatch extends CommonObject
             return $this->LibStatut($this->status,$mode);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return label of a status
          *
    @@ -469,6 +514,7 @@ class CommandeFournisseurDispatch extends CommonObject
          */
         function LibStatut($statut,$mode=0)
         {
    +        // phpcs:enable
             global $langs;
             $langs->load('orders');
     
    @@ -476,27 +522,27 @@ class CommandeFournisseurDispatch extends CommonObject
             {
                 return $langs->trans($this->statuts[$statut]);
             }
    -        if ($mode == 1)
    +        elseif ($mode == 1)
             {
                 return $langs->trans($this->statutshort[$statut]);
             }
    -        if ($mode == 2)
    +        elseif ($mode == 2)
             {
                 return $langs->trans($this->statuts[$statut]);
             }
    -        if ($mode == 3)
    +        elseif ($mode == 3)
             {
                 if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0');
                 if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4');
                 if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut8');
             }
    -        if ($mode == 4)
    +        elseif ($mode == 4)
             {
                 if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
                 if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
                 if ($statut==2) return img_picto($langs->trans($this->statuts[$statut]),'statut8').' '.$langs->trans($this->statuts[$statut]);
             }
    -        if ($mode == 5)
    +        elseif ($mode == 5)
             {
                 if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut0');
                 if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans($this->statutshort[$statut]).' </span>'.img_picto($langs->trans($this->statuts[$statut]),'statut4');
    @@ -528,8 +574,6 @@ class CommandeFournisseurDispatch extends CommonObject
     		$this->batch='';
     		$this->eatby='';
     		$this->sellby='';
    -
    -
     	}
     
     	/**
    @@ -627,5 +671,4 @@ class CommandeFournisseurDispatch extends CommonObject
     			return - 1;
     		}
     	}
    -
     }
    diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php
    index 7f5496094f7..58230038fcc 100644
    --- a/htdocs/fourn/class/fournisseur.facture.class.php
    +++ b/htdocs/fourn/class/fournisseur.facture.class.php
    @@ -5,13 +5,13 @@
      * Copyright (C) 2005		Marc Barilley			<marc@ocebo.com>
      * Copyright (C) 2005-2012	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2010-2017	Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2013		Philippe Grand			<philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018	Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
      * Copyright (C) 2014-2016	Marcos García			<marcosgdf@gmail.com>
      * Copyright (C) 2015		Bahfir Abbes			<bafbes@gmail.com>
      * Copyright (C) 2015		Ferran Marcet			<fmarcet@2byte.es>
      * Copyright (C) 2016		Alexandre Spangaro		<aspangaro@zendsi.com>
    - * Copyright (C) 2018           Nicolas ZABOURI			<info@inovea-conseil.com>
    + * Copyright (C) 2018       Nicolas ZABOURI			<info@inovea-conseil.com>
      *
      * 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
    @@ -41,16 +41,34 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
      */
     class FactureFournisseur extends CommonInvoice
     {
    -    public $element='invoice_supplier';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='invoice_supplier';
    +
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element='facture_fourn';
    -    public $table_element_line='facture_fourn_det';
    -    public $fk_element='fk_facture_fourn';
    +
    +    /**
    +	 * @var int    Name of subtable line
    +	 */
    +	public $table_element_line='facture_fourn_det';
    +
    +    /**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element='fk_facture_fourn';
    +
         public $picto='bill';
    +
         /**
          * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
          * @var int
          */
         public $ismultientitymanaged = 1;
    +
         /**
          * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
          * @var integer
    @@ -62,8 +80,16 @@ class FactureFournisseur extends CommonInvoice
          */
         protected $table_ref_field = 'ref';
     
    -    public $rowid;
    -    public $ref;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $rowid;
    +
    +    /**
    +	 * @var string Ref
    +	 */
    +	public $ref;
    +
         public $product_ref;
         public $ref_supplier;
         public $socid;
    @@ -100,17 +126,24 @@ class FactureFournisseur extends CommonInvoice
         public $total_localtax1=0;
         public $total_localtax2=0;
         public $total_ttc=0;
    -    /**
    +
    +	/**
     	 * @deprecated
     	 * @see note_private, note_public
     	 */
         public $note;
    +
         public $note_private;
         public $note_public;
         public $propalid;
         public $cond_reglement_id;
         public $cond_reglement_code;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_account;
    +
         public $mode_reglement_id;
         public $mode_reglement_code;
     
    @@ -119,26 +152,37 @@ class FactureFournisseur extends CommonInvoice
     	 * @var SupplierInvoiceLine[]
     	 */
         public $lines = array();
    +
     	/**
     	 * @deprecated
     	 */
         public $fournisseur;
     
    -	//Incorterms
    +	/**
    +     * @var int ID Incorterms
    +     */
         public $fk_incoterms;
    +
         public $location_incoterms;
         public $libelle_incoterms;  //Used into tooltip
     
         public $extraparams=array();
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
         public $fk_multicurrency;
    +
         public $multicurrency_code;
         public $multicurrency_tx;
         public $multicurrency_total_ht;
         public $multicurrency_total_tva;
         public $multicurrency_total_ttc;
         //! id of source invoice if replacement invoice or credit note
    +    /**
    +     * @var int ID
    +     */
         public $fk_facture_source;
     
         /**
    @@ -636,7 +680,6 @@ class FactureFournisseur extends CommonInvoice
                         $this->error=$this->db->lasterror();
                         return -3;
                     }
    -
                 }
                 else
                 {
    @@ -656,13 +699,15 @@ class FactureFournisseur extends CommonInvoice
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Load this->lines
          *
    -     *	@return     int         1 si ok, < 0 si erreur
    +     *  @return     int         1 si ok, < 0 si erreur
          */
         function fetch_lines()
         {
    +        // phpcs:enable
         	$this->lines = array();
     
             $sql = 'SELECT f.rowid, f.ref as ref_supplier, f.description, f.date_start, f.date_end, f.pu_ht, f.pu_ttc, f.qty, f.remise_percent, f.vat_src_code, f.tva_tx';
    @@ -881,6 +926,7 @@ class FactureFournisseur extends CommonInvoice
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Add a discount line into an invoice (as an invoice line) using an existing absolute discount (Consume the discount)
          *
    @@ -889,6 +935,7 @@ class FactureFournisseur extends CommonInvoice
          */
         function insert_discount($idremise)
         {
    +        // phpcs:enable
         	global $langs;
     
         	include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    @@ -1132,8 +1179,9 @@ class FactureFournisseur extends CommonInvoice
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *	Tag invoice as a payed invoice
    +     *  Tag invoice as a payed invoice
          *
          *	@param  User	$user       Object user
     	 *	@param  string	$close_code	Code renseigne si on classe a payee completement alors que paiement incomplet. Not implementd yet.
    @@ -1142,6 +1190,7 @@ class FactureFournisseur extends CommonInvoice
          */
         function set_paid($user, $close_code='', $close_note='')
         {
    +        // phpcs:enable
             global $conf,$langs;
             $error=0;
     
    @@ -1180,6 +1229,7 @@ class FactureFournisseur extends CommonInvoice
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Tag la facture comme non payee completement + appel trigger BILL_UNPAYED
          *	Fonction utilisee quand un paiement prelevement est refuse,
    @@ -1190,6 +1240,7 @@ class FactureFournisseur extends CommonInvoice
          */
         function set_unpaid($user)
         {
    +        // phpcs:enable
             global $conf,$langs;
             $error=0;
     
    @@ -1391,6 +1442,7 @@ class FactureFournisseur extends CommonInvoice
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Set draft status
          *
    @@ -1400,6 +1452,7 @@ class FactureFournisseur extends CommonInvoice
          */
         function set_draft($user, $idwarehouse=-1)
         {
    +        // phpcs:enable
             global $conf,$langs;
     
             $error=0;
    @@ -1955,15 +2008,17 @@ class FactureFournisseur extends CommonInvoice
             }
         }
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
     	 *	Renvoi liste des factures remplacables
     	 *	Statut validee ou abandonnee pour raison autre + non payee + aucun paiement + pas deja remplacee
     	 *
    -	 *	@param		int		$socid		Id societe
    +	 *	@param      int		$socid		Id societe
     	 *	@return    	array				Tableau des factures ('id'=>id, 'ref'=>ref, 'status'=>status, 'paymentornot'=>0/1)
    -	 */
    +     */
     	function list_replacable_supplier_invoices($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$return = array();
    @@ -2001,6 +2056,7 @@ class FactureFournisseur extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoi liste des factures qualifiables pour correction par avoir
     	 *	Les factures qui respectent les regles suivantes sont retournees:
    @@ -2011,6 +2067,7 @@ class FactureFournisseur extends CommonInvoice
     	 */
     	function list_qualified_avoir_supplier_invoices($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$return = array();
    @@ -2051,6 +2108,7 @@ class FactureFournisseur extends CommonInvoice
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
    @@ -2059,6 +2117,7 @@ class FactureFournisseur extends CommonInvoice
          */
         function load_board($user)
         {
    +        // phpcs:enable
             global $conf, $langs;
     
             $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut';
    @@ -2347,13 +2406,15 @@ class FactureFournisseur extends CommonInvoice
             $this->total_ttc      = $xnbp*119.6;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
     	 *      @return         int     <0 if KO, >0 if OK
    -	 */
    +     */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		$this->nb=array();
    @@ -2563,7 +2624,14 @@ class FactureFournisseur extends CommonInvoice
      */
     class SupplierInvoiceLine extends CommonObjectLine
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='facture_fourn_det';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='facture_fourn_det';
     
     	public $oldline;
    @@ -2573,6 +2641,7 @@ class SupplierInvoiceLine extends CommonObjectLine
     	 * @see product_ref
     	 */
     	public $ref;
    +
     	/**
     	 * Internal ref
     	 * @var string
    @@ -2591,6 +2660,7 @@ class SupplierInvoiceLine extends CommonObjectLine
     	 * @see label
     	 */
     	public $libelle;
    +
     	/**
     	 * Product description
     	 * @var string
    @@ -2604,6 +2674,7 @@ class SupplierInvoiceLine extends CommonObjectLine
     	 * @see subprice
     	 */
     	public $pu_ht;
    +
     	public $subprice;
     
     	/**
    @@ -2619,6 +2690,7 @@ class SupplierInvoiceLine extends CommonObjectLine
     	 * @see total_tva
     	 */
     	public $tva;
    +
     	public $total_tva;
     
     	/**
    @@ -2664,18 +2736,32 @@ class SupplierInvoiceLine extends CommonObjectLine
     	public $total_ttc;
     	public $total_localtax1;
     	public $total_localtax2;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
     	public $product_type;
     	public $product_label;
     	public $info_bits;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_parent_line;
    +
     	public $special_code;
     	public $rang;
     	public $localtax1_type;
     	public $localtax2_type;
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     	public $multicurrency_subprice;
     	public $multicurrency_total_ht;
    @@ -2760,10 +2846,10 @@ class SupplierInvoiceLine extends CommonObjectLine
     		$this->rang       		= $obj->rang;
     		$this->fk_unit           = $obj->fk_unit;
     
    -		$this->multicurrency_subprice	= $obj->multicurrency_subprice;
    -		$this->multicurrency_total_ht	= $obj->multicurrency_total_ht;
    -		$this->multicurrency_total_tva	= $obj->multicurrency_total_tva;
    -		$this->multicurrency_total_ttc	= $obj->multicurrency_total_ttc;
    +		$this->multicurrency_subprice = $obj->multicurrency_subprice;
    +		$this->multicurrency_total_ht = $obj->multicurrency_total_ht;
    +		$this->multicurrency_total_tva = $obj->multicurrency_total_tva;
    +		$this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
     
     		$this->fetch_optionals();
     
    @@ -3065,7 +3151,6 @@ class SupplierInvoiceLine extends CommonObjectLine
     
                 $this->db->commit();
                 return $this->id;
    -
             }
             else
             {
    @@ -3074,13 +3159,16 @@ class SupplierInvoiceLine extends CommonObjectLine
                 return -2;
             }
         }
    -            /**
    +
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Mise a jour de l'objet ligne de commande en base
          *
          *  @return		int		<0 si ko, >0 si ok
          */
         function update_total()
         {
    +        // phpcs:enable
             $this->db->begin();
     
             // Mise a jour ligne en base
    diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php
    index 5c50597195a..a86e728e028 100644
    --- a/htdocs/fourn/class/fournisseur.product.class.php
    +++ b/htdocs/fourn/class/fournisseur.product.class.php
    @@ -37,49 +37,70 @@ require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.
      */
     class ProductFournisseur extends Product
     {
    -    var $db;
    -    var $error;
    -
    -    var $product_fourn_price_id;  // id of ligne product-supplier
    -
    -    var $id;                      // product id
    -	/**
    -	 * @deprecated
    -	 * @see ref_supplier
    -	 */
    -    var $fourn_ref;
    -    var $delivery_time_days;
    -    var $ref_supplier;			  // ref supplier (can be set by get_buyprice)
    -    var $vatrate_supplier;		  // default vat rate for this supplier/qty/product (can be set by get_buyprice)
    -
    -    var $fourn_id;                //supplier id
    -    var $fourn_qty;               // quantity for price (can be set by get_buyprice)
    -    var $fourn_pu;			       // unit price for quantity (can be set by get_buyprice)
    -
    -    var $fourn_price;             // price for quantity
    -    var $fourn_remise_percent;    // discount for quantity (percent)
    -    var $fourn_remise;            // discount for quantity (amount)
    -    var $product_fourn_id;        // supplier id
    -    var $fk_availability;         // availability delay - visible/used if option FOURN_PRODUCT_AVAILABILITY is on (duplicate information compared to delivery delay)
    -    var $fourn_unitprice;
    -    var $fourn_tva_tx;
    -    var $fourn_tva_npr;
    -
    -    var $fk_supplier_price_expression;
    -    var $supplier_reputation;     // reputation of supplier
    -    var $reputations=array();     // list of available supplier reputations
    -
    -    // Multicurreny
    -    var $fourn_multicurrency_id;
    -    var $fourn_multicurrency_code;
    -    var $fourn_multicurrency_tx;
    -    var $fourn_multicurrency_price;
    -    var $fourn_multicurrency_unitprice;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
         /**
    -	 *	Constructor
    -	 *
    -	 *  @param		DoliDB		$db      Database handler
    +     * @var string Error code (or message)
    +     */
    +    public $error='';
    +
    +    public $product_fourn_price_id;  // id of ligne product-supplier
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $id;
    +
    +    /**
    +     * @deprecated
    +     * @see ref_supplier
    +     */
    +    public $fourn_ref;
    +    public $delivery_time_days;
    +    public $ref_supplier;			  // ref supplier (can be set by get_buyprice)
    +    public $desc_supplier;
    +    public $vatrate_supplier;		  // default vat rate for this supplier/qty/product (can be set by get_buyprice)
    +
    +    public $fourn_id;                //supplier id
    +    public $fourn_qty;               // quantity for price (can be set by get_buyprice)
    +    public $fourn_pu;			       // unit price for quantity (can be set by get_buyprice)
    +
    +    public $fourn_price;             // price for quantity
    +    public $fourn_remise_percent;    // discount for quantity (percent)
    +    public $fourn_remise;            // discount for quantity (amount)
    +    public $product_fourn_id;        // supplier id
    +
    +    /**
    +     * @var int ID availability delay - visible/used if option FOURN_PRODUCT_AVAILABILITY is on (duplicate information compared to delivery delay)
    +     */
    +    public $fk_availability;
    +
    +    public $fourn_unitprice;
    +    public $fourn_tva_tx;
    +    public $fourn_tva_npr;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_supplier_price_expression;
    +
    +    public $supplier_reputation;     // reputation of supplier
    +    public $reputations=array();     // list of available supplier reputations
    +
    +    // Multicurreny
    +    public $fourn_multicurrency_id;
    +    public $fourn_multicurrency_code;
    +    public $fourn_multicurrency_tx;
    +    public $fourn_multicurrency_price;
    +    public $fourn_multicurrency_unitprice;
    +
    +    /**
    +     *	Constructor
    +     *
    +     *  @param		DoliDB		$db      Database handler
          */
         function __construct($db)
         {
    @@ -92,6 +113,7 @@ class ProductFournisseur extends Product
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Remove all prices for this couple supplier-product
          *
    @@ -100,6 +122,7 @@ class ProductFournisseur extends Product
          */
         function remove_fournisseur($id_fourn)
         {
    +        // phpcs:enable
             $ok=1;
     
             $this->db->begin();
    @@ -128,6 +151,7 @@ class ProductFournisseur extends Product
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Remove a price for a couple supplier-product
          *
    @@ -136,6 +160,7 @@ class ProductFournisseur extends Product
          */
         function remove_product_fournisseur_price($rowid)
         {
    +        // phpcs:enable
             global $conf, $user;
     
             $error=0;
    @@ -162,17 +187,17 @@ class ProductFournisseur extends Product
                 }
             }
     
    -        if (empty($error)){
    +        if (empty($error)) {
                 $this->db->commit();
                 return 1;
    -        }else{
    +        } else {
                 $this->db->rollback();
                 return -1;
             }
    -
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Modify the purchase price for a supplier
          *
    @@ -196,10 +221,12 @@ class ProductFournisseur extends Product
          *    @param  	string		$multicurrency_price_base_type	HT or TTC in currency
          *    @param  	float		$multicurrency_tx	            Rate currency
          *    @param  	string		$multicurrency_code	            Currency code
    +     *    @param  	string		$desc_fourn     	            Custom description for product_fourn_price
          *    @return	int								<0 if KO, >=0 if OK
          */
    -    function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0, $supplier_reputation='', $localtaxes_array=array(), $newdefaultvatcode='', $multicurrency_buyprice=0, $multicurrency_price_base_type='HT',$multicurrency_tx=1,$multicurrency_code='')
    +    function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0, $supplier_reputation='', $localtaxes_array=array(), $newdefaultvatcode='', $multicurrency_buyprice=0, $multicurrency_price_base_type='HT',$multicurrency_tx=1,$multicurrency_code='', $desc_fourn='')
         {
    +        // phpcs:enable
             global $conf, $langs;
             //global $mysoc;
     
    @@ -270,6 +297,7 @@ class ProductFournisseur extends Product
     	  		$sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
     			$sql.= " SET fk_user = " . $user->id." ,";
                 $sql.= " ref_fourn = '" . $this->db->escape($ref_fourn) . "',";
    +            $sql.= " desc_fourn = '" . $this->db->escape($desc_fourn) . "',";
     			$sql.= " price = ".price2num($buyprice).",";
     			$sql.= " quantity = ".$qty.",";
     			$sql.= " remise_percent = ".$remise_percent.",";
    @@ -336,7 +364,7 @@ class ProductFournisseur extends Product
                     // Add price for this quantity to supplier
                     $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price(";
                     $sql.= " multicurrency_price, multicurrency_unitprice, multicurrency_tx, fk_multicurrency, multicurrency_code,";
    -                $sql .= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation)";
    +                $sql .= "datec, fk_product, fk_soc, ref_fourn, desc_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation)";
                     $sql .= " values(";
                     $sql.= (isset($multicurrency_buyprice)?"'".$this->db->escape(price2num($multicurrency_buyprice))."'":'null').",";
                     $sql.= (isset($multicurrency_unitBuyPrice)?"'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'":'null').",";
    @@ -347,6 +375,7 @@ class ProductFournisseur extends Product
                     $sql .= " " . $this->id . ",";
                     $sql .= " " . $fourn->id . ",";
                     $sql .= " '" . $this->db->escape($ref_fourn) . "',";
    +                $sql .= " '" . $this->db->escape($desc_fourn) . "',";
                     $sql .= " " . $user->id . ",";
                     $sql .= " " . $buyprice . ",";
                     $sql .= " " . $qty . ",";
    @@ -424,6 +453,7 @@ class ProductFournisseur extends Product
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Loads the price information of a provider
          *
    @@ -433,10 +463,11 @@ class ProductFournisseur extends Product
          */
         function fetch_product_fournisseur_price($rowid, $ignore_expression = 0)
         {
    +        // phpcs:enable
             global $conf;
     
             $sql = "SELECT pfp.rowid, pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.default_vat_code, pfp.info_bits as fourn_tva_npr, pfp.fk_availability,";
    -        $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.fk_product, pfp.charges, pfp.fk_supplier_price_expression, pfp.delivery_time_days,";
    +        $sql.= " pfp.fk_soc, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_product, pfp.charges, pfp.fk_supplier_price_expression, pfp.delivery_time_days,";
             $sql.= " pfp.supplier_reputation";
             $sql.= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code";
             $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
    @@ -456,6 +487,7 @@ class ProductFournisseur extends Product
                 	$this->fourn_id					= $obj->fk_soc;
                 	$this->fourn_ref				= $obj->ref_fourn; // deprecated
     	            $this->ref_supplier             = $obj->ref_fourn;
    +	            $this->desc_supplier            = $obj->desc_fourn;
                 	$this->fourn_price				= $obj->price;
                 	$this->fourn_charges            = $obj->charges;	// deprecated
                 	$this->fourn_qty                = $obj->quantity;
    @@ -510,6 +542,7 @@ class ProductFournisseur extends Product
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    List all supplier prices of a product
          *
    @@ -522,10 +555,11 @@ class ProductFournisseur extends Product
          */
         function list_product_fournisseur_price($prodid, $sortfield='', $sortorder='', $limit=0, $offset=0)
         {
    +        // phpcs:enable
             global $conf;
     
             $sql = "SELECT s.nom as supplier_name, s.rowid as fourn_id,";
    -        $sql.= " pfp.rowid as product_fourn_pri_id, pfp.ref_fourn, pfp.fk_product as product_fourn_id, pfp.fk_supplier_price_expression,";
    +        $sql.= " pfp.rowid as product_fourn_pri_id, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_product as product_fourn_id, pfp.fk_supplier_price_expression,";
             $sql.= " pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability, pfp.charges, pfp.info_bits, pfp.delivery_time_days, pfp.supplier_reputation";
             $sql.= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code";
             $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
    @@ -553,6 +587,7 @@ class ProductFournisseur extends Product
                     $prodfourn->product_fourn_id		= $record["product_fourn_id"];
                     $prodfourn->fourn_ref				= $record["ref_fourn"];
                     $prodfourn->ref_supplier			= $record["ref_fourn"];
    +                $prodfourn->desc_supplier           = $record["desc_fourn"];
                     $prodfourn->fourn_price				= $record["price"];
                     $prodfourn->fourn_qty				= $record["quantity"];
     				$prodfourn->fourn_remise_percent	= $record["remise_percent"];
    @@ -609,6 +644,7 @@ class ProductFournisseur extends Product
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Load properties for minimum price
          *
    @@ -619,6 +655,7 @@ class ProductFournisseur extends Product
          */
         function find_min_price_product_fournisseur($prodid, $qty=0, $socid=0)
         {
    +        // phpcs:enable
             global $conf;
     
             if (empty($prodid))
    @@ -796,6 +833,7 @@ class ProductFournisseur extends Product
             return $thirdparty->getNomUrl($withpicto,$option,$maxlen,$notooltip);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Display price of product
          *
    @@ -803,12 +841,13 @@ class ProductFournisseur extends Product
          *  @param  int     $showsuptitle     Show "Supplier" into output string
          *  @param  int     $maxlen           Max length of name
          *  @param  integer $notooltip        1=Disable tooltip
    -     *  @param  array   $productFournList  list of ProductFournisseur objects
    +     *  @param  array   $productFournList list of ProductFournisseur objects
          *                                    to display in table format.
          *  @return string                    String with supplier price
          */
         function display_price_product_fournisseur($showunitprice=1,$showsuptitle=1,$maxlen=0,$notooltip=0, $productFournList=array())
         {
    +        // phpcs:enable
             global $langs;
     
             $out = '';
    @@ -848,6 +887,4 @@ class ProductFournisseur extends Product
     
     		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
     	}
    -
     }
    -
    diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php
    index 494196e9c2d..a366faa0400 100644
    --- a/htdocs/fourn/class/paiementfourn.class.php
    +++ b/htdocs/fourn/class/paiementfourn.class.php
    @@ -35,8 +35,16 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
      */
     class PaiementFourn extends Paiement
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='payment_supplier';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='paiementfourn';
    +
     	public $picto = 'payment';
     
     	var $statut;        //Status of payment. 0 = unvalidated; 1 = validated
    @@ -254,7 +262,6 @@ class PaiementFourn extends Paiement
     							$this->error=$this->db->lasterror();
     							$error++;
     						}
    -
     					}
     					else
     					{
    @@ -497,6 +504,7 @@ class PaiementFourn extends Paiement
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoi le libelle d'un statut donne
     	 *
    @@ -506,6 +514,7 @@ class PaiementFourn extends Paiement
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$langs->load('compta');
    @@ -761,14 +770,16 @@ class PaiementFourn extends Paiement
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *    	Load the third party of object, from id into this->thirdparty
    +	 *  Load the third party of object, from id into this->thirdparty
     	 *
    -	 *		@param		int		$force_thirdparty_id	Force thirdparty id
    -	 *		@return		int								<0 if KO, >0 if OK
    +	 *	@param		int		$force_thirdparty_id	Force thirdparty id
    +	 *	@return		int								<0 if KO, >0 if OK
     	 */
     	function fetch_thirdparty($force_thirdparty_id=0)
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
     
     		if (empty($force_thirdparty_id))
    @@ -786,5 +797,4 @@ class PaiementFourn extends Paiement
     
     		return parent::fetch_thirdparty($force_thirdparty_id);
     	}
    -
     }
    diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
    index 9009364d4b1..70fcaf004fb 100644
    --- a/htdocs/fourn/commande/card.php
    +++ b/htdocs/fourn/commande/card.php
    @@ -4,10 +4,11 @@
      * Copyright (C) 2005      Eric	Seigne          <eric.seigne@ryxeo.com>
      * Copyright (C) 2005-2016 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2010-2015 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2011-2015 Philippe Grand       <philippe.grand@atoo-net.com>
    + * Copyright (C) 2011-2018 Philippe Grand       <philippe.grand@atoo-net.com>
      * Copyright (C) 2012-2016 Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2013      Florian Henry        <florian.henry@open-concept.pro>
      * Copyright (C) 2014      Ion Agorria          <ion@agorria.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -220,7 +221,6 @@ if (empty($reshook))
     				//$newstatus=3;  // Submited
     				// TODO If there is at least one reception, we can set to Received->Received partially
     				$newstatus=4;  // Received partially
    -
     			}
     			else if ($object->statut == 6) $newstatus=2;	// Canceled->Approved
     			else if ($object->statut == 7) $newstatus=3;	// Canceled->Process running
    @@ -351,7 +351,7 @@ if (empty($reshook))
     				if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
     					$idprod = $res->fk_product_child;
     				} else {
    -					setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors');
    +					setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
     					$error ++;
     				}
     			}
    @@ -399,7 +399,11 @@ if (empty($reshook))
     			{
     				$label = $productsupplier->label;
     
    -				$desc = $productsupplier->description;
    +				// if we use supplier description of the products
    +				if(!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) {
    +				    $desc = $productsupplier->desc_supplier;
    +				} else $desc = $productsupplier->description;
    +
     				if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc);
     
     				$type = $productsupplier->type;
    @@ -695,7 +699,6 @@ if (empty($reshook))
     			dol_print_error($db,$object->error);
     			exit;
     			}
    -
     	}
     
     	// Remove a product line
    @@ -1438,7 +1441,6 @@ if ($action=='create')
     
     		// Object source contacts list
     		$srccontactslist = $objectsrc->liste_contact(- 1, 'external', 1);
    -
     	}
     	else
     	{
    @@ -1538,7 +1540,7 @@ if ($action=='create')
     	print '<td>';
     	$usehourmin=0;
     	if (! empty($conf->global->SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE)) $usehourmin=1;
    -	$form->select_date($datelivraison?$datelivraison:-1,'liv_',$usehourmin,$usehourmin,'',"set");
    +	print $form->selectDate($datelivraison?$datelivraison:-1, 'liv_', $usehourmin, $usehourmin, '', "set");
     	print '</td></tr>';
     
     	// Bank Account
    @@ -1695,7 +1697,6 @@ elseif (! empty($object->id))
     	if ($action	== 'delete')
     	{
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 2);
    -
     	}
     
     	// Clone confirmation
    @@ -1707,7 +1708,6 @@ elseif (! empty($object->id))
     		);
     		// Paiement incomplet. On demande si motif = escompte ou autre
     		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id,$langs->trans('CloneOrder'),$langs->trans('ConfirmCloneOrder',$object->ref),'confirm_clone',$formquestion,'yes',1);
    -
     	}
     
     	// Confirmation de la validation
    @@ -1786,14 +1786,12 @@ elseif (! empty($object->id))
     	if ($action	== 'refuse')
     	{
     		$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("DenyingThisOrder"),$langs->trans("ConfirmDenyingThisOrder",$object->ref),"confirm_refuse", '', 0, 1);
    -
     	}
     
     	// Confirmation de l'annulation
     	if ($action	== 'cancel')
     	{
     		$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id",$langs->trans("Cancel"),$langs->trans("ConfirmCancelThisOrder",$object->ref),"confirm_cancel", '', 0, 1);
    -
     	}
     
     	// Confirmation de l'envoi de la commande
    @@ -1801,7 +1799,6 @@ elseif (! empty($object->id))
     	{
     		$date_com = dol_mktime(GETPOST('rehour'),GETPOST('remin'),GETPOST('resec'),GETPOST("remonth"),GETPOST("reday"),GETPOST("reyear"));
     		$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id."&datecommande=".$date_com."&methode=".$_POST["methodecommande"]."&comment=".urlencode($_POST["comment"]), $langs->trans("MakeOrder"),$langs->trans("ConfirmMakeOrder",dol_print_date($date_com,'day')),"confirm_commande",'',0,2);
    -
     	}
     
     	// Confirmation to delete line
    @@ -2041,7 +2038,7 @@ elseif (! empty($object->id))
     		print '<input type="hidden" name="action" value="setdate_livraison">';
     		$usehourmin=0;
     		if (! empty($conf->global->SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE)) $usehourmin=1;
    -		$form->select_date($object->date_livraison?$object->date_livraison:-1,'liv_',$usehourmin,$usehourmin,'',"setdate_livraison");
    +		print $form->selectDate($object->date_livraison?$object->date_livraison:-1, 'liv_', $usehourmin, $usehourmin, '', "setdate_livraison");
     		print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
     		print '</form>';
     	}
    @@ -2444,7 +2441,6 @@ elseif (! empty($object->id))
     				{
     					print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delete">'.$langs->trans("Delete").'</a>';
     				}
    -
     			}
     
     			print "</div>";
    @@ -2465,7 +2461,7 @@ elseif (! empty($object->id))
     			print '<tr><td>'.$langs->trans("OrderDate").'</td><td>';
     			$date_com = dol_mktime(GETPOST('rehour','int'), GETPOST('remin','int'), GETPOST('resec','int'), GETPOST('remonth','int'), GETPOST('reday','int'), GETPOST('reyear','int'));
     			if (empty($date_com)) $date_com=dol_now();
    -			print $form->select_date($date_com,'',1,1,'',"commande",1,1,1);
    +			print $form->selectDate($date_com, '', 1, 1, '', "commande", 1, 1);
     			print '</td></tr>';
     
     			print '<tr><td>'.$langs->trans("OrderMode").'</td><td>';
    @@ -2521,7 +2517,7 @@ elseif (! empty($object->id))
     				//print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Receive").'</td></tr>';
     				print '<tr><td>'.$langs->trans("DeliveryDate").'</td><td>';
     				$datepreselected = dol_now();
    -				print $form->select_date($datepreselected,'',1,1,'',"commande",1,1,1);
    +				print $form->selectDate($datepreselected, '', 1, 1, '', "commande", 1, 1);
     				print "</td></tr>\n";
     
     				print "<tr><td class=\"fieldrequired\">".$langs->trans("Delivery")."</td><td>\n";
    @@ -2719,7 +2715,6 @@ elseif (! empty($object->id))
     							}
     						}
     					}
    -
     				}
     				elseif ($user_status_code == "PERMISSION_DENIED")
     				{
    @@ -2777,5 +2772,4 @@ elseif (! empty($object->id))
     
     // End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/commande/contact.php b/htdocs/fourn/commande/contact.php
    index 262d73a6082..c69c92ead29 100644
    --- a/htdocs/fourn/commande/contact.php
    +++ b/htdocs/fourn/commande/contact.php
    @@ -33,10 +33,8 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load("facture");
    -$langs->load("orders");
    -$langs->load("sendings");
    -$langs->load("companies");
    +// Load translation files required by the page
    +$langs->loadLangs(array("facture","orders","sendings","companies"));
     
     $id		= GETPOST('id', 'int');
     $ref	= GETPOST('ref', 'alpha');
    @@ -194,7 +192,6 @@ if ($id > 0 || ! empty($ref))
     
     		// Contacts lines
     		include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php';
    -
     	}
     	else
     	{
    @@ -203,6 +200,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php
    index 761cce030f7..7f2e5ba4139 100644
    --- a/htdocs/fourn/commande/dispatch.php
    +++ b/htdocs/fourn/commande/dispatch.php
    @@ -5,8 +5,9 @@
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2014      Cedric Gross         <c.gross@kreiz-it.fr>
    - * Copyright (C) 2016      Florian Henry         <florian.henry@atm-consulting.fr>
    + * Copyright (C) 2016      Florian Henry        <florian.henry@atm-consulting.fr>
      * Copyright (C) 2017      Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2018      Frédéric France      <frederic.france@netlogic.fr>
      *
      * 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
    @@ -39,13 +40,9 @@ require_once DOL_DOCUMENT_ROOT . '/product/class/html.formproduct.class.php';
     if (! empty($conf->projet->enabled))
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     
    -$langs->load('orders');
    -$langs->load('sendings');
    -$langs->load('companies');
    -$langs->load('bills');
    -$langs->load('deliveries');
    -$langs->load('products');
    -$langs->load('stocks');
    +// Load translation files required by the page
    +$langs->loadLangs(array("bills", "orders", "sendings", "companies", "deliveries", "products", "stocks"));
    +
     if (! empty($conf->productbatch->enabled))
     	$langs->load('productbatch');
     
    @@ -492,7 +489,7 @@ if ($id > 0 || ! empty($ref)) {
     			$db->free($resql);
     		}
     
    -		$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, SUM(l.qty) as qty,";
    +		$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,";
     		$sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse";
     		$sql .= " FROM " . MAIN_DB_PREFIX . "commande_fournisseurdet as l";
     		$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON l.fk_product=p.rowid";
    @@ -511,7 +508,7 @@ if ($id > 0 || ! empty($ref)) {
     				print '<tr class="liste_titre">';
     
     				print '<td>' . $langs->trans("Description") . '</td>';
    -				if (!empty($conf->productbatch->enabled))
    +				if (! empty($conf->productbatch->enabled))
     				{
     					print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
     					print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
    @@ -521,8 +518,9 @@ if ($id > 0 || ! empty($ref)) {
     				{
     					print '<td></td>';
     					print '<td></td>';
    -					print '<td></td>';					
    +					print '<td></td>';
     				}
    +				print '<td align="right">' . $langs->trans("SupplierRef") . '</td>';
     				print '<td align="right">' . $langs->trans("QtyOrdered") . '</td>';
     				print '<td align="right">' . $langs->trans("QtyDispatchedShort") . '</td>';
     				print '<td align="right">' . $langs->trans("QtyToDispatchShort") . '</td>';
    @@ -535,7 +533,6 @@ if ($id > 0 || ! empty($ref)) {
     			$nbproduct = 0;			// Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default)
     									// or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on.
     
    -			$var = false;
     			while ( $i < $num ) {
     				$objp = $db->fetch_object($resql);
     
    @@ -594,6 +591,9 @@ if ($id > 0 || ! empty($ref)) {
     						if (! empty($objp->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP))
     							$up_ht_disc = price2num($up_ht_disc * (100 - $objp->remise_percent) / 100, 'MU');
     
    +						// Supplier ref
    +						print '<td align="right">'.$objp->sref.'</td>';
    +
     						// Qty ordered
     						print '<td align="right">' . $objp->qty . '</td>';
     
    @@ -632,15 +632,15 @@ if ($id > 0 || ! empty($ref)) {
     							print '</td>';
     							print '<td class="nowraponall">';
     							$dlcdatesuffix = dol_mktime(0, 0, 0, GETPOST('dlc' . $suffix . 'month'), GETPOST('dlc' . $suffix . 'day'), GETPOST('dlc' . $suffix . 'year'));
    -							$form->select_date($dlcdatesuffix, 'dlc' . $suffix, '', '', 1, "");
    +							print $form->selectDate($dlcdatesuffix, 'dlc' . $suffix, '', '', 1, '');
     							print '</td>';
     							print '<td class="nowraponall">';
     							$dluodatesuffix = dol_mktime(0, 0, 0, GETPOST('dluo' . $suffix . 'month'), GETPOST('dluo' . $suffix . 'day'), GETPOST('dluo' . $suffix . 'year'));
    -							$form->select_date($dluodatesuffix, 'dluo' . $suffix, '', '', 1, "");
    +							print $form->selectDate($dluodatesuffix, 'dluo' . $suffix, '', '', 1, '');
     							print '</td>';
    -							print '<td colspan="2">&nbsp</td>'; // Qty ordered + qty already dispatached
    +							print '<td colspan="3">&nbsp</td>'; // Supplier ref + Qty ordered + qty already dispatched
     						} else {
    -							
    +
     							$type = 'dispatch';
     							print '<td align="right">';
     							print '</td>';     // Qty to dispatch
    @@ -651,7 +651,7 @@ if ($id > 0 || ! empty($ref)) {
     							print '</tr>';
     
     							print '<tr class="oddeven" name="' . $type . $suffix . '">';
    -							print '<td colspan="6">';
    +							print '<td colspan="7">';
     							print '<input name="fk_commandefourndet' . $suffix . '" type="hidden" value="' . $objp->rowid . '">';
     							print '<input name="product' . $suffix . '" type="hidden" value="' . $objp->fk_product . '">';
     
    @@ -673,7 +673,7 @@ if ($id > 0 || ! empty($ref)) {
     						print '<input id="qty' . $suffix . '" name="qty' . $suffix . '" type="text" class="width50 right" value="' . (GETPOST('qty' . $suffix) != '' ? GETPOST('qty' . $suffix) : $remaintodispatch) . '">';
     						print '</td>';
     
    -                        print '<td>';
    +						print '<td>';
     						if (! empty($conf->productbatch->enabled) && $objp->tobatch == 1) {
     						    $type = 'batch';
     						    //print img_picto($langs->trans('AddDispatchBatchLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
    @@ -793,8 +793,6 @@ if ($id > 0 || ! empty($ref)) {
     			print '<td>' . $langs->trans("Date") . '</td>';
     			print "</tr>\n";
     
    -			$var = false;
    -
     			while ( $i < $num ) {
     				$objp = $db->fetch_object($resql);
     
    @@ -868,7 +866,6 @@ if ($id > 0 || ! empty($ref)) {
     				print "</tr>\n";
     
     				$i ++;
    -				$var = ! $var;
     			}
     			$db->free($resql);
     
    @@ -880,6 +877,6 @@ if ($id > 0 || ! empty($ref)) {
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/commande/document.php b/htdocs/fourn/commande/document.php
    index 59358279e31..eb299d6a94d 100644
    --- a/htdocs/fourn/commande/document.php
    +++ b/htdocs/fourn/commande/document.php
    @@ -38,14 +38,8 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load('orders');
    -$langs->load('other');
    -$langs->load('sendings');
    -$langs->load('companies');
    -$langs->load('bills');
    -$langs->load('deliveries');
    -$langs->load('products');
    -$langs->load('stocks');
    +// Load translation files required by the page
    +$langs->loadLangs(array("bills", "orders", "sendings", "companies", "deliveries", "products", "stocks","other"));
     
     $id = GETPOST('id','int');
     $ref = GETPOST('ref', 'alpha');
    @@ -107,7 +101,7 @@ if ($object->id > 0)
     	dol_fiche_head($head, 'documents', $langs->trans('SupplierOrder'), -1, 'order');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -181,7 +175,6 @@ if ($object->id > 0)
     	$permtoedit = $user->rights->fournisseur->commande->creer;
     	$param = '&id=' . $object->id;
     	include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
    @@ -189,6 +182,6 @@ else
     	exit;
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php
    index 4eead48abf4..59e7b82e488 100644
    --- a/htdocs/fourn/commande/index.php
    +++ b/htdocs/fourn/commande/index.php
    @@ -34,8 +34,8 @@ $orderid = GETPOST('orderid');
     if ($user->societe_id) $socid=$user->societe_id;
     $result = restrictedArea($user, 'fournisseur', $orderid, '', 'commande');
     
    -$langs->load("suppliers");
    -$langs->load("orders");
    +// Load translation files required by the page
    +$langs->loadLangs(array("suppliers", "orders"));
     
     
     /*
    @@ -432,6 +432,6 @@ print "</table><br>";
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/commande/info.php b/htdocs/fourn/commande/info.php
    index 016e9007fb9..dee7a83bc6a 100644
    --- a/htdocs/fourn/commande/info.php
    +++ b/htdocs/fourn/commande/info.php
    @@ -33,10 +33,8 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load("orders");
    -$langs->load("suppliers");
    -$langs->load("companies");
    -$langs->load('stocks');
    +// Load translation files required by the page
    +$langs->loadLangs(array("suppliers", "orders", "companies", "stocks"));
     
     $id=GETPOST('id','int');
     $ref=GETPOST('ref','alpha');
    @@ -221,7 +219,6 @@ if (!empty($object->id))
         show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters);
     }
     
    -
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php
    index 590bf14949e..7158d7b2c0e 100644
    --- a/htdocs/fourn/commande/list.php
    +++ b/htdocs/fourn/commande/list.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    +/* Copyright (C) 2001-2006  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2013      Cédric Salvador      <csalvador@gpcsolutions.fr>
      * Copyright (C) 2014      Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2014      Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2016      Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -262,7 +263,6 @@ if (empty($reshook))
     				$res = $object->create($user);
     
     				if($res > 0) $nb_bills_created++;
    -
     			}
     
     			if ($object->id > 0)
    @@ -427,7 +427,7 @@ if (empty($reshook))
     		if (! $error)
     		{
     			$db->commit();
    -			setEventMessage($langs->trans('BillCreated', $nb_bills_created));
    +			setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs');
     		}
     		else
     		{
    @@ -681,7 +681,7 @@ if ($resql)
     		print $langs->trans('DateInvoice');
     		print '</td>';
     		print '<td>';
    -		print $form->select_date('', '', '', '', '', '', 1, 1);
    +		print $form->selectDate('', '', '', '', '', '', 1, 1);
     		print '</td>';
     		print '</tr>';
     		print '<tr>';
    @@ -1127,7 +1127,7 @@ if ($resql)
     		// Status
     		if (! empty($arrayfields['cf.fk_statut']['checked']))
     		{
    -			print '<td align="right" class="nowrap">'.$objectstatic->LibStatut($obj->fk_statut, 5, $obj->billed, 1).'</td>';
    +			print '<td align="right" class="nowrap">'.$objectstatic->LibStatut($obj->fk_statut, 5, $obj->billed).'</td>';
     			if (! $i) $totalarray['nbfield']++;
     		}
     		// Billed
    @@ -1197,6 +1197,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/commande/note.php b/htdocs/fourn/commande/note.php
    index 44edbdc8f00..288b43d200b 100644
    --- a/htdocs/fourn/commande/note.php
    +++ b/htdocs/fourn/commande/note.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2012      Marcos García        <marcosgdf@gmail.com>
    - * Copyright (C) 2017      Ferran Marcet       	 <fmarcet@2byte.es>
    + * Copyright (C) 2017      Ferran Marcet       	<fmarcet@2byte.es>
      *
      * 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
    @@ -32,10 +32,8 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load("orders");
    -$langs->load("suppliers");
    -$langs->load("companies");
    -$langs->load('stocks');
    +// Load translation files required by the page
    +$langs->loadLangs(array("suppliers", "orders", "companies", "stocks"));
     
     $id = GETPOST('facid','int')?GETPOST('facid','int'):GETPOST('id','int');
     $ref = GETPOST('ref');
    @@ -155,7 +153,6 @@ if ($id > 0 || ! empty($ref))
         }
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php
    index 4c229518eba..5456627384e 100644
    --- a/htdocs/fourn/commande/orderstoinvoice.php
    +++ b/htdocs/fourn/commande/orderstoinvoice.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2001-2005 Rodolphe Quiedeville   	<rodolphe@quiedeville.org>
    +/* Copyright (C) 2001-2005 Rodolphe Quiedeville     <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2013 Laurent Destailleur   	<eldy@users.sourceforge.net>
      * Copyright (C) 2005      Marc Barilley / Ocebo  	<marc@ocebo.com>
      * Copyright (C) 2005-2012 Regis Houssin          	<regis.houssin@capnetworks.com>
    @@ -8,6 +8,7 @@
      * Copyright (C) 2012-2017 Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2014	   Florian Henry			<florian.henry@open-concept.pro>
      * Copyright (C) 2015      Marcos García            <marcosgdf@gmail.com>
    + * Copyright (C) 2018      Frédéric France          <frederic.france@netlogic.fr>
      *
      * 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
    @@ -40,9 +41,8 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
     }
     
    -$langs->load('orders');
    -$langs->load('deliveries');
    -$langs->load('companies');
    +// Load translation files required by the page
    +$langs->loadLangs(array("orders", "companies", "deliveries"));
     
     if (! $user->rights->fournisseur->facture->creer)
     	accessforbidden();
    @@ -104,9 +104,9 @@ if (($action == 'create' || $action == 'add') && ! $error) {
     	if (! empty($conf->projet->enabled))
     		require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     
    -	$langs->load('bills');
    -	$langs->load('products');
    -	$langs->load('main');
    +	// Load translation files required by the page
    +    $langs->loadLangs(array("bills", "main", "products"));
    +
     	if (isset($_GET['orders_to_invoice'])) {
     		$orders_id = GETPOST('orders_to_invoice','',1);
     		$n = count($orders_id);
    @@ -261,7 +261,6 @@ if (($action == 'create' || $action == 'add') && ! $error) {
     						$error++;
     						break;
     					}
    -
     				}
     			}
     
    @@ -270,7 +269,6 @@ if (($action == 'create' || $action == 'add') && ! $error) {
     				header('Location: ' . DOL_URL_ROOT . '/fourn/facture/card.php?facid=' . $id);
     				exit();
     			}
    -
     		} else {
     			$db->rollback();
     			$action = 'create';
    @@ -332,7 +330,7 @@ if ($action == 'create' && !$error) {
     
     	// Date invoice
     	print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td colspan="2">';
    -	$html->select_date('', '', '', '', '', "add", 1, 1);
    +	print $html->selectDate('', '', '', '', '', "add", 1, 1);
     	print '</td></tr>';
     	// Payment term
     	print '<tr><td class="nowrap">' . $langs->trans('PaymentConditionsShort') . '</td><td colspan="2">';
    @@ -486,8 +484,8 @@ if (($action != 'create' && $action != 'add') && !$error) {
     		$num = $db->num_rows($resql);
     		print load_fiche_titre($title);
     		$i = 0;
    -		$period = $html->select_date($date_start, 'date_start', 0, 0, 1, '', 1, 0, 1) . ' - ' . $html->select_date($date_end, 'date_end', 0, 0, 1, '', 1, 0, 1);
    -		$periodely = $html->select_date($date_starty, 'date_start_dely', 0, 0, 1, '', 1, 0, 1) . ' - ' . $html->select_date($date_endy, 'date_end_dely', 0, 0, 1, '', 1, 0, 1);
    +		$period = $html->selectDate($date_start, 'date_start', 0, 0, 1, '', 1, 0) . ' - ' . $html->selectDate($date_end, 'date_end', 0, 0, 1, '', 1, 0);
    +		$periodely = $html->selectDate($date_starty, 'date_start_dely', 0, 0, 1, '', 1, 0) . ' - ' . $html->selectDate($date_endy, 'date_end_dely', 0, 0, 1, '', 1, 0);
     
     		if (! empty($socid)) {
     			// Company
    @@ -617,5 +615,6 @@ if (($action != 'create' && $action != 'add') && !$error) {
     
     dol_htmloutput_mesg($mesg, $mesgs);
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/contact.php b/htdocs/fourn/contact.php
    index a334442e9ab..3225ce63714 100644
    --- a/htdocs/fourn/contact.php
    +++ b/htdocs/fourn/contact.php
    @@ -123,14 +123,12 @@ if ($result)
         }
         print "</table>";
         $db->free($result);
    -
     }
     else
     {
         dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
    index 36785a154dc..9df540da197 100644
    --- a/htdocs/fourn/facture/card.php
    +++ b/htdocs/fourn/facture/card.php
    @@ -9,6 +9,7 @@
      * Copyright (C) 2013		Florian Henry			<florian.henry@open-concept.pro>
      * Copyright (C) 2014-2016  Marcos García			<marcosgdf@gmail.com>
      * Copyright (C) 2016-2017	Alexandre Spangaro		<aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -524,7 +525,6 @@ if (empty($reshook))
     				{
     					$error++;
     				}
    -
     			}
     			if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT)
     			{
    @@ -542,7 +542,6 @@ if (empty($reshook))
     						break;
     					}
     				}
    -
     			}
     
     			if (empty($error))
    @@ -756,7 +755,6 @@ if (empty($reshook))
     
     						$object->update_price(1);
     					}
    -
     				}
     
     				if(GETPOST('invoiceAvoirWithPaymentRestAmount', 'int')==1 && $id>0)
    @@ -1097,6 +1095,7 @@ if (empty($reshook))
     		$product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
     		$date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start' . $predef . 'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year'));
     		$date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end' . $predef . 'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year'));
    +
     		$prod_entry_mode = GETPOST('prod_entry_mode');
     		if ($prod_entry_mode == 'free')
     		{
    @@ -1161,7 +1160,7 @@ if (empty($reshook))
     				if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
     					$idprod = $res->fk_product_child;
     				} else {
    -					setEventMessage($langs->trans('ErrorProductCombinationNotFound'), 'errors');
    +					setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
     					$error ++;
     				}
     			}
    @@ -1207,7 +1206,11 @@ if (empty($reshook))
     			{
     				$label = $productsupplier->label;
     
    -				$desc = $productsupplier->description;
    +				// if we use supplier description of the products
    +				if(!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) {
    +				    $desc = $productsupplier->desc_supplier;
    +				} else $desc = $productsupplier->description;
    +
     				if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc);
     
     				$type = $productsupplier->type;
    @@ -1663,7 +1666,6 @@ if ($action == 'create')
     			// Replicate extrafields
     			$objectsrc->fetch_optionals($originid);
     			$object->array_options = $objectsrc->array_options;
    -
     		}
     	}
     	else
    @@ -1950,12 +1952,12 @@ if ($action == 'create')
     
     	// Date invoice
     	print '<tr><td class="fieldrequired">'.$langs->trans('DateInvoice').'</td><td>';
    -	$form->select_date($dateinvoice,'','','','',"add",1,1);
    +	print $form->selectDate($dateinvoice, '', '', '', '', "add", 1, 1);
     	print '</td></tr>';
     
     	// Due date
     	print '<tr><td>'.$langs->trans('DateMaxPayment').'</td><td>';
    -	$form->select_date($datedue,'ech','','','',"add",1,1);
    +	print $form->selectDate($datedue, 'ech', '', '', '', "add", 1, 1);
     	print '</td></tr>';
     
     	// Payment term
    @@ -2251,7 +2253,6 @@ else
                 }
     
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, 1, 1);
    -
             }
     
             // Confirmation edit (back to draft)
    @@ -2287,27 +2288,23 @@ else
                     );
                 }
                 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateBill'), $langs->trans('ConfirmUnvalidateBill', $object->ref), 'confirm_edit', $formquestion, 1, 1);
    -
     		}
     
     		// Confirmation set paid
     		if ($action == 'paid')
     		{
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', 0, 1);
    -
     		}
     
     		// Confirmation de la suppression de la facture fournisseur
     		if ($action == 'delete')
     		{
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteBill'), $langs->trans('ConfirmDeleteBill'), 'confirm_delete', '', 0, 1);
    -
     		}
     		if ($action == 'deletepaiement')
     		{
     			$payment_id = GETPOST('paiement_id');
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&paiement_id='.$payment_id, $langs->trans('DeletePayment'), $langs->trans('ConfirmDeletePayment'), 'confirm_delete_paiement', '', 0, 1);
    -
     		}
     
     	   	// Confirmation to delete line
    @@ -3196,7 +3193,6 @@ else
     	}
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/facture/contact.php b/htdocs/fourn/facture/contact.php
    index 6b54e28987f..58e5630c0d6 100644
    --- a/htdocs/fourn/facture/contact.php
    +++ b/htdocs/fourn/facture/contact.php
    @@ -34,9 +34,7 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load("bills");
    -$langs->load('other');
    -$langs->load("companies");
    +$langs->loadLangs(array("bills", "other", "companies"));
     
     $id		= (GETPOST('id','int') ? GETPOST('id','int') : GETPOST('facid','int'));
     $ref	= GETPOST('ref','alpha');
    @@ -268,7 +266,6 @@ if ($id > 0 || ! empty($ref))
     
     		// Contacts lines
     		include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php';
    -
     	}
     	else
     	{
    @@ -276,6 +273,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/facture/document.php b/htdocs/fourn/facture/document.php
    index 1f0c9f86739..d38a7992bd8 100644
    --- a/htdocs/fourn/facture/document.php
    +++ b/htdocs/fourn/facture/document.php
    @@ -38,9 +38,7 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load('bills');
    -$langs->load('other');
    -$langs->load("companies");
    +$langs->loadLangs(array('bills', 'other', 'companies'));
     
     $id = GETPOST('facid','int')?GETPOST('facid','int'):GETPOST('id','int');
     $action=GETPOST('action','alpha');
    @@ -145,7 +143,7 @@ if ($object->id > 0)
         print '<div class="fichecenter">';
         print '<div class="underbanner clearboth"></div>';
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -159,7 +157,6 @@ if ($object->id > 0)
     	if ($action == 'delete')
     	{
     		print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
    -
     	}
     
     	print '<table class="border" width="100%">';
    @@ -260,6 +257,6 @@ else
         print $langs->trans('ErrorUnknown');
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/facture/impayees.php b/htdocs/fourn/facture/impayees.php
    index c1c4be9fb76..4582f403b02 100644
    --- a/htdocs/fourn/facture/impayees.php
    +++ b/htdocs/fourn/facture/impayees.php
    @@ -33,9 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
     
     if (! $user->rights->fournisseur->facture->lire) accessforbidden();
     
    -$langs->load("companies");
    -$langs->load("bills");
    -
    +$langs->loadLangs(array("companies", "bills"));
     
     $socid=GETPOST('socid','int');
     $option = GETPOST('option');
    @@ -296,7 +294,6 @@ if ($user->rights->fournisseur->facture->lire)
     	{
     		dol_print_error($db);
     	}
    -
     }
     
     // End of page
    diff --git a/htdocs/fourn/facture/info.php b/htdocs/fourn/facture/info.php
    index 1297c44037b..d0ca8cbc3da 100644
    --- a/htdocs/fourn/facture/info.php
    +++ b/htdocs/fourn/facture/info.php
    @@ -34,8 +34,7 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load('companies');
    -$langs->load('bills');
    +$langs->loadLangs(array("companies", "bills"));
     
     $id = GETPOST("facid",'int')?GETPOST("facid",'int'):GETPOST("id",'int');
     $ref = GETPOST("ref",'alpha');
    @@ -126,6 +125,6 @@ print '</td></tr></table>';
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php
    index 98a6956a809..e1bd120b0b4 100644
    --- a/htdocs/fourn/facture/list.php
    +++ b/htdocs/fourn/facture/list.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2002-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    +/* Copyright (C) 2002-2006  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2013 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2013-2018 Philippe Grand       <philippe.grand@atoo-net.com>
    @@ -10,6 +10,7 @@
      * Copyright (C) 2015 	   Abbes Bahfir         <bafbes@gmail.com>
      * Copyright (C) 2015-2016 Ferran Marcet        <fmarcet@2byte.es>
      * Copyright (C) 2017      Josep Lluís Amador   <joseplluis@lliuretic.cat>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -512,7 +513,7 @@ if ($resql)
     		print $langs->trans('DateInvoice');
     		print '</td>';
     		print '<td>';
    -		print $form->select_date('', '', '', '', '', '', 1, 1);
    +		print $form->selectDate('', '', '', '', '', '', 1, 1);
     		print '</td>';
     		print '</tr>';
     		print '<tr>';
    @@ -819,7 +820,6 @@ if ($resql)
     	if ($num > 0)
     	{
     		$i=0;
    -
     		$totalarray=array();
     		while ($i < min($num,$limit))
     		{
    @@ -1132,7 +1132,6 @@ if ($resql)
     			   else print '<td></td>';
     			}
     			print '</tr>';
    -
     		}
     	}
     
    @@ -1167,7 +1166,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/facture/note.php b/htdocs/fourn/facture/note.php
    index 11d59d1170c..109ff71980c 100644
    --- a/htdocs/fourn/facture/note.php
    +++ b/htdocs/fourn/facture/note.php
    @@ -33,8 +33,7 @@ if (! empty($conf->projet->enabled)) {
     	require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
     }
     
    -$langs->load('bills');
    -$langs->load("companies");
    +$langs->loadLangs(array("bills", "companies"));
     
     $id = (GETPOST('id','int') ? GETPOST('id','int') : GETPOST('facid','int'));
     $ref = GETPOST('ref','alpha');
    @@ -214,7 +213,6 @@ if ($object->id > 0)
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php
    index 74593cb8675..7946f98cb66 100644
    --- a/htdocs/fourn/facture/paiement.php
    +++ b/htdocs/fourn/facture/paiement.php
    @@ -9,6 +9,7 @@
      * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
      * Copyright (C) 2015       Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2017       Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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,10 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
    -$langs->load('companies');
    -$langs->load('bills');
    -$langs->load('banks');
    -$langs->load('compta');
    +$langs->loadLangs(array('companies', 'bills', 'banks', 'compta'));
     
     // Security check
     $action		= GETPOST('action','alpha');
    @@ -443,7 +441,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                 print $supplierstatic->getNomUrl(1,'supplier');
                 print '</td></tr>';
                 print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td>';
    -            $form->select_date($dateinvoice,'','','','',"addpaiement",1,1,0,0,'','',$object->date);
    +            print $form->selectDate($dateinvoice, '', '', '', 0, "addpaiement", 1, 1, 0, '', '', $object->date);
                 print '</td></tr>';
                 print '<tr><td class="fieldrequired">'.$langs->trans('PaymentMode').'</td><td>';
                 $form->select_types_paiements(empty($_POST['paiementid'])?$obj->fk_mode_reglement:$_POST['paiementid'],'paiementid');
    @@ -475,14 +473,14 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	             * Autres factures impayees
     	             */
     	            $sql = 'SELECT f.rowid as facid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.multicurrency_total_ttc, f.datef as df,';
    -	            $sql.= ' SUM(pf.amount) as am, SUM(pf.multicurrency_amount) as multicurrency_am';
    +	            $sql.= ' SUM(pf.amount) as am, SUM(pf.multicurrency_amount) as multicurrency_am, f.date_lim_reglement as dlr';
     	            $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as f';
     	            $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid';
     	            $sql.= " WHERE f.entity = ".$conf->entity;
     	            $sql.= ' AND f.fk_soc = '.$object->socid;
     	            $sql.= ' AND f.paye = 0';
     	            $sql.= ' AND f.fk_statut = 1';  // Statut=0 => non validee, Statut=2 => annulee
    -	            $sql.= ' GROUP BY f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.multicurrency_total_ttc, f.datef';
    +	            $sql.= ' GROUP BY f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.multicurrency_total_ttc, f.datef, f.date_lim_reglement';
     	            $resql = $db->query($sql);
     	            if ($resql)
     	            {
    @@ -513,6 +511,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	                    print '<td>'.$langs->trans('Invoice').'</td>';
     	                    print '<td>'.$langs->trans('RefSupplier').'</td>';
     	                    print '<td align="center">'.$langs->trans('Date').'</td>';
    +	                    print '<td align="center">'.$langs->trans('DateMaxPayment').'</td>';
     	                    if (!empty($conf->multicurrency->enabled)) print '<td>'.$langs->trans('Currency').'</td>';
     						if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
     						if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAlreadyPaid').'</td>';
    @@ -571,7 +570,25 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	                        {
     	                            print '<td align="center"><b>!!!</b></td>';
     	                        }
    -
    +	                        
    +	                        // Date Max Payment
    +	                        if ($objp->dlr > 0 )
    +	                        {
    +	                            print '<td align="center">';
    +	                            print dol_print_date($db->jdate($objp->dlr), 'day');
    +	                            
    +	                            if ($invoice->hasDelay())
    +	                            {
    +	                                print img_warning($langs->trans('Late'));
    +	                            }
    +	                            
    +	                            print '</td>';
    +	                        }
    +	                        else
    +	                        {
    +	                            print '<td align="center"><b>--</b></td>';
    +	                        }
    +	                        
     	                        // Multicurrency
     	                        if (!empty($conf->multicurrency->enabled))
     	                        {
    @@ -663,7 +680,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	                    {
     	                        // Print total
     	                        print '<tr class="liste_total">';
    -	                        print '<td colspan="3" align="left">'.$langs->trans('TotalTTC').':</td>';
    +	                        print '<td colspan="4" align="left">'.$langs->trans('TotalTTC').':</td>';
     							if (!empty($conf->multicurrency->enabled)) print '<td>&nbsp;</td>';
     							if (!empty($conf->multicurrency->enabled)) print '<td>&nbsp;</td>';
     							if (!empty($conf->multicurrency->enabled)) print '<td>&nbsp;</td>';
    @@ -941,5 +958,6 @@ if (empty($action))
         }
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/facture/rapport.php b/htdocs/fourn/facture/rapport.php
    index c20b26b1263..fb76247f5d7 100644
    --- a/htdocs/fourn/facture/rapport.php
    +++ b/htdocs/fourn/facture/rapport.php
    @@ -146,6 +146,7 @@ if ($year)
             print '<td align="right">'.$langs->trans("Size").'</td>';
             print '<td align="right">'.$langs->trans("Date").'</td>';
             print '</tr>';
    +
             if (is_resource($handle))
             {
                 while (($file = readdir($handle))!==false)
    @@ -165,6 +166,6 @@ if ($year)
         }
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/index.php b/htdocs/fourn/index.php
    index 033bcc63a2a..7228b68f1cd 100644
    --- a/htdocs/fourn/index.php
    +++ b/htdocs/fourn/index.php
    @@ -28,9 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
     require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
     
    -$langs->load("suppliers");
    -$langs->load("orders");
    -$langs->load("companies");
    +$langs->loadLangs(array("suppliers", "orders", "companies"));
     
     // Security check
     $socid = GETPOST("socid", 'int');
    @@ -313,6 +311,6 @@ if (count($companystatic->SupplierCategories))
     //print "</td></tr></table>\n";
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/js/lib_dispatch.js b/htdocs/fourn/js/lib_dispatch.js
    index c2c570643f8..d183aeb4e48 100644
    --- a/htdocs/fourn/js/lib_dispatch.js
    +++ b/htdocs/fourn/js/lib_dispatch.js
    @@ -23,23 +23,23 @@
     /**
      * addDispatchLine
      * Adds new table row for dispatching to multiple stock locations
    - * 
    + *
      * @param	index	int		index of product line. 0 = first product line
      * @param	type	string	type of dispatch (batch = batch dispatch, dispatch = non batch dispatch)
      * @param	mode	string	'qtymissing' will create new line with qty missing, 'lessone' will keep 1 in old line and the rest in new one
      */
    -function addDispatchLine(index, type, mode) 
    +function addDispatchLine(index, type, mode)
     {
     	mode = mode || 'qtymissing'
    -	
    +
     	console.log("fourn/js/lib_dispatch.js Split line type="+type+" index="+index+" mode="+mode);
     	var $row = $("tr[name='"+type+'_0_'+index+"']").clone(true), 		// clone first batch line to jQuery object
     		nbrTrs = $("tr[name^='"+type+"_'][name$='_"+index+"']").length, // position of line for batch
     		qtyOrdered = parseFloat($("#qty_ordered_0_"+index).val()), 		// Qty ordered is same for all rows
     		qty = parseFloat($("#qty_"+(nbrTrs - 1)+"_"+index).val()),
     		qtyDispatched;
    -			
    -	if (mode === 'lessone') 
    +
    +	if (mode === 'lessone')
     	{
     		qtyDispatched = parseFloat($("#qty_dispatched_0_"+index).val()) + 1;
     	}
    @@ -47,7 +47,7 @@ function addDispatchLine(index, type, mode)
     	{
     		qtyDispatched = parseFloat($("#qty_dispatched_0_"+index).val()) + qty;
     	}
    -	
    +
     	if (qtyDispatched < qtyOrdered)
     	{
     		//replace tr suffix nbr
    @@ -62,19 +62,19 @@ function addDispatchLine(index, type, mode)
     		$row.attr('name',type+'_'+nbrTrs+'_'+index);
     		//insert new row before last row
     		$("tr[name^='"+type+"_'][name$='_"+index+"']:last").after($row);
    -		
    +
     		//remove cloned select2 with duplicate id.
     		$("#s2id_entrepot_"+nbrTrs+'_'+index).detach();			// old way to find duplicated select2 component
     		$(".csswarehouse_"+nbrTrs+"_"+index+":first-child").parent("span.selection").parent(".select2").detach();
    -		
    +
     		/*  Suffix of lines are:  _ trs.length _ index  */
     		$("#qty_"+nbrTrs+"_"+index).focus();
     		$("#qty_dispatched_0_"+index).val(qtyDispatched);
    -		
    +
     		//hide all buttons then show only the last one
     		$("tr[name^='"+type+"_'][name$='_"+index+"'] .splitbutton").hide();
     		$("tr[name^='"+type+"_'][name$='_"+index+"']:last .splitbutton").show();
    -		
    +
     		if (mode === 'lessone')
     		{
     			qty = 1; // keep 1 in old line
    @@ -94,11 +94,11 @@ function addDispatchLine(index, type, mode)
     
     /**
      * onChangeDispatchLineQty
    - * 
    - * Change event handler for dispatch qty input field, 
    + *
    + * Change event handler for dispatch qty input field,
      * recalculate qty dispatched when qty input has changed.
      * If qty is more then qty ordered reset input qty to max qty to dispatch.
    - * 
    + *
      * element requires arbitrary data qty (value before change), type (type of dispatch) and index (index of product line)
      */
     
    @@ -124,4 +124,4 @@ function onChangeDispatchLineQty() {
     		}
     		$(this).data('qty', $(this).val());
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php
    index daa452d0c29..9cc5fb27b84 100644
    --- a/htdocs/fourn/paiement/card.php
    +++ b/htdocs/fourn/paiement/card.php
    @@ -32,10 +32,7 @@ require DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
     require DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
     require DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     
    -$langs->load('bills');
    -$langs->load('banks');
    -$langs->load('companies');
    -$langs->load("suppliers");
    +$langs->loadLangs(array('bills', 'banks', 'companies', 'suppliers'));
     
     $id			= GETPOST('id','int');
     $action		= GETPOST('action','alpha');
    @@ -169,7 +166,6 @@ if ($result > 0)
     	if ($action == 'delete')
     	{
     		print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans("DeletePayment"), $langs->trans("ConfirmDeletePayment"), 'confirm_delete');
    -
     	}
     
     	/*
    @@ -178,7 +174,6 @@ if ($result > 0)
     	if ($action == 'valide')
     	{
     		print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans("ValidatePayment"), $langs->trans("ConfirmValidatePayment"), 'confirm_valide');
    -
     	}
     
     	$linkback = '<a href="' . DOL_URL_ROOT . '/fourn/facture/paiement.php' . (! empty($socid) ? '?socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
    @@ -348,7 +343,6 @@ if ($result > 0)
     		   	|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->fournisseur->supplier_invoice_advance->validate)))
     			{
     				print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&amp;action=valide">'.$langs->trans('Valid').'</a>';
    -
     			}
     		}
     	}
    @@ -407,6 +401,6 @@ else
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/paiement/info.php b/htdocs/fourn/paiement/info.php
    index eafc4f2decc..1c670c1396a 100644
    --- a/htdocs/fourn/paiement/info.php
    +++ b/htdocs/fourn/paiement/info.php
    @@ -28,9 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     
    -$langs->load("bills");
    -$langs->load("suppliers");
    -$langs->load("companies");
    +$langs->loadLangs(array("bills", "suppliers", "companies"));
     
     $id			= GETPOST('id','int');
     
    @@ -57,6 +55,6 @@ print '<table width="100%"><tr><td>';
     dol_print_object_info($object);
     print '</td></tr></table>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/fourn/product/list.php b/htdocs/fourn/product/list.php
    index 47bc949a758..9927b6b2b5d 100644
    --- a/htdocs/fourn/product/list.php
    +++ b/htdocs/fourn/product/list.php
    @@ -308,5 +308,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/fourn/recap-fourn.php b/htdocs/fourn/recap-fourn.php
    index e680c18074e..1ff9f486510 100644
    --- a/htdocs/fourn/recap-fourn.php
    +++ b/htdocs/fourn/recap-fourn.php
    @@ -191,5 +191,6 @@ else
         dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/ftp/admin/ftpclient.php b/htdocs/ftp/admin/ftpclient.php
    index ee7acc9070d..07f2847eda2 100644
    --- a/htdocs/ftp/admin/ftpclient.php
    +++ b/htdocs/ftp/admin/ftpclient.php
    @@ -25,8 +25,7 @@
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     
    -$langs->load("admin");
    -$langs->load("ftp");
    +$langs->loadLangs(array("admin", "ftp"));
     
     // Security check
     if (!$user->admin) accessforbidden();
    @@ -309,6 +308,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php
    index 943d4fa94e1..64b9fb0a8ea 100644
    --- a/htdocs/ftp/index.php
    +++ b/htdocs/ftp/index.php
    @@ -22,7 +22,7 @@
      *	\brief      Main page for FTP section area
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
    @@ -235,7 +235,6 @@ if ($_POST["const"] && $_POST["delete"] && $_POST["delete"] == $langs->trans("De
     				$action='';
     			}
     		}
    -
     	}
     	else
     	{
    @@ -339,7 +338,6 @@ if ($action == 'download')
     		{
     			setEventMessages($langs->transnoentitiesnoconv('FailedToGetFile',$remotefile), null, 'errors');
     		}
    -
     	}
     	else
     	{
    @@ -378,7 +376,7 @@ jQuery(document).ready(function() {
     		$(".checkboxfordelete").prop('checked', false);
     		jQuery("#delconst").hide();
     	});
    -	
    +
     });
     
     </script>
    @@ -408,7 +406,6 @@ else
     		if ($action == 'delete')
     		{
     			print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'&section='.urlencode($_REQUEST["section"]).'&file='.urlencode($_GET["file"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1);
    -			
     		}
     
     		// Confirmation de la suppression d'une ligne categorie
    @@ -486,7 +483,7 @@ else
     			$newsection=$section;
     		    $newsectioniso=utf8_decode($section);
     			//$newsection='/home';
    -			
    +
     			// List content of directory ($newsection = '/', '/home', ...)
     			if (! empty($conf->global->FTP_CONNECT_WITH_SFTP))
     			{
    @@ -551,7 +548,7 @@ else
     					$is_directory=ftp_isdir($conn_id, $newremotefileiso);
     				}
     
    -				
    +
     				print '<tr class="oddeven" height="18">';
     				// Name
     				print '<td>';
    @@ -610,19 +607,18 @@ else
     				$i++;
     				$nbofentries++;
     			}
    -
     		}
     
     		print "</table>";
     
    -		
    +
     		if (! $ok)
     		{
     		      print $mesg.'<br>'."\n";
     		      setEventMessages($mesg, null, 'errors');
     		}
    -		
    -		
    +
    +
     		// Actions
     		/*
     		if ($user->rights->ftp->write && ! empty($section))
    @@ -654,7 +650,7 @@ else
     				break;
     			}
     			$i++;
    -		}		
    +		}
     	    if (! $foundsetup)
     	    {
                 print $langs->trans("SetupOfFTPClientModuleNotComplete");
    @@ -669,11 +665,11 @@ else
     print '<br>';
     
     // Close FTP connection
    -if ($conn_id) 
    +if ($conn_id)
     {
         if (! empty($conf->global->FTP_CONNECT_WITH_SFTP))
         {
    -        
    +
         }
         else if (! empty($conf->global->FTP_CONNECT_WITH_SSL))
         {
    @@ -684,10 +680,9 @@ if ($conn_id)
             ftp_close($conn_id);
         }
     }
    -    
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    @@ -709,7 +704,7 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect
     
     	$ok=1;
         $conn_id=null;
    -    
    +
     	if (! is_numeric($ftp_port))
     	{
     		$mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServer",$ftp_server,$ftp_port);
    @@ -719,17 +714,17 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect
     	if ($ok)
     	{
     		$connecttimeout=(empty($conf->global->FTP_CONNECT_TIMEOUT)?40:$conf->global->FTP_CONNECT_TIMEOUT);
    -		if (! empty($conf->global->FTP_CONNECT_WITH_SFTP)) 
    +		if (! empty($conf->global->FTP_CONNECT_WITH_SFTP))
     		{
     		    dol_syslog('Try to connect with ssh2_ftp');
     		    $tmp_conn_id = ssh2_connect($ftp_server, $ftp_port);
     		}
    -		else if (! empty($conf->global->FTP_CONNECT_WITH_SSL)) 
    +		else if (! empty($conf->global->FTP_CONNECT_WITH_SSL))
     		{
     		    dol_syslog('Try to connect with ftp_ssl_connect');
     		    $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout);
     		}
    -		else 
    +		else
     		{
     		    dol_syslog('Try to connect with ftp_connect');
     		    $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout);
    @@ -744,7 +739,7 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect
         				{
         					// Turn on passive mode transfers (must be after a successful login
         					//if ($ftp_passive) ftp_pasv($conn_id, true);
    -    
    +
         					// Change the dir
         					$newsectioniso=utf8_decode($section);
         					//ftp_chdir($conn_id, $newsectioniso);
    @@ -756,25 +751,25 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect
             				    $error++;
     		                }
         				}
    -    				else 
    +    				else
         				{
         					$mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials");
     	   				    $ok=0;
         				    $error++;
         				}
    -				}   
    +				}
     				else
     				{
     				    if (ftp_login($conn_id, $ftp_user, $ftp_password))
         				{
         					// Turn on passive mode transfers (must be after a successful login
         					if ($ftp_passive) ftp_pasv($conn_id, true);
    -    
    +
         					// Change the dir
         					$newsectioniso=utf8_decode($section);
         					ftp_chdir($conn_id, $newsectioniso);
         				}
    -    				else 
    +    				else
         				{
         					$mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials");
     	   				    $ok=0;
    @@ -809,7 +804,6 @@ function ftp_isdir($connect_id,$dir)
     	{
     		ftp_cdup($connect_id);
     		return 1;
    -
     	}
     	else
     	{
    diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php
    index 2ac212527b3..a1bf6e3fa6a 100644
    --- a/htdocs/holiday/card.php
    +++ b/htdocs/holiday/card.php
    @@ -4,7 +4,8 @@
      * Copyright (C) 2012-2016	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2013		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2017		Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2014-2017	Ferran Marcet		<fmarcet@2byte.es>
    + * Copyright (C) 2014-2017  Ferran Marcet		<fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -26,7 +27,7 @@
      *		\brief      Form and file creation of paid holiday.
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
    @@ -40,6 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php';
     // Get parameters
     $action=GETPOST('action', 'alpha');
     $id=GETPOST('id', 'int');
    +$ref=GETPOST('ref', 'alpha');
     $fuserid = (GETPOST('fuserid','int')?GETPOST('fuserid','int'):$user->id);
     
     // Protection if external user
    @@ -213,7 +215,7 @@ if ($action == 'update')
         $object->fetch($id);
     
     	// If under validation
    -    if ($object->statut == 1)
    +    if ($object->statut == Holiday::STATUS_DRAFT)
         {
             // If this is the requestor or has read/write rights
             if ($cancreate)
    @@ -297,7 +299,7 @@ if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights-
     	$object->fetch($id);
     
         // If this is a rough draft, approved, canceled or refused
    -	if ($object->statut == 1 || $object->statut == 4 || $object->statut == 5)
    +	if ($object->statut == Holiday::STATUS_DRAFT || $object->statut == Holiday::STATUS_CANCELED || $object->statut == Holiday::STATUS_REFUSED)
     	{
     		// Si l'utilisateur à le droit de lire cette demande, il peut la supprimer
     		if ($candelete)
    @@ -324,18 +326,20 @@ if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights-
     	}
     }
     
    -// Si envoi de la demande
    +// Action validate (+ send email for approval)
     if ($action == 'confirm_send')
     {
         $object = new Holiday($db);
         $object->fetch($id);
     
         // Si brouillon et créateur
    -    if($object->statut == 1 && $cancreate)
    +    if($object->statut == Holiday::STATUS_DRAFT && $cancreate)
         {
    -        $object->statut = 2;
    +    	$object->oldcopy = dol_clone($object);
     
    -        $verif = $object->update($user);
    +    	$object->statut = Holiday::STATUS_VALIDATED;
    +
    +        $verif = $object->validate($user);
     
             // Si pas d'erreur SQL on redirige vers la fiche de la demande
             if ($verif > 0)
    @@ -434,13 +438,15 @@ if ($action == 'confirm_valid')
         $object->fetch($id);
     
         // Si statut en attente de validation et valideur = utilisateur
    -    if ($object->statut == 2 && $user->id == $object->fk_validator)
    +    if ($object->statut == Holiday::STATUS_VALIDATED && $user->id == $object->fk_validator)
         {
    +    	$object->oldcopy = dol_clone($object);
    +
             $object->date_valid = dol_now();
             $object->fk_user_valid = $user->id;
    -        $object->statut = 3;
    +        $object->statut = Holiday::STATUS_APPROVED;
     
    -        $verif = $object->update($user);
    +        $verif = $object->approve($user);
     
             // Si pas d'erreur SQL on redirige vers la fiche de la demande
             if ($verif > 0)
    @@ -529,11 +535,11 @@ if ($action == 'confirm_refuse' && GETPOST('confirm','alpha') == 'yes')
             $object->fetch($id);
     
             // Si statut en attente de validation et valideur = utilisateur
    -        if ($object->statut == 2 && $user->id == $object->fk_validator)
    +        if ($object->statut == Holiday::STATUS_VALIDATED && $user->id == $object->fk_validator)
             {
                 $object->date_refuse = dol_print_date('dayhour', dol_now());
                 $object->fk_user_refuse = $user->id;
    -            $object->statut = 5;
    +            $object->statut = Holiday::STATUS_REFUSED;
                 $object->detail_refuse = GETPOST('detail_refuse','alphanohtml');
     
                 $verif = $object->update($user);
    @@ -614,7 +620,7 @@ if ($action == 'confirm_draft' && GETPOST('confirm') == 'yes')
         $object->fetch($id);
     
         $oldstatus = $object->statut;
    -    $object->statut = 1;
    +    $object->statut = Holiday::STATUS_DRAFT;
     
         $result = $object->update($user);
         if ($result < 0)
    @@ -645,18 +651,18 @@ if ($action == 'confirm_cancel' && GETPOST('confirm') == 'yes')
         $object->fetch($id);
     
         // Si statut en attente de validation et valideur = valideur ou utilisateur, ou droits de faire pour les autres
    -    if (($object->statut == 2 || $object->statut == 3) && ($user->id == $object->fk_validator || in_array($object->fk_user, $childids) || ! empty($user->rights->holiday->write_all)))
    +    if (($object->statut == Holiday::STATUS_VALIDATED || $object->statut == Holiday::STATUS_APPROVED) && ($user->id == $object->fk_validator || in_array($object->fk_user, $childids) || ! empty($user->rights->holiday->write_all)))
         {
         	$db->begin();
     
         	$oldstatus = $object->statut;
             $object->date_cancel = dol_now();
             $object->fk_user_cancel = $user->id;
    -        $object->statut = 4;
    +        $object->statut = Holiday::STATUS_CANCELED;
     
             $result = $object->update($user);
     
    -        if ($result >= 0 && $oldstatus == 3)	// holiday was already validated, status 3, so we must increase back sold
    +        if ($result >= 0 && $oldstatus == Holiday::STATUS_APPROVED)	// holiday was already validated, status 3, so we must increase back sold
             {
             	// Calculcate number of days consummed
             	$nbopenedday=num_open_day($object->date_debut_gmt,$object->date_fin_gmt,0,1,$object->halfday);
    @@ -740,7 +746,6 @@ if ($action == 'confirm_cancel' && GETPOST('confirm') == 'yes')
                 }
             }
         }
    -
     }
     
     
    @@ -756,7 +761,7 @@ $listhalfday=array('morning'=>$langs->trans("Morning"),"afternoon"=>$langs->tran
     
     llxHeader('', $langs->trans('CPTitreMenu'));
     
    -if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create')
    +if ((empty($id) && empty($ref)) || $action == 'add' || $action == 'request' || $action == 'create')
     {
         // Si l'utilisateur n'a pas le droit de faire une demande
         if (($fuserid == $user->id && empty($user->rights->holiday->write)) || ($fuserid != $user->id && empty($user->rights->holiday->write_all)))
    @@ -909,10 +914,10 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create
             print '<td>';
             // Si la demande ne vient pas de l'agenda
             if (! GETPOST('date_debut_')) {
    -            $form->select_date(-1, 'date_debut_', 0, 0, 0, '', 1, 1);
    +            print $form->selectDate(-1, 'date_debut_', 0, 0, 0, '', 1, 1);
             } else {
                 $tmpdate = dol_mktime(0, 0, 0, GETPOST('date_debut_month','int'), GETPOST('date_debut_day','int'), GETPOST('date_debut_year','int'));
    -            $form->select_date($tmpdate, 'date_debut_', 0, 0, 0, '', 1, 1);
    +            print $form->selectDate($tmpdate, 'date_debut_', 0, 0, 0, '', 1, 1);
             }
             print ' &nbsp; &nbsp; ';
             print $form->selectarray('starthalfday', $listhalfday, (GETPOST('starthalfday','alpha')?GETPOST('starthalfday','alpha'):'morning'));
    @@ -928,10 +933,10 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create
             print '<td>';
             // Si la demande ne vient pas de l'agenda
             if (! GETPOST('date_fin_')) {
    -            $form->select_date(-1,'date_fin_', 0, 0, 0, '', 1, 1);
    +            print $form->selectDate(-1, 'date_fin_', 0, 0, 0, '', 1, 1);
             } else {
                 $tmpdate = dol_mktime(0, 0, 0, GETPOST('date_fin_month','int'), GETPOST('date_fin_day','int'), GETPOST('date_fin_year','int'));
    -            $form->select_date($tmpdate,'date_fin_', 0, 0, 0, '', 1, 1);
    +            print $form->selectDate($tmpdate, 'date_fin_', 0, 0, 0, '', 1, 1);
             }
             print ' &nbsp; &nbsp; ';
             print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday','alpha')?GETPOST('endhalfday','alpha'):'afternoon'));
    @@ -993,9 +998,9 @@ else
         else
         {
             // Affichage de la fiche d'une demande de congés payés
    -        if ($id > 0)
    +        if (($id > 0) || $ref)
             {
    -            $object->fetch($id);
    +        	$result = $object->fetch($id, $ref);
     
                 $valideur = new User($db);
                 $valideur->fetch($object->fk_validator);
    @@ -1059,7 +1064,7 @@ else
     
                     $linkback='<a href="'.DOL_URL_ROOT.'/holiday/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
    -                dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref');
    +                dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref');
     
     
                     print '<div class="fichecenter">';
    @@ -1104,9 +1109,9 @@ else
                         print '<tr>';
                         print '<td class="nowrap">'.$langs->trans('DateDebCP').' ('.$langs->trans("FirstDayOfHoliday").')</td>';
                         print '<td>';
    -                    $form->select_date($object->date_debut,'date_debut_');
    -			        print ' &nbsp; &nbsp; ';
    -        			print $form->selectarray('starthalfday', $listhalfday, (GETPOST('starthalfday')?GETPOST('starthalfday'):$starthalfday));
    +                    print $form->selectDate($object->date_debut, 'date_debut_');
    +                    print ' &nbsp; &nbsp; ';
    +                    print $form->selectarray('starthalfday', $listhalfday, (GETPOST('starthalfday')?GETPOST('starthalfday'):$starthalfday));
                         print '</td>';
                         print '</tr>';
                     }
    @@ -1126,9 +1131,9 @@ else
                         print '<tr>';
                         print '<td class="nowrap">'.$langs->trans('DateFinCP').' ('.$langs->trans("LastDayOfHoliday").')</td>';
                         print '<td>';
    -                    $form->select_date($object->date_fin,'date_fin_');
    -			        print ' &nbsp; &nbsp; ';
    -        			print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday')?GETPOST('endhalfday'):$endhalfday));
    +                    print $form->selectDate($object->date_fin, 'date_fin_');
    +                    print ' &nbsp; &nbsp; ';
    +                    print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday')?GETPOST('endhalfday'):$endhalfday));
                         print '</td>';
                         print '</tr>';
                     }
    @@ -1255,7 +1260,7 @@ else
                     }
     
                     // Si envoi en validation
    -                if ($action == 'sendToValidate' && $object->statut == 1)
    +                if ($action == 'sendToValidate' && $object->statut == Holiday::STATUS_DRAFT)
                     {
                     	print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("TitleToValidCP"),$langs->trans("ConfirmToValidCP"),"confirm_send", '', 1, 1);
                     }
    @@ -1286,10 +1291,10 @@ else
                     }
     
     
    -                if ($action == 'edit' && $object->statut == 1)
    +                if ($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT)
                     {
                         print '<div align="center">';
    -                    if ($cancreate && $object->statut == 1)
    +                    if ($cancreate && $object->statut == Holiday::STATUS_DRAFT)
                         {
                             print '<input type="submit" value="'.$langs->trans("Save").'" class="button">';
                         }
    @@ -1341,23 +1346,19 @@ else
     
                         print '</div>';
                     }
    -
                 } else {
                     print '<div class="tabBar">';
                     print $langs->trans('ErrorUserViewCP');
                     print '<br><br><input type="button" value="'.$langs->trans("ReturnCP").'" class="button" onclick="history.go(-1)" />';
                     print '</div>';
                 }
    -
             } else {
                 print '<div class="tabBar">';
                 print $langs->trans('ErrorIDFicheCP');
                 print '<br><br><input type="button" value="'.$langs->trans("ReturnCP").'" class="button" onclick="history.go(-1)" />';
                 print '</div>';
             }
    -
         }
    -
     }
     
     // End of page
    diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php
    index 03b2491ab59..6dd49b52a93 100644
    --- a/htdocs/holiday/class/holiday.class.php
    +++ b/htdocs/holiday/class/holiday.class.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2012-2016	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2013		Florian Henry		<florian.henry@open-concept.pro>
      * Copyright (C) 2016       Juanjo Menent       <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -32,44 +33,94 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Holiday extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='holiday';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='holiday';
    -	public $ismultientitymanaged = 0;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    -	var $fk_element = 'fk_holiday';
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 0;
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element = 'fk_holiday';
    +
     	public $picto = 'holiday';
     
     	/**
     	 * @deprecated
    -	 * @see id
    +	 * @see $id
     	 */
    -	var $rowid;
    +	public $rowid;
     
    -	var $fk_user;
    -	var $date_create='';
    -	var $description;
    -	var $date_debut='';			// Date start in PHP server TZ
    -	var $date_fin='';			// Date end in PHP server TZ
    -	var $date_debut_gmt='';		// Date start in GMT
    -	var $date_fin_gmt='';		// Date end in GMT
    -	var $halfday='';			// 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning
    -	var $statut='';				// 1=draft, 2=validated, 3=approved
    -	var $fk_validator;
    -	var $date_valid='';
    -	var $fk_user_valid;
    -	var $date_refuse='';
    -	var $fk_user_refuse;
    -	var $date_cancel='';
    -	var $fk_user_cancel;
    -	var $detail_refuse='';
    -	var $fk_type;
    +	/**
    +	 * @var int User ID
    +	 */
    +	public $fk_user;
     
    -	var $holiday = array();
    -	var $events = array();
    -	var $logs = array();
    +	public $date_create='';
     
    -	var $optName = '';
    -	var $optValue = '';
    -	var $optRowid = '';
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +	public $date_debut='';			// Date start in PHP server TZ
    +	public $date_fin='';			// Date end in PHP server TZ
    +	public $date_debut_gmt='';		// Date start in GMT
    +	public $date_fin_gmt='';		// Date end in GMT
    +	public $halfday='';				// 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning
    +	public $statut='';				// 1=draft, 2=validated, 3=approved
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_validator;
    +
    +	public $date_valid='';
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_valid;
    +
    +	public $date_refuse='';
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_refuse;
    +
    +	public $date_cancel='';
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_cancel;
    +
    +	public $detail_refuse='';
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_type;
    +
    +	public $holiday = array();
    +	public $events = array();
    +	public $logs = array();
    +
    +	public $optName = '';
    +	public $optValue = '';
    +	public $optRowid = '';
     
     	/**
     	 * Draft status
    @@ -104,6 +155,67 @@ class Holiday extends CommonObject
     	}
     
     
    +	/**
    +	 *  Returns the reference to the following non used Order depending on the active numbering module
    +	 *  defined into HOLIDAY_ADDON
    +	 *
    +	 *	@param	Societe		$objsoc     third party object
    +	 *  @return string      			Holiday free reference
    +	 */
    +	function getNextNumRef($objsoc)
    +	{
    +		global $langs, $conf;
    +		$langs->load("order");
    +
    +		if (empty($conf->global->HOLIDAY_ADDON))
    +		{
    +			$conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
    +		}
    +
    +		if (! empty($conf->global->HOLIDAY_ADDON))
    +		{
    +			$mybool=false;
    +
    +			$file = $conf->global->HOLIDAY_ADDON.".php";
    +			$classname = $conf->global->HOLIDAY_ADDON;
    +
    +			// Include file with class
    +			$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']);
    +			foreach ($dirmodels as $reldir)
    +			{
    +				$dir = dol_buildpath($reldir."core/modules/holiday/");
    +
    +				// Load file with numbering class (if found)
    +				$mybool|=@include_once $dir.$file;
    +			}
    +
    +			if ($mybool === false)
    +			{
    +				dol_print_error('',"Failed to include file ".$file);
    +				return '';
    +			}
    +
    +			$obj = new $classname();
    +			$numref = $obj->getNextValue($objsoc,$this);
    +
    +			if ($numref != "")
    +			{
    +				return $numref;
    +			}
    +			else
    +			{
    +				$this->error=$obj->error;
    +				//dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
    +				return "";
    +			}
    +		}
    +		else
    +		{
    +			print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
    +			return "";
    +		}
    +	}
    +
     	/**
     	 * Update balance of vacations and check table of users for holidays is complete. If not complete.
     	 *
    @@ -221,14 +333,16 @@ class Holiday extends CommonObject
     	 *	Load object in memory from database
     	 *
     	 *  @param	int		$id         Id object
    +	 *  @param	string	$ref        Ref object
     	 *  @return int         		<0 if KO, >0 if OK
     	 */
    -	function fetch($id)
    +	function fetch($id, $ref='')
     	{
     		global $langs;
     
     		$sql = "SELECT";
     		$sql.= " cp.rowid,";
    +		$sql.= " cp.ref,";
     		$sql.= " cp.fk_user,";
     		$sql.= " cp.date_create,";
     		$sql.= " cp.description,";
    @@ -250,7 +364,8 @@ class Holiday extends CommonObject
     		$sql.= " cp.fk_type,";
     		$sql.= " cp.entity";
     		$sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp";
    -		$sql.= " WHERE cp.rowid = ".$id;
    +		if ($id > 0) $sql.= " WHERE cp.rowid = ".$id;
    +		else $sql.=" WHERE cp.ref = '".$this->db->escape($ref)."'";
     
     		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
     		$resql=$this->db->query($sql);
    @@ -262,7 +377,7 @@ class Holiday extends CommonObject
     
     				$this->id    = $obj->rowid;
     				$this->rowid = $obj->rowid;	// deprecated
    -				$this->ref   = $obj->rowid;
    +				$this->ref   = ($obj->ref?$obj->ref:$obj->rowid);
     				$this->fk_user = $obj->fk_user;
     				$this->date_create = $this->db->jdate($obj->date_create);
     				$this->description = $obj->description;
    @@ -311,6 +426,7 @@ class Holiday extends CommonObject
     
     		$sql = "SELECT";
     		$sql.= " cp.rowid,";
    +		$sql.= " cp.ref,";
     
     		$sql.= " cp.fk_user,";
     		$sql.= " cp.fk_type,";
    @@ -346,12 +462,12 @@ class Holiday extends CommonObject
     		$sql.= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
     		$sql.= " AND cp.fk_user IN (".$user_id.")";
     
    -		// Filtre de séléction
    +		// Selection filter
     		if(!empty($filter)) {
     			$sql.= $filter;
     		}
     
    -		// Ordre d'affichage du résultat
    +		// Order of display of the result
     		if(!empty($order)) {
     			$sql.= $order;
     		}
    @@ -359,25 +475,26 @@ class Holiday extends CommonObject
     		dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
     		$resql=$this->db->query($sql);
     
    -		// Si pas d'erreur SQL
    +		// If no SQL error
     		if ($resql) {
     
     			$i = 0;
     			$tab_result = $this->holiday;
     			$num = $this->db->num_rows($resql);
     
    -			// Si pas d'enregistrement
    +			// If no registration
     			if(!$num) {
     				return 2;
     			}
     
    -			// Liste les enregistrements et les ajoutent au tableau
    +			// List the records and add them to the table
     			while($i < $num) {
     
     				$obj = $this->db->fetch_object($resql);
     
     				$tab_result[$i]['rowid'] = $obj->rowid;
    -				$tab_result[$i]['ref'] = $obj->rowid;
    +				$tab_result[$i]['ref'] = ($obj->ref?$obj->ref:$obj->rowid);
    +
     				$tab_result[$i]['fk_user'] = $obj->fk_user;
     				$tab_result[$i]['fk_type'] = $obj->fk_type;
     				$tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
    @@ -412,13 +529,13 @@ class Holiday extends CommonObject
     				$i++;
     			}
     
    -			// Retourne 1 avec le tableau rempli
    +			// Returns 1 with the filled array
     			$this->holiday = $tab_result;
     			return 1;
     		}
     		else
     		{
    -			// Erreur SQL
    +			// SQL Error
     			$this->error="Error ".$this->db->lasterror();
     			return -1;
     		}
    @@ -437,6 +554,7 @@ class Holiday extends CommonObject
     
     		$sql = "SELECT";
     		$sql.= " cp.rowid,";
    +		$sql.= " cp.ref,";
     
     		$sql.= " cp.fk_user,";
     		$sql.= " cp.fk_type,";
    @@ -471,12 +589,12 @@ class Holiday extends CommonObject
     		$sql.= " WHERE cp.entity IN (".getEntity('holiday').")";
     		$sql.= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
     
    -		// Filtrage de séléction
    +		// Selection filtering
     		if(!empty($filter)) {
     			$sql.= $filter;
     		}
     
    -		// Ordre d'affichage
    +		// order of display
     		if(!empty($order)) {
     			$sql.= $order;
     		}
    @@ -484,25 +602,25 @@ class Holiday extends CommonObject
     		dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
     		$resql=$this->db->query($sql);
     
    -		// Si pas d'erreur SQL
    +		// If no SQL error
     		if ($resql) {
     
     			$i = 0;
     			$tab_result = $this->holiday;
     			$num = $this->db->num_rows($resql);
     
    -			// Si pas d'enregistrement
    +			// If no registration
     			if(!$num) {
     				return 2;
     			}
     
    -			// On liste les résultats et on les ajoutent dans le tableau
    +			// List the records and add them to the table
     			while($i < $num) {
     
     				$obj = $this->db->fetch_object($resql);
     
     				$tab_result[$i]['rowid'] = $obj->rowid;
    -				$tab_result[$i]['ref'] = $obj->rowid;
    +				$tab_result[$i]['ref'] = ($obj->ref?$obj->ref:$obj->rowid);
     				$tab_result[$i]['fk_user'] = $obj->fk_user;
     				$tab_result[$i]['fk_type'] = $obj->fk_type;
     				$tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
    @@ -536,18 +654,203 @@ class Holiday extends CommonObject
     
     				$i++;
     			}
    -			// Retourne 1 et ajoute le tableau à la variable
    +			// Returns 1 and adds the array to the variable
     			$this->holiday = $tab_result;
     			return 1;
     		}
     		else
     		{
    -			// Erreur SQL
    +			// SQL Error
     			$this->error="Error ".$this->db->lasterror();
     			return -1;
     		}
     	}
     
    +
    +	/**
    +	 *	Validate leave request
    +	 *
    +	 *  @param	User	$user        	User that validate
    +	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
    +	 *  @return int         			<0 if KO, >0 if OK
    +	 */
    +	function validate($user=null, $notrigger=0)
    +	{
    +		global $conf, $langs;
    +		$error=0;
    +
    +		// Define new ref
    +		if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id))
    +		{
    +			$num = $this->getNextNumRef(null);
    +		}
    +		else
    +		{
    +			$num = $this->ref;
    +		}
    +		$this->newref = $num;
    +
    +		// Update status
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
    +		if(!empty($this->statut) && is_numeric($this->statut)) {
    +			$sql.= " statut = ".$this->statut.",";
    +		} else {
    +			$error++;
    +		}
    +		$sql.= " ref = '".$num."'";
    +		$sql.= " WHERE rowid= ".$this->id;
    +
    +		$this->db->begin();
    +
    +		dol_syslog(get_class($this)."::validate", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if (! $resql) {
    +			$error++; $this->errors[]="Error ".$this->db->lasterror();
    +		}
    +
    +		if (! $error)
    +		{
    +			if (! $notrigger)
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('HOLIDAY_VALIDATE',$user);
    +				if ($result < 0) { $error++; }
    +				// End call triggers
    +			}
    +		}
    +
    +		// Commit or rollback
    +		if ($error)
    +		{
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +		else
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +	}
    +
    +
    +	/**
    +	 *	Approve leave request
    +	 *
    +	 *  @param	User	$user        	User that approve
    +	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
    +	 *  @return int         			<0 if KO, >0 if OK
    +	 */
    +	function approve($user=null, $notrigger=0)
    +	{
    +		global $conf, $langs;
    +		$error=0;
    +
    +		// Update request
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
    +
    +		$sql.= " description= '".$this->db->escape($this->description)."',";
    +
    +		if(!empty($this->date_debut)) {
    +			$sql.= " date_debut = '".$this->db->idate($this->date_debut)."',";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->date_fin)) {
    +			$sql.= " date_fin = '".$this->db->idate($this->date_fin)."',";
    +		} else {
    +			$error++;
    +		}
    +		$sql.= " halfday = ".$this->halfday.",";
    +		if(!empty($this->statut) && is_numeric($this->statut)) {
    +			$sql.= " statut = ".$this->statut.",";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->fk_validator)) {
    +			$sql.= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->date_valid)) {
    +			$sql.= " date_valid = '".$this->db->idate($this->date_valid)."',";
    +		} else {
    +			$sql.= " date_valid = NULL,";
    +		}
    +		if(!empty($this->fk_user_valid)) {
    +			$sql.= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',";
    +		} else {
    +			$sql.= " fk_user_valid = NULL,";
    +		}
    +		if(!empty($this->date_refuse)) {
    +			$sql.= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
    +		} else {
    +			$sql.= " date_refuse = NULL,";
    +		}
    +		if(!empty($this->fk_user_refuse)) {
    +			$sql.= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',";
    +		} else {
    +			$sql.= " fk_user_refuse = NULL,";
    +		}
    +		if(!empty($this->date_cancel)) {
    +			$sql.= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
    +		} else {
    +			$sql.= " date_cancel = NULL,";
    +		}
    +		if(!empty($this->fk_user_cancel)) {
    +			$sql.= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',";
    +		} else {
    +			$sql.= " fk_user_cancel = NULL,";
    +		}
    +		if(!empty($this->detail_refuse)) {
    +			$sql.= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
    +		} else {
    +			$sql.= " detail_refuse = NULL";
    +		}
    +
    +		$sql.= " WHERE rowid= ".$this->id;
    +
    +		$this->db->begin();
    +
    +		dol_syslog(get_class($this)."::approve", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if (! $resql) {
    +			$error++; $this->errors[]="Error ".$this->db->lasterror();
    +		}
    +
    +		if (! $error)
    +		{
    +			if (! $notrigger)
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('HOLIDAY_APPROVE',$user);
    +				if ($result < 0) { $error++; }
    +				// End call triggers
    +			}
    +		}
    +
    +		// Commit or rollback
    +		if ($error)
    +		{
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +		else
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +	}
    +
     	/**
     	 *	Update database
     	 *
    @@ -913,6 +1216,7 @@ class Holiday extends CommonObject
     		return $this->LibStatut($this->statut, $mode, $this->date_debut);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Returns the label of a statut
     	 *
    @@ -923,58 +1227,59 @@ class Holiday extends CommonObject
     	 */
     	function LibStatut($statut, $mode=0, $startdate='')
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			if ($statut == 1) return $langs->trans('DraftCP');
    -			if ($statut == 2) return $langs->trans('ToReviewCP');
    -			if ($statut == 3) return $langs->trans('ApprovedCP');
    -			if ($statut == 4) return $langs->trans('CancelCP');
    -			if ($statut == 5) return $langs->trans('RefuseCP');
    +			elseif ($statut == 2) return $langs->trans('ToReviewCP');
    +			elseif ($statut == 3) return $langs->trans('ApprovedCP');
    +			elseif ($statut == 4) return $langs->trans('CancelCP');
    +			elseif ($statut == 5) return $langs->trans('RefuseCP');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			$pictoapproved='statut6';
     			if (! empty($startdate) && $startdate > dol_now()) $pictoapproved='statut4';
     			if ($statut == 1) return img_picto($langs->trans('DraftCP'),'statut0').' '.$langs->trans('DraftCP');				// Draft
    -			if ($statut == 2) return img_picto($langs->trans('ToReviewCP'),'statut1').' '.$langs->trans('ToReviewCP');		// Waiting approval
    -			if ($statut == 3) return img_picto($langs->trans('ApprovedCP'),$pictoapproved).' '.$langs->trans('ApprovedCP');
    -			if ($statut == 4) return img_picto($langs->trans('CancelCP'),'statut5').' '.$langs->trans('CancelCP');
    -			if ($statut == 5) return img_picto($langs->trans('RefuseCP'),'statut5').' '.$langs->trans('RefuseCP');
    +			elseif ($statut == 2) return img_picto($langs->trans('ToReviewCP'),'statut1').' '.$langs->trans('ToReviewCP');		// Waiting approval
    +			elseif ($statut == 3) return img_picto($langs->trans('ApprovedCP'),$pictoapproved).' '.$langs->trans('ApprovedCP');
    +			elseif ($statut == 4) return img_picto($langs->trans('CancelCP'),'statut5').' '.$langs->trans('CancelCP');
    +			elseif ($statut == 5) return img_picto($langs->trans('RefuseCP'),'statut5').' '.$langs->trans('RefuseCP');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			$pictoapproved='statut6';
     			if (! empty($startdate) && $startdate > dol_now()) $pictoapproved='statut4';
     			if ($statut == 1) return img_picto($langs->trans('DraftCP'),'statut0');
    -			if ($statut == 2) return img_picto($langs->trans('ToReviewCP'),'statut1');
    -			if ($statut == 3) return img_picto($langs->trans('ApprovedCP'),$pictoapproved);
    -			if ($statut == 4) return img_picto($langs->trans('CancelCP'),'statut5');
    -			if ($statut == 5) return img_picto($langs->trans('RefuseCP'),'statut5');
    +			elseif ($statut == 2) return img_picto($langs->trans('ToReviewCP'),'statut1');
    +			elseif ($statut == 3) return img_picto($langs->trans('ApprovedCP'),$pictoapproved);
    +			elseif ($statut == 4) return img_picto($langs->trans('CancelCP'),'statut5');
    +			elseif ($statut == 5) return img_picto($langs->trans('RefuseCP'),'statut5');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			$pictoapproved='statut6';
     			if (! empty($startdate) && $startdate > dol_now()) $pictoapproved='statut4';
     			if ($statut == 1) return $langs->trans('DraftCP').' '.img_picto($langs->trans('DraftCP'),'statut0');				// Draft
    -			if ($statut == 2) return $langs->trans('ToReviewCP').' '.img_picto($langs->trans('ToReviewCP'),'statut1');		// Waiting approval
    -			if ($statut == 3) return $langs->trans('ApprovedCP').' '.img_picto($langs->trans('ApprovedCP'),$pictoapproved);
    -			if ($statut == 4) return $langs->trans('CancelCP').' '.img_picto($langs->trans('CancelCP'),'statut5');
    -			if ($statut == 5) return $langs->trans('RefuseCP').' '.img_picto($langs->trans('RefuseCP'),'statut5');
    +			elseif ($statut == 2) return $langs->trans('ToReviewCP').' '.img_picto($langs->trans('ToReviewCP'),'statut1');		// Waiting approval
    +			elseif ($statut == 3) return $langs->trans('ApprovedCP').' '.img_picto($langs->trans('ApprovedCP'),$pictoapproved);
    +			elseif ($statut == 4) return $langs->trans('CancelCP').' '.img_picto($langs->trans('CancelCP'),'statut5');
    +			elseif ($statut == 5) return $langs->trans('RefuseCP').' '.img_picto($langs->trans('RefuseCP'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			$pictoapproved='statut6';
     			if (! empty($startdate) && $startdate > dol_now()) $pictoapproved='statut4';
     			if ($statut == 1) return $langs->trans('DraftCP').' '.img_picto($langs->trans('DraftCP'),'statut0');				// Draft
    -			if ($statut == 2) return $langs->trans('ToReviewCP').' '.img_picto($langs->trans('ToReviewCP'),'statut1');		// Waiting approval
    -			if ($statut == 3) return $langs->trans('ApprovedCP').' '.img_picto($langs->trans('ApprovedCP'),$pictoapproved);
    -			if ($statut == 4) return $langs->trans('CancelCP').' '.img_picto($langs->trans('CancelCP'),'statut5');
    -			if ($statut == 5) return $langs->trans('RefuseCP').' '.img_picto($langs->trans('RefuseCP'),'statut5');
    +			elseif ($statut == 2) return $langs->trans('ToReviewCP').' '.img_picto($langs->trans('ToReviewCP'),'statut1');		// Waiting approval
    +			elseif ($statut == 3) return $langs->trans('ApprovedCP').' '.img_picto($langs->trans('ApprovedCP'),$pictoapproved);
    +			elseif ($statut == 4) return $langs->trans('CancelCP').' '.img_picto($langs->trans('CancelCP'),'statut5');
    +			elseif ($statut == 5) return $langs->trans('RefuseCP').' '.img_picto($langs->trans('RefuseCP'),'statut5');
     		}
     
    -		return $statut;
    +		else return $statut;
     	}
     
     
    @@ -985,7 +1290,8 @@ class Holiday extends CommonObject
     	 *   @param		string	$htmlname		Name of HTML select field
     	 *   @return    string					Show select of status
     	 */
    -	function selectStatutCP($selected='', $htmlname='select_statut') {
    +    function selectStatutCP($selected='', $htmlname='select_statut')
    +    {
     
     		global $langs;
     
    @@ -1009,7 +1315,6 @@ class Holiday extends CommonObject
     
     		$statut.= '</select>'."\n";
     		print $statut;
    -
     	}
     
     	/**
    @@ -1019,7 +1324,8 @@ class Holiday extends CommonObject
     	 *  @param	string	$value      vrai si mise à jour OK sinon faux
     	 *  @return boolean				ok or ko
     	 */
    -	function updateConfCP($name,$value) {
    +    function updateConfCP($name,$value)
    +    {
     
     		$sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
     		$sql.= " value = '".$value."'";
    @@ -1238,7 +1544,6 @@ class Holiday extends CommonObject
     				return -1;
     			}
     		}
    -
     	}
     
     	/**
    @@ -1247,7 +1552,8 @@ class Holiday extends CommonObject
     	 *  @param	string	$name       name du paramètre de configuration
     	 *  @return string      		retourne checked si > 0
     	 */
    -	function getCheckOption($name) {
    +    function getCheckOption($name)
    +    {
     
     		$sql = "SELECT value";
     		$sql.= " FROM ".MAIN_DB_PREFIX."holiday_config";
    @@ -1308,13 +1614,13 @@ class Holiday extends CommonObject
     	 *  @param	int		$user_id        ID de l'utilisateur à supprimer
     	 *  @return boolean      			Vrai si pas d'erreur, faut si Erreur
     	 */
    -	function deleteCPuser($user_id) {
    +    function deleteCPuser($user_id)
    +    {
     
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday_users";
     		$sql.= " WHERE fk_user = '".$user_id."'";
     
     		$this->db->query($sql);
    -
     	}
     
     
    @@ -1415,7 +1721,6 @@ class Holiday extends CommonObject
     					$this->error="Error ".$this->db->lasterror();
     					return -1;
     				}
    -
     			}
     			else
     			{
    @@ -1457,7 +1762,6 @@ class Holiday extends CommonObject
     					return -1;
     				}
     			}
    -
     		}
     		else
     		{ // Si faux donc return array
    @@ -1570,6 +1874,7 @@ class Holiday extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return list of people with permission to validate leave requests.
     	 * Search for permission "approve leave requests"
    @@ -1578,6 +1883,7 @@ class Holiday extends CommonObject
     	 */
     	function fetch_users_approver_holiday()
     	{
    +        // phpcs:enable
     		$users_validator=array();
     
     		$sql = "SELECT DISTINCT ur.fk_user";
    @@ -1632,7 +1938,8 @@ class Holiday extends CommonObject
     	 *
     	 *  @return     int      retourne le nombre d'utilisateur
     	 */
    -	function countActiveUsersWithoutCP() {
    +    function countActiveUsersWithoutCP()
    +    {
     
     		$sql = "SELECT count(u.rowid) as compteur";
     		$sql.= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
    @@ -1868,5 +2175,4 @@ class Holiday extends CommonObject
     		$this->halfday=0;
     		$this->fk_type=1;
     	}
    -
     }
    diff --git a/htdocs/holiday/define_holiday.php b/htdocs/holiday/define_holiday.php
    index 55724549360..c0bfff15507 100644
    --- a/htdocs/holiday/define_holiday.php
    +++ b/htdocs/holiday/define_holiday.php
    @@ -26,7 +26,7 @@
      *		\brief      File that defines the balance of paid holiday of users.
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
     require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php';
     
    @@ -374,6 +374,6 @@ else
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/holiday/document.php b/htdocs/holiday/document.php
    index 9d5618f3a2a..5f33e24e8c6 100644
    --- a/htdocs/holiday/document.php
    +++ b/htdocs/holiday/document.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2003-2007 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2010 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
    - * Copyright (C) 2005-2009 Regis Houssin         <regis.houssin@capnetworks.com>
    - * Copyright (C) 2005      Simon TOSSER          <simon@kornog-computing.com>
    - * Copyright (C) 2011-2012 Juanjo Menent         <jmenent@2byte.es>
    - * Copyright (C) 2013      Cédric Salvador       <csalvador@gpcsolutions.fr>
    +/* Copyright (C) 2003-2007  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2009  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2005       Simon TOSSER            <simon@kornog-computing.com>
    + * Copyright (C) 2011-2012  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -99,7 +100,7 @@ if ($object->id)
     	dol_fiche_head($head, 'documents', $langs->trans("CPTitreMenu"), -1,'holiday');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -110,7 +111,7 @@ if ($object->id)
     
     	$linkback='<a href="'.DOL_URL_ROOT.'/holiday/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
    -	dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref');
    +	dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref');
     
     
     	print '<div class="fichecenter">';
    @@ -152,7 +153,7 @@ if ($object->id)
             print '<tr>';
             print '<td>'.$langs->trans('DateDebCP').' ('.$langs->trans("FirstDayOfHoliday").')</td>';
             print '<td>';
    -        $form->select_date($object->date_debut,'date_debut_');
    +        print $form->selectDate($object->date_debut, 'date_debut_');
             print ' &nbsp; &nbsp; ';
     		print $form->selectarray('starthalfday', $listhalfday, (GETPOST('starthalfday')?GETPOST('starthalfday'):$starthalfday));
             print '</td>';
    @@ -174,9 +175,9 @@ if ($object->id)
             print '<tr>';
             print '<td>'.$langs->trans('DateFinCP').' ('.$langs->trans("LastDayOfHoliday").')</td>';
             print '<td>';
    -        $form->select_date($object->date_fin,'date_fin_');
    +        print $form->selectDate($object->date_fin, 'date_fin_');
             print ' &nbsp; &nbsp; ';
    -		print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday')?GETPOST('endhalfday'):$endhalfday));
    +        print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday')?GETPOST('endhalfday'):$endhalfday));
             print '</td>';
             print '</tr>';
         }
    @@ -295,7 +296,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php
    index 5df3fdb314b..f155f513a18 100644
    --- a/htdocs/holiday/list.php
    +++ b/htdocs/holiday/list.php
    @@ -23,7 +23,7 @@
      *		\brief      List of holiday
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    @@ -512,7 +512,7 @@ print '</td>';
     print "</tr>\n";
     
     print '<tr class="liste_titre">';
    -print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"cp.rowid","",$param,'',$sortfield,$sortorder);
    +print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"cp.ref","",$param,'',$sortfield,$sortorder);
     print_liste_field_titre("DateCreateCP",$_SERVER["PHP_SELF"],"cp.date_create","",$param,'align="center"',$sortfield,$sortorder);
     print_liste_field_titre("Employee",$_SERVER["PHP_SELF"],"cp.fk_user","",$param,'',$sortfield,$sortorder);
     print_liste_field_titre("ValidatorCP",$_SERVER["PHP_SELF"],"cp.fk_validator","",$param,'',$sortfield,$sortorder);
    @@ -546,7 +546,7 @@ elseif (! empty($holiday->holiday) && !empty($mysoc->country_id))
     	{
     		// Leave request
     		$holidaystatic->id=$infos_CP['rowid'];
    -		$holidaystatic->ref=$infos_CP['rowid'];
    +		$holidaystatic->ref=($infos_CP['ref']?$infos_CP['ref']:$infos_CP['rowid']);
     
     		// User
     		$userstatic->id=$infos_CP['fk_user'];
    @@ -605,7 +605,6 @@ elseif (! empty($holiday->holiday) && !empty($mysoc->country_id))
     		print '</td>';
     
     		print '</tr>'."\n";
    -
     	}
     }
     
    @@ -630,8 +629,8 @@ print '</form>';
     	print '</div>';
     }*/
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    diff --git a/htdocs/holiday/month_report.php b/htdocs/holiday/month_report.php
    index 6a4da422ea3..53fab6a825f 100644
    --- a/htdocs/holiday/month_report.php
    +++ b/htdocs/holiday/month_report.php
    @@ -22,7 +22,7 @@
      *      \brief      Monthly report of leave requests.
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -189,11 +189,10 @@ else
              print '<td class="maxwidth300">' . dol_escape_htmltag(dolGetFirstLineOfText($obj->description)) . '</td>';
           print '</tr>';
        }
    -
     }
     print '</table>';
     print '</div>';
     
    -// Fin de page
    -$db->close();
    +// End of page
     llxFooter();
    +$db->close();
    diff --git a/htdocs/holiday/view_log.php b/htdocs/holiday/view_log.php
    index 198b9a8854c..124d26baf92 100644
    --- a/htdocs/holiday/view_log.php
    +++ b/htdocs/holiday/view_log.php
    @@ -23,7 +23,7 @@
      *  \ingroup    holiday
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
     require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    @@ -124,7 +124,6 @@ foreach($cp->logs as $logs_CP)
        	print '<td style="text-align: right;">'.price2num($logs_CP['prev_solde'],5).' '.$langs->trans('days').'</td>';
        	print '<td style="text-align: right;">'.price2num($logs_CP['new_solde'],5).' '.$langs->trans('days').'</td>';
        	print '</tr>'."\n";
    -
     }
     
     if ($log_holiday == '2')
    @@ -138,6 +137,6 @@ print '</tbody>'."\n";
     print '</table>'."\n";
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/hrm/admin/admin_establishment.php b/htdocs/hrm/admin/admin_establishment.php
    index 996ddd58ed3..5b15c1fb8bc 100644
    --- a/htdocs/hrm/admin/admin_establishment.php
    +++ b/htdocs/hrm/admin/admin_establishment.php
    @@ -20,7 +20,7 @@
      * \ingroup HRM
      * \brief 	HRM Establishment module setup page
      */
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php';
     
    @@ -124,7 +124,6 @@ if ($result)
     
                 $i++;
             }
    -
         }
         else
         {
    @@ -145,5 +144,6 @@ print '<div class="tabsAction">';
     print '<a class="butAction" href="../establishment/card.php?action=create">'.$langs->trans("NewEstablishment").'</a>';
     print '</div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/hrm/admin/admin_hrm.php b/htdocs/hrm/admin/admin_hrm.php
    index a7a8b8a9352..c61480347bb 100644
    --- a/htdocs/hrm/admin/admin_hrm.php
    +++ b/htdocs/hrm/admin/admin_hrm.php
    @@ -20,7 +20,7 @@
      * \ingroup HRM
      * \brief 	HRM module setup page
      */
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     
    @@ -108,5 +108,6 @@ print '<div class="center"><input type="submit" class="button" value="' . $langs
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/hrm/class/establishment.class.php b/htdocs/hrm/class/establishment.class.php
    index 8a99788d040..4153972d27c 100644
    --- a/htdocs/hrm/class/establishment.class.php
    +++ b/htdocs/hrm/class/establishment.class.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2015		Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -28,22 +29,67 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class Establishment extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='establishment';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='establishment';
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line = '';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element = 'fk_establishment';
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
         public $picto='building';
    -    
    -    public $id;
    -    public $ref;
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +    /**
    +	 * @var string Ref
    +	 */
    +	public $ref;
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
     
     	public $name;
    +
    +	/**
    +	 * @var string Address
    +	 */
     	public $address;
    +
     	public $zip;
     	public $town;
    -	public $status;		// 0=open, 1=closed
    +
    +	/**
    +	 * @var int Status 0=open, 1=closed
    +	 */
    +	public $status;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
     
     	public $country_id;
    @@ -62,8 +108,6 @@ class Establishment extends CommonObject
     
     		$this->statuts_short = array(0 => 'Closed', 1 => 'Opened');
             $this->statuts = array(0 => 'Closed', 1 => 'Opened');
    -
    -		return 1;
     	}
     
     	/**
    @@ -208,7 +252,7 @@ class Establishment extends CommonObject
     
                 $this->country_id   = $obj->country_id;
                 $this->country_code = $obj->country_code;
    -            $this->country      = $obj->country;			
    +            $this->country      = $obj->country;
     
     			return 1;
     		}
    @@ -257,6 +301,7 @@ class Establishment extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Give a label from a status
     	 *
    @@ -266,35 +311,36 @@ class Establishment extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			return $langs->trans($this->statuts[$status]);
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $langs->trans($this->statuts_short[$status]);
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status==0) return img_picto($langs->trans($this->statuts_short[$status]),'statut5').' '.$langs->trans($this->statuts_short[$status]);
    -			if ($status==1) return img_picto($langs->trans($this->statuts_short[$status]),'statut4').' '.$langs->trans($this->statuts_short[$status]);
    +			elseif ($status==1) return img_picto($langs->trans($this->statuts_short[$status]),'statut4').' '.$langs->trans($this->statuts_short[$status]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status==0 && ! empty($this->statuts_short[$status])) return img_picto($langs->trans($this->statuts_short[$status]),'statut5');
    -			if ($status==1 && ! empty($this->statuts_short[$status])) return img_picto($langs->trans($this->statuts_short[$status]),'statut4');
    +			elseif ($status==1 && ! empty($this->statuts_short[$status])) return img_picto($langs->trans($this->statuts_short[$status]),'statut4');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status==0 && ! empty($this->statuts_short[$status])) return img_picto($langs->trans($this->statuts_short[$status]),'statut5').' '.$langs->trans($this->statuts[$status]);
    -			if ($status==1 && ! empty($this->statuts_short[$status])) return img_picto($langs->trans($this->statuts_short[$status]),'statut4').' '.$langs->trans($this->statuts[$status]);
    +			elseif ($status==1 && ! empty($this->statuts_short[$status])) return img_picto($langs->trans($this->statuts_short[$status]),'statut4').' '.$langs->trans($this->statuts[$status]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status==0 && ! empty($this->statuts_short[$status])) return $langs->trans($this->statuts_short[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut5');
    -			if ($status==1 && ! empty($this->statuts_short[$status])) return $langs->trans($this->statuts_short[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut4');
    +			elseif ($status==1 && ! empty($this->statuts_short[$status])) return $langs->trans($this->statuts_short[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut4');
     		}
     	}
     
    @@ -320,7 +366,7 @@ class Establishment extends CommonObject
     				$obj = $this->db->fetch_object($result);
     				$this->id = $obj->rowid;
     
    -				$this->date_creation     = $this->db->jdate($obj->datec);
    +				$this->date_creation = $this->db->jdate($obj->datec);
     				if ($obj->fk_user_author)
     				{
     					$cuser = new User($this->db);
    @@ -386,7 +432,7 @@ class Establishment extends CommonObject
     
             return '';
         }
    -    
    +
         /**
          * Initialise object with example values
          * Id must be 0 if object instance is a specimen
    @@ -397,5 +443,5 @@ class Establishment extends CommonObject
         {
             $this->id = 0;
             $this->ref = 'DEAAA';
    -    }    
    +    }
     }
    diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php
    index db316098003..d7f591da027 100644
    --- a/htdocs/hrm/establishment/card.php
    +++ b/htdocs/hrm/establishment/card.php
    @@ -19,7 +19,7 @@
      *  \file       	htdocs/hrm/establishment/card.php
      *  \brief      	Page to show an establishment
      */
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    @@ -334,7 +334,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
         if ($action == 'delete')
         {
             print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteEstablishment"),$langs->trans("ConfirmDeleteEstablishment"),"confirm_delete");
    -
         }
     
     
    @@ -408,5 +407,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
         print '</div>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/hrm/establishment/info.php b/htdocs/hrm/establishment/info.php
    index 76eb236d1a1..35e4f483e3d 100644
    --- a/htdocs/hrm/establishment/info.php
    +++ b/htdocs/hrm/establishment/info.php
    @@ -20,7 +20,7 @@
      *  \brief      	Page to show info of an establishment
      */
     
    -require('../../main.inc.php');
    +require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php';
    @@ -53,5 +53,6 @@ if ($id)
         print '</div>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php
    index e2b6acaec4f..45d10d16d8b 100644
    --- a/htdocs/hrm/index.php
    +++ b/htdocs/hrm/index.php
    @@ -24,7 +24,7 @@
      *		\brief      Home page for HRM area.
      */
     
    -require('../main.inc.php');
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    @@ -236,7 +236,6 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read)
     
                     $i++;
                 }
    -
             }
             else
             {
    @@ -309,7 +308,6 @@ if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire)
     
     				$i++;
     			}
    -
     		}
     		else
     		{
    @@ -382,7 +380,6 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire
     
     				$i++;
     			}
    -
     		}
     		else
     		{
    @@ -397,8 +394,6 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire
     
     print '</div></div></div>';
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/imports/class/import.class.php b/htdocs/imports/class/import.class.php
    index f8754193515..a0d33d4c28a 100644
    --- a/htdocs/imports/class/import.class.php
    +++ b/htdocs/imports/class/import.class.php
    @@ -43,8 +43,15 @@ class Import
     	var $array_import_convertvalue;
     	var $array_import_run_sql_after;
     
    -	var $error;
    -	var $errors;
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
     
     	/**
    @@ -58,6 +65,7 @@ class Import
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load description int this->array_import_module, this->array_import_fields, ... of an importable dataset
     	 *
    @@ -67,6 +75,7 @@ class Import
     	 */
     	function load_arrays($user,$filter='')
     	{
    +        // phpcs:enable
     		global $langs,$conf;
     
     		dol_syslog(get_class($this)."::load_arrays user=".$user->id." filter=".$filter);
    @@ -176,6 +185,7 @@ class Import
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Build an import example file.
     	 *  Arrays this->array_export_xxx are already loaded for required datatoexport
    @@ -188,6 +198,7 @@ class Import
     	 */
     	function build_example_file($model, $headerlinefields, $contentlinevalues,$datatoimport)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$indice=0;
    @@ -349,5 +360,4 @@ class Import
     			return 1;
     		}
     	}
    -
     }
    diff --git a/htdocs/imports/emptyexample.php b/htdocs/imports/emptyexample.php
    index ffb270a6306..f11ad902de6 100644
    --- a/htdocs/imports/emptyexample.php
    +++ b/htdocs/imports/emptyexample.php
    @@ -22,9 +22,15 @@
      */
     
     // This file is a wrapper, so empty header
    -function llxHeader() { print '<html><title>Build an import example file</title><body>'; }
    +function llxHeader()
    +{
    +    print '<html><title>Build an import example file</title><body>';
    +}
     // This file is a wrapper, so empty footer
    -function llxFooter() { print '</body></html>'; }
    +function llxFooter()
    +{
    +    print '</body></html>';
    +}
     
     require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -86,4 +92,3 @@ foreach($fieldstarget as $code=>$label)
     //var_dump($contentlinevalues);
     
     print $objimport->build_example_file($format,$headerlinefields,$contentlinevalues,$datatoimport);
    -
    diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php
    index c57a4207782..54aaa8a60a5 100644
    --- a/htdocs/imports/import.php
    +++ b/htdocs/imports/import.php
    @@ -488,7 +488,6 @@ if ($step == 3 && $datatoimport)
     	if ($action == 'delete')
     	{
     		print $form->formconfirm($_SERVER["PHP_SELF"].'?urlfile='.urlencode(GETPOST('urlfile')).'&step=3'.$param, $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
    -
     	}
     
     	print '<div class="underbanner clearboth"></div>';
    @@ -662,7 +661,6 @@ if ($step == 4 && $datatoimport)
                 header("Location: ".$_SERVER["PHP_SELF"].'?step=3'.$param.'&filetoimport='.urlencode($relativepath));
                 exit;
             }
    -
         }
     
     	if (GETPOST('update')) {
    @@ -906,12 +904,11 @@ if ($step == 4 && $datatoimport)
     	$height=24;
     	$i = 0;
     	$mandatoryfieldshavesource=true;
    -	$var=true;
    +
     	print '<table width="100%" class="nobordernopadding">';
     	foreach($fieldstarget as $code=>$label)
     	{
    -		$var = !$var;
    -		print '<tr '.$bc[$var].' height="'.$height.'">';
    +		print '<tr class="oddeven" height="'.$height.'">';
     
     		$i++;
     		$entity=(! empty($objimport->array_import_entities[0][$code])?$objimport->array_import_entities[0][$code]:$objimport->array_import_icon[0]);
    @@ -1163,7 +1160,6 @@ if ($step == 4 && $datatoimport)
     		print '</table>';
     		print '</form>';
     	}
    -
     }
     
     
    @@ -1610,7 +1606,6 @@ if ($step == 5 && $datatoimport)
                 print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunImportFile").'</a>';
             }
             print '</div>';
    -
         }
     
         print '</form>';
    @@ -1915,9 +1910,8 @@ if ($step == 6 && $datatoimport)
     
     print '<br>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    diff --git a/htdocs/imports/index.php b/htdocs/imports/index.php
    index cd67a90e4dd..b1852a3de4f 100644
    --- a/htdocs/imports/index.php
    +++ b/htdocs/imports/index.php
    @@ -134,7 +134,6 @@ print '</table>';
     
     //print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/includes/jquery/plugins/multiselect/MIT-LICENSE.txt b/htdocs/includes/jquery/plugins/multiselect/MIT-LICENSE.txt
    deleted file mode 100755
    index 1076f8b4b2b..00000000000
    --- a/htdocs/includes/jquery/plugins/multiselect/MIT-LICENSE.txt
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -Copyright (c) 2009 Michael Aufreiter, http://www.quasipartikel.at
    -
    -Permission is hereby granted, free of charge, to any person obtaining
    -a copy of this software and associated documentation files (the
    -"Software"), to deal in the Software without restriction, including
    -without limitation the rights to use, copy, modify, merge, publish,
    -distribute, sublicense, and/or sell copies of the Software, and to
    -permit persons to whom the Software is furnished to do so, subject to
    -the following conditions:
    -
    -The above copyright notice and this permission notice shall be
    -included in all copies or substantial portions of the Software.
    -
    -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    \ No newline at end of file
    diff --git a/htdocs/includes/jquery/plugins/multiselect/css/ui.multiselect.css b/htdocs/includes/jquery/plugins/multiselect/css/ui.multiselect.css
    deleted file mode 100755
    index 2072baa57c4..00000000000
    --- a/htdocs/includes/jquery/plugins/multiselect/css/ui.multiselect.css
    +++ /dev/null
    @@ -1,144 +0,0 @@
    -/* Multiselect
    -----------------------------------*/
    -.multiselect {
    -	width: 600px;
    -	height: 150px;
    -}
    -
    -.ui-multiselect {
    -	border: solid 1px;
    -	font-size: 0.8em;
    -}
    -
    -.ui-multiselect ul {
    -	-moz-user-select: none;
    -}
    -
    -.ui-multiselect li {
    -	margin: 0;
    -	padding: 0;
    -	cursor: default;
    -	line-height: 20px;
    -	height: 20px;
    -	font-size: 11px;
    -	list-style: none;
    -}
    -
    -.ui-multiselect li a {
    -	color: #999;
    -	text-decoration: none;
    -	padding: 0;
    -	display: block;
    -	float: left;
    -	cursor: pointer;
    -}
    -
    -.ui-multiselect li.ui-draggable-dragging {
    -	padding-left: 10px;
    -}
    -
    -.ui-multiselect div.selected {
    -	position: relative;
    -	padding: 0;
    -	margin: 0;
    -	border: 0;
    -	float: left;
    -}
    -
    -.ui-multiselect ul.selected {
    -	position: relative;
    -	padding: 0;
    -	overflow: auto;
    -	overflow-x: hidden;
    -	background: #fff;
    -	margin: 0;
    -	list-style: none;
    -	border: 0;
    -	position: relative;
    -	width: 100%;
    -}
    -
    -.ui-multiselect ul.selected li {
    -	
    -}
    -
    -.ui-multiselect div.available {
    -	position: relative;
    -	padding: 0;
    -	margin: 0;
    -	border: 0;
    -	float: left;
    -	border-left: 1px solid;
    -}
    -
    -.ui-multiselect ul.available {
    -	position: relative;
    -	padding: 0;
    -	overflow: auto;
    -	overflow-x: hidden;
    -	background: #fff;
    -	margin: 0;
    -	list-style: none;
    -	border: 0;
    -	width: 100%;
    -}
    -
    -.ui-multiselect ul.available li {
    -	padding-left: 10px;
    -}
    -
    -.ui-multiselect .ui-state-default {
    -	border: none;
    -	margin-bottom: 1px;
    -	position: relative;
    -	padding-left: 20px;
    -}
    -
    -.ui-multiselect .ui-state-hover {
    -	border: none;
    -}
    -
    -.ui-multiselect .ui-widget-header {
    -	border: none;
    -	font-size: 11px;
    -	margin-bottom: 1px;
    -}
    -
    -.ui-multiselect .add-all {
    -	float: right;
    -	padding: 7px;
    -}
    -
    -.ui-multiselect .remove-all {
    -	float: right;
    -	padding: 7px;
    -}
    -
    -.ui-multiselect .search {
    -	float: left;
    -	padding: 4px;
    -}
    -
    -.ui-multiselect .count {
    -	float: left;
    -	padding: 7px;
    -}
    -
    -.ui-multiselect li span.ui-icon-arrowthick-2-n-s {
    -	position: absolute;
    -	left: 2px;
    -}
    -
    -.ui-multiselect li a.action {
    -	position: absolute;
    -	right: 2px;
    -	top: 2px;
    -}
    -
    -.ui-multiselect input.search {
    -	height: 14px;
    -	padding: 1px;
    -	opacity: 0.5;
    -	margin: 4px;
    -	width: 100px;
    -}
    \ No newline at end of file
    diff --git a/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js b/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js
    new file mode 100644
    index 00000000000..ee62d1f588d
    --- /dev/null
    +++ b/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.js
    @@ -0,0 +1,360 @@
    +// jquery.multi-select.js
    +// by mySociety
    +// https://github.com/mysociety/jquery-multi-select
    +
    +;(function($) {
    +
    +  "use strict";
    +
    +  var pluginName = "multiSelect",
    +    defaults = {
    +      'containerHTML': '<div class="multi-select-container">',
    +      'menuHTML': '<div class="multi-select-menu">',
    +      'buttonHTML': '<span class="multi-select-button">',
    +      'menuItemsHTML': '<div class="multi-select-menuitems">',
    +      'menuItemHTML': '<label class="multi-select-menuitem">',
    +      'presetsHTML': '<div class="multi-select-presets">',
    +      'activeClass': 'multi-select-container--open',
    +      'noneText': '-- Select --',
    +      'allText': undefined,
    +      'presets': undefined,
    +      'positionedMenuClass': 'multi-select-container--positioned',
    +      'positionMenuWithin': undefined,
    +      'viewportBottomGutter': 20,
    +      'menuMinHeight': 200
    +    };
    +
    +  /**
    +   * @constructor
    +   */
    +  function MultiSelect(element, options) {
    +    this.element = element;
    +    this.$element = $(element);
    +    this.settings = $.extend( {}, defaults, options );
    +    this._defaults = defaults;
    +    this._name = pluginName;
    +    this.init();
    +  }
    +
    +  function arraysAreEqual(array1, array2) {
    +    if ( array1.length != array2.length ){
    +      return false;
    +    }
    +
    +    array1.sort();
    +    array2.sort();
    +
    +    for ( var i = 0; i < array1.length; i++ ){
    +      if ( array1[i] !== array2[i] ){
    +        return false;
    +      }
    +    }
    +
    +    return true;
    +  }
    +
    +  $.extend(MultiSelect.prototype, {
    +
    +    init: function() {
    +      this.checkSuitableInput();
    +      this.findLabels();
    +      this.constructContainer();
    +      this.constructButton();
    +      this.constructMenu();
    +
    +      this.setUpBodyClickListener();
    +      this.setUpLabelsClickListener();
    +
    +      this.$element.hide();
    +    },
    +
    +    checkSuitableInput: function(text) {
    +      if ( this.$element.is('select[multiple]') === false ) {
    +        throw new Error('$.multiSelect only works on <select multiple> elements');
    +      }
    +    },
    +
    +    findLabels: function() {
    +      this.$labels = $('label[for="' + this.$element.attr('id') + '"]');
    +    },
    +
    +    constructContainer: function() {
    +      this.$container = $(this.settings['containerHTML']);
    +      this.$element.data('multi-select-container', this.$container);
    +      this.$container.insertAfter(this.$element);
    +    },
    +
    +    constructButton: function() {
    +      var _this = this;
    +      this.$button = $(this.settings['buttonHTML']);
    +      this.$button.attr({
    +        'role': 'button',
    +        'aria-haspopup': 'true',
    +        'tabindex': 0,
    +        'aria-label': this.$labels.eq(0).text()
    +      })
    +      .on('keydown.multiselect', function(e) {
    +        var key = e.which;
    +        var returnKey = 13;
    +        var spaceKey = 32;
    +        if ((key === returnKey) || (key === spaceKey)) {
    +          _this.$button.click();
    +        }
    +      }).on('click.multiselect', function(e) {
    +        _this.menuToggle();
    +      })
    +      .appendTo(this.$container);
    +
    +      this.$element.on('change.multiselect', function() {
    +        _this.updateButtonContents();
    +      });
    +
    +      this.updateButtonContents();
    +    },
    +
    +    updateButtonContents: function() {
    +      var _this = this;
    +      var options = [];
    +      var selected = [];
    +
    +      this.$element.children('option').each(function() {
    +        var text = /** @type string */ ($(this).text());
    +        options.push(text);
    +        if ($(this).is(':selected')) {
    +          selected.push( $.trim(text) );
    +        }
    +      });
    +
    +      this.$button.empty();
    +
    +      if (selected.length == 0) {
    +        this.$button.text( this.settings['noneText'] );
    +      } else if ( (selected.length === options.length) && this.settings['allText']) {
    +        this.$button.text( this.settings['allText'] );
    +      } else {
    +        this.$button.text( selected.join(', ') );
    +      }
    +    },
    +
    +    constructMenu: function() {
    +      var _this = this;
    +
    +      this.$menu = $(this.settings['menuHTML']);
    +      this.$menu.attr({
    +        'role': 'menu'
    +      }).on('keyup.multiselect', function(e){
    +        var key = e.which;
    +        var escapeKey = 27;
    +        if (key === escapeKey) {
    +          _this.menuHide();
    +        }
    +      })
    +      .appendTo(this.$container);
    +
    +      this.constructMenuItems();
    +
    +      if ( this.settings['presets'] ) {
    +        this.constructPresets();
    +      }
    +    },
    +
    +    constructMenuItems: function() {
    +      var _this = this;
    +
    +      this.$menuItems = $(this.settings['menuItemsHTML']);
    +      this.$menu.append(this.$menuItems);
    +
    +      this.$element.on('change.multiselect', function(e, internal) {
    +        // Don't need to update the menu items if this
    +        // change event was fired by our tickbox handler.
    +        if(internal !== true){
    +          _this.updateMenuItems();
    +        }
    +      });
    +
    +      this.updateMenuItems();
    +    },
    +
    +    updateMenuItems: function() {
    +      var _this = this;
    +      this.$menuItems.empty();
    +
    +      this.$element.children('option').each(function(option_index, option) {
    +        var $item = _this.constructMenuItem($(option), option_index);
    +        _this.$menuItems.append($item);
    +      });
    +    },
    +
    +    constructPresets: function() {
    +      var _this = this;
    +      this.$presets = $(this.settings['presetsHTML']);
    +      this.$menu.prepend(this.$presets);
    +
    +      $.each(this.settings['presets'], function(i, preset){
    +        var unique_id = _this.$element.attr('name') + '_preset_' + i;
    +        var $item = $(_this.settings['menuItemHTML'])
    +          .attr({
    +            'for': unique_id,
    +            'role': 'menuitem'
    +          })
    +          .text(' ' + preset.name)
    +          .appendTo(_this.$presets);
    +
    +        var $input = $('<input>')
    +          .attr({
    +            'type': 'radio',
    +            'name': _this.$element.attr('name') + '_presets',
    +            'id': unique_id
    +          })
    +          .prependTo($item);
    +
    +        $input.on('change.multiselect', function(){
    +          _this.$element.val(preset.options);
    +          _this.$element.trigger('change');
    +        });
    +      });
    +
    +      this.$element.on('change.multiselect', function() {
    +        _this.updatePresets();
    +      });
    +
    +      this.updatePresets();
    +    },
    +
    +    updatePresets: function() {
    +      var _this = this;
    +
    +      $.each(this.settings['presets'], function(i, preset){
    +        var unique_id = _this.$element.attr('name') + '_preset_' + i;
    +        var $input = _this.$presets.find('#' + unique_id);
    +
    +        if ( arraysAreEqual(preset.options || [], _this.$element.val() || []) ){
    +          $input.prop('checked', true);
    +        } else {
    +          $input.prop('checked', false);
    +        }
    +      });
    +    },
    +
    +    constructMenuItem: function($option, option_index) {
    +      var unique_id = this.$element.attr('name') + '_' + option_index;
    +      var $item = $(this.settings['menuItemHTML'])
    +        .attr({
    +          'for': unique_id,
    +          'role': 'menuitem'
    +        })
    +        .text(' ' + $option.text());
    +
    +      var $input = $('<input>')
    +        .attr({
    +          'type': 'checkbox',
    +          'id': unique_id,
    +          'value': $option.val()
    +        })
    +        .prependTo($item);
    +
    +      if ( $option.is(':disabled') ) {
    +        $input.attr('disabled', 'disabled');
    +      }
    +      if ( $option.is(':selected') ) {
    +        $input.prop('checked', 'checked');
    +      }
    +
    +      $input.on('change.multiselect', function() {
    +        if ($(this).prop('checked')) {
    +          $option.prop('selected', true);
    +        } else {
    +          $option.prop('selected', false);
    +        }
    +
    +        // .prop() on its own doesn't generate a change event.
    +        // Other plugins might want to do stuff onChange.
    +        $option.trigger('change', [true]);
    +      });
    +
    +      return $item;
    +    },
    +
    +    setUpBodyClickListener: function() {
    +      var _this = this;
    +
    +      // Hide the $menu when you click outside of it.
    +      $('html').on('click.multiselect', function(){
    +        _this.menuHide();
    +      });
    +
    +      // Stop click events from inside the $button or $menu from
    +      // bubbling up to the body and closing the menu!
    +      this.$container.on('click.multiselect', function(e){
    +        e.stopPropagation();
    +      });
    +    },
    +
    +    setUpLabelsClickListener: function() {
    +      var _this = this;
    +      this.$labels.on('click.multiselect', function(e) {
    +        e.preventDefault();
    +        e.stopPropagation();
    +        _this.menuToggle();
    +      });
    +    },
    +
    +    menuShow: function() {
    +      $('html').trigger('click.multiselect'); // Close any other open menus
    +      this.$container.addClass(this.settings['activeClass']);
    +
    +      if ( this.settings['positionMenuWithin'] && this.settings['positionMenuWithin'] instanceof $ ) {
    +        var menuLeftEdge = this.$menu.offset().left + this.$menu.outerWidth();
    +        var withinLeftEdge = this.settings['positionMenuWithin'].offset().left +
    +          this.settings['positionMenuWithin'].outerWidth();
    +
    +        if ( menuLeftEdge > withinLeftEdge ) {
    +          this.$menu.css( 'width', (withinLeftEdge - this.$menu.offset().left) );
    +          this.$container.addClass(this.settings['positionedMenuClass']);
    +        }
    +      }
    +
    +      var menuBottom = this.$menu.offset().top + this.$menu.outerHeight();
    +      var viewportBottom = $(window).scrollTop() + $(window).height();
    +      if ( menuBottom > viewportBottom - this.settings['viewportBottomGutter'] ) {
    +        this.$menu.css({
    +          'maxHeight': Math.max(
    +            viewportBottom - this.settings['viewportBottomGutter'] - this.$menu.offset().top,
    +            this.settings['menuMinHeight']
    +          ),
    +          'overflow': 'scroll'
    +        });
    +      } else {
    +        this.$menu.css({
    +          'maxHeight': '',
    +          'overflow': ''
    +        });
    +      }
    +    },
    +
    +    menuHide: function() {
    +      this.$container.removeClass(this.settings['activeClass']);
    +      this.$container.removeClass(this.settings['positionedMenuClass']);
    +      this.$menu.css('width', 'auto');
    +    },
    +
    +    menuToggle: function() {
    +      if ( this.$container.hasClass(this.settings['activeClass']) ) {
    +        this.menuHide();
    +      } else {
    +        this.menuShow();
    +      }
    +    }
    +
    +  });
    +
    +  $.fn[ pluginName ] = function(options) {
    +    return this.each(function() {
    +      if ( !$.data(this, "plugin_" + pluginName) ) {
    +        $.data(this, "plugin_" + pluginName,
    +          new MultiSelect(this, options) );
    +      }
    +    });
    +  };
    +
    +})(jQuery);
    diff --git a/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.min.js b/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.min.js
    new file mode 100644
    index 00000000000..015aee2264b
    --- /dev/null
    +++ b/htdocs/includes/jquery/plugins/multiselect/jquery.multi-select.min.js
    @@ -0,0 +1,9 @@
    +(function(c){function f(b,a){this.b=c(b);this.a=c.extend({},g,a);this.H()}var g={containerHTML:'<div class="multi-select-container">',menuHTML:'<div class="multi-select-menu">',buttonHTML:'<span class="multi-select-button">',menuItemsHTML:'<div class="multi-select-menuitems">',menuItemHTML:'<label class="multi-select-menuitem">',presetsHTML:'<div class="multi-select-presets">',activeClass:"multi-select-container--open",noneText:"-- Select --",allText:void 0,presets:void 0,positionedMenuClass:"multi-select-container--positioned",
    +positionMenuWithin:void 0,viewportBottomGutter:20,menuMinHeight:200};c.extend(f.prototype,{H:function(){this.v();this.G();this.A();this.w();this.B();this.J();this.K();this.b.hide()},v:function(){if(!1===this.b.is("select[multiple]"))throw Error("$.multiSelect only works on <select multiple> elements");},G:function(){this.l=c('label[for="'+this.b.attr("id")+'"]')},A:function(){this.f=c(this.a.containerHTML);this.b.data("multi-select-container",this.f);this.f.insertAfter(this.b)},w:function(){var b=
    +this;this.g=c(this.a.buttonHTML);this.g.attr({role:"button","aria-haspopup":"true",tabindex:0,"aria-label":this.l.eq(0).text()}).on("keydown.multiselect",function(a){a=a.which;13!==a&&32!==a||b.g.click()}).on("click.multiselect",function(){b.m()}).appendTo(this.f);this.b.on("change.multiselect",function(){b.o()});this.o()},o:function(){var b=[],a=[];this.b.children("option").each(function(){var d=c(this).text();b.push(d);c(this).is(":selected")&&a.push(c.trim(d))});this.g.empty();0==a.length?this.g.text(this.a.noneText):
    +a.length===b.length&&this.a.allText?this.g.text(this.a.allText):this.g.text(a.join(", "))},B:function(){var b=this;this.c=c(this.a.menuHTML);this.c.attr({role:"menu"}).on("keyup.multiselect",function(a){27===a.which&&b.j()}).appendTo(this.f);this.D();this.a.presets&&this.F()},D:function(){var b=this;this.h=c(this.a.menuItemsHTML);this.c.append(this.h);this.b.on("change.multiselect",function(a,c){!0!==c&&b.s()});this.s()},s:function(){var b=this;this.h.empty();this.b.children("option").each(function(a,
    +d){a=b.C(c(d),a);b.h.append(a)})},F:function(){var b=this;this.i=c(this.a.presetsHTML);this.c.prepend(this.i);c.each(this.a.presets,function(a,d){a=b.b.attr("name")+"_preset_"+a;var h=c(b.a.menuItemHTML).attr({"for":a,role:"menuitem"}).text(" "+d.name).appendTo(b.i);c("<input>").attr({type:"radio",name:b.b.attr("name")+"_presets",id:a}).prependTo(h).on("change.multiselect",function(){b.b.val(d.options);b.b.trigger("change")})});this.b.on("change.multiselect",function(){b.u()});this.u()},u:function(){var b=
    +this;c.each(this.a.presets,function(a,c){a=b.b.attr("name")+"_preset_"+a;a=b.i.find("#"+a);a:{c=c.options||[];var d=b.b.val()||[];if(c.length!=d.length)c=!1;else{c.sort();d.sort();for(var e=0;e<c.length;e++)if(c[e]!==d[e]){c=!1;break a}c=!0}}c?a.prop("checked",!0):a.prop("checked",!1)})},C:function(b,a){var d=this.b.attr("name")+"_"+a;a=c(this.a.menuItemHTML).attr({"for":d,role:"menuitem"}).text(" "+b.text());d=c("<input>").attr({type:"checkbox",id:d,value:b.val()}).prependTo(a);b.is(":disabled")&&
    +d.attr("disabled","disabled");b.is(":selected")&&d.prop("checked","checked");d.on("change.multiselect",function(){c(this).prop("checked")?b.prop("selected",!0):b.prop("selected",!1);b.trigger("change",[!0])});return a},J:function(){var b=this;c("html").on("click.multiselect",function(){b.j()});this.f.on("click.multiselect",function(a){a.stopPropagation()})},K:function(){var b=this;this.l.on("click.multiselect",function(a){a.preventDefault();a.stopPropagation();b.m()})},I:function(){c("html").trigger("click.multiselect");
    +this.f.addClass(this.a.activeClass);if(this.a.positionMenuWithin&&this.a.positionMenuWithin instanceof c){var b=this.c.offset().left+this.c.outerWidth(),a=this.a.positionMenuWithin.offset().left+this.a.positionMenuWithin.outerWidth();b>a&&(this.c.css("width",a-this.c.offset().left),this.f.addClass(this.a.positionedMenuClass))}b=this.c.offset().top+this.c.outerHeight();a=c(window).scrollTop()+c(window).height();b>a-this.a.viewportBottomGutter?this.c.css({maxHeight:Math.max(a-this.a.viewportBottomGutter-
    +this.c.offset().top,this.a.menuMinHeight),overflow:"scroll"}):this.c.css({maxHeight:"",overflow:""})},j:function(){this.f.removeClass(this.a.activeClass);this.f.removeClass(this.a.positionedMenuClass);this.c.css("width","auto")},m:function(){this.f.hasClass(this.a.activeClass)?this.j():this.I()}});c.fn.multiSelect=function(b){return this.each(function(){c.data(this,"plugin_multiSelect")||c.data(this,"plugin_multiSelect",new f(this,b))})}})(jQuery);
    diff --git a/htdocs/includes/jquery/plugins/multiselect/js/ui.multiselect.js b/htdocs/includes/jquery/plugins/multiselect/js/ui.multiselect.js
    deleted file mode 100755
    index 1234fa7a957..00000000000
    --- a/htdocs/includes/jquery/plugins/multiselect/js/ui.multiselect.js
    +++ /dev/null
    @@ -1,336 +0,0 @@
    -/*
    - * jQuery UI Multiselect
    - *
    - * Authors:
    - *  Michael Aufreiter (quasipartikel.at)
    - *  Yanick Rochon (yanick.rochon[at]gmail[dot]com)
    - * 
    - * Dual licensed under the MIT (MIT-LICENSE.txt)
    - * and GPL (GPL-LICENSE.txt) licenses.
    - * 
    - * http://www.quasipartikel.at/multiselect/
    - *
    - * 
    - * Depends:
    - *	ui.core.js
    - *	ui.sortable.js
    - *
    - * Optional:
    - * localization (http://plugins.jquery.com/project/localisation)
    - * scrollTo (http://plugins.jquery.com/project/ScrollTo)
    - * 
    - * Todo:
    - *  Make batch actions faster
    - *  Implement dynamic insertion through remote calls
    - */
    -
    -
    -(function($) {
    -
    -$.widget("ui.multiselect", {
    -  options: {
    -		sortable: true,
    -		searchable: true,
    -		doubleClickable: true,
    -		animated: 'fast',
    -		show: 'slideDown',
    -		hide: 'slideUp',
    -		dividerLocation: 0.6,
    -		nodeComparator: function(node1,node2) {
    -			var text1 = node1.text(),
    -			    text2 = node2.text();
    -			return text1 == text2 ? 0 : (text1 < text2 ? -1 : 1);
    -		}
    -	},
    -	_create: function() {
    -		this.element.hide();
    -		this.id = this.element.attr("id");
    -		this.container = $('<div class="ui-multiselect ui-helper-clearfix ui-widget"></div>').insertAfter(this.element);
    -		this.count = 0; // number of currently selected options
    -		this.selectedContainer = $('<div class="selected"></div>').appendTo(this.container);
    -		this.availableContainer = $('<div class="available"></div>').appendTo(this.container);
    -		this.selectedActions = $('<div class="actions ui-widget-header ui-helper-clearfix"><span class="count">0 '+$.ui.multiselect.locale.itemsCount+'</span><a href="#" class="remove-all">'+$.ui.multiselect.locale.removeAll+'</a></div>').appendTo(this.selectedContainer);
    -		this.availableActions = $('<div class="actions ui-widget-header ui-helper-clearfix"><input type="text" class="search empty ui-widget-content ui-corner-all"/><a href="#" class="add-all">'+$.ui.multiselect.locale.addAll+'</a></div>').appendTo(this.availableContainer);
    -		this.selectedList = $('<ul class="selected connected-list"><li class="ui-helper-hidden-accessible"></li></ul>').bind('selectstart', function(){return false;}).appendTo(this.selectedContainer);
    -		this.availableList = $('<ul class="available connected-list"><li class="ui-helper-hidden-accessible"></li></ul>').bind('selectstart', function(){return false;}).appendTo(this.availableContainer);
    -		
    -		var that = this;
    -
    -		// set dimensions
    -		this.container.width(this.element.width()+1);
    -		this.selectedContainer.width(Math.floor(this.element.width()*this.options.dividerLocation));
    -		this.availableContainer.width(Math.floor(this.element.width()*(1-this.options.dividerLocation)));
    -
    -		// fix list height to match <option> depending on their individual header's heights
    -		this.selectedList.height(Math.max(this.element.height()-this.selectedActions.height(),1));
    -		this.availableList.height(Math.max(this.element.height()-this.availableActions.height(),1));
    -		
    -		if ( !this.options.animated ) {
    -			this.options.show = 'show';
    -			this.options.hide = 'hide';
    -		}
    -		
    -		// init lists
    -		this._populateLists(this.element.find('option'));
    -		
    -		// make selection sortable
    -		if (this.options.sortable) {
    -			this.selectedList.sortable({
    -				placeholder: 'ui-state-highlight',
    -				axis: 'y',
    -				update: function(event, ui) {
    -					// apply the new sort order to the original selectbox
    -					that.selectedList.find('li').each(function() {
    -						if ($(this).data('optionLink'))
    -							$(this).data('optionLink').remove().appendTo(that.element);
    -					});
    -				},
    -				receive: function(event, ui) {
    -					ui.item.data('optionLink').attr('selected', true);
    -					// increment count
    -					that.count += 1;
    -					that._updateCount();
    -					// workaround, because there's no way to reference 
    -					// the new element, see http://dev.jqueryui.com/ticket/4303
    -					that.selectedList.children('.ui-draggable').each(function() {
    -						$(this).removeClass('ui-draggable');
    -						$(this).data('optionLink', ui.item.data('optionLink'));
    -						$(this).data('idx', ui.item.data('idx'));
    -						that._applyItemState($(this), true);
    -					});
    -			
    -					// workaround according to http://dev.jqueryui.com/ticket/4088
    -					setTimeout(function() { ui.item.remove(); }, 1);
    -				}
    -			});
    -		}
    -		
    -		// set up livesearch
    -		if (this.options.searchable) {
    -			this._registerSearchEvents(this.availableContainer.find('input.search'));
    -		} else {
    -			$('.search').hide();
    -		}
    -		
    -		// batch actions
    -		this.container.find(".remove-all").click(function() {
    -			that._populateLists(that.element.find('option').removeAttr('selected'));
    -			return false;
    -		});
    -		
    -		this.container.find(".add-all").click(function() {
    -			var options = that.element.find('option').not(":selected");
    -			if (that.availableList.children('li:hidden').length > 1) {
    -				that.availableList.children('li').each(function(i) {
    -					if ($(this).is(":visible")) $(options[i-1]).attr('selected', 'selected'); 
    -				});
    -			} else {
    -				options.attr('selected', 'selected');
    -			}
    -			that._populateLists(that.element.find('option'));
    -			return false;
    -		});
    -	},
    -	destroy: function() {
    -		this.element.show();
    -		this.container.remove();
    -
    -		$.Widget.prototype.destroy.apply(this, arguments);
    -	},
    -	_populateLists: function(options) {
    -		this.selectedList.children('.ui-element').remove();
    -		this.availableList.children('.ui-element').remove();
    -		this.count = 0;
    -
    -		var that = this;
    -		var items = $(options.map(function(i) {
    -	      var item = that._getOptionNode(this).appendTo(this.selected ? that.selectedList : that.availableList).show();
    -
    -			if (this.selected) that.count += 1;
    -			that._applyItemState(item, this.selected);
    -			item.data('idx', i);
    -			return item[0];
    -    }));
    -		
    -		// update count
    -		this._updateCount();
    -		that._filter.apply(this.availableContainer.find('input.search'), [that.availableList]);
    -  },
    -	_updateCount: function() {
    -		this.selectedContainer.find('span.count').text(this.count+" "+$.ui.multiselect.locale.itemsCount);
    -	},
    -	_getOptionNode: function(option) {
    -		option = $(option);
    -		var node = $('<li class="ui-state-default ui-element" title="'+option.text()+'"><span class="ui-icon"/>'+option.text()+'<a href="#" class="action"><span class="ui-corner-all ui-icon"/></a></li>').hide();
    -		node.data('optionLink', option);
    -		return node;
    -	},
    -	// clones an item with associated data
    -	// didn't find a smarter away around this
    -	_cloneWithData: function(clonee) {
    -		var clone = clonee.clone(false,false);
    -		clone.data('optionLink', clonee.data('optionLink'));
    -		clone.data('idx', clonee.data('idx'));
    -		return clone;
    -	},
    -	_setSelected: function(item, selected) {
    -		item.data('optionLink').attr('selected', selected);
    -
    -		if (selected) {
    -			var selectedItem = this._cloneWithData(item);
    -			item[this.options.hide](this.options.animated, function() { $(this).remove(); });
    -			selectedItem.appendTo(this.selectedList).hide()[this.options.show](this.options.animated);
    -			
    -			this._applyItemState(selectedItem, true);
    -			return selectedItem;
    -		} else {
    -			
    -			// look for successor based on initial option index
    -			var items = this.availableList.find('li'), comparator = this.options.nodeComparator;
    -			var succ = null, i = item.data('idx'), direction = comparator(item, $(items[i]));
    -
    -			// TODO: test needed for dynamic list populating
    -			if ( direction ) {
    -				while (i>=0 && i<items.length) {
    -					direction > 0 ? i++ : i--;
    -					if ( direction != comparator(item, $(items[i])) ) {
    -						// going up, go back one item down, otherwise leave as is
    -						succ = items[direction > 0 ? i : i+1];
    -						break;
    -					}
    -				}
    -			} else {
    -				succ = items[i];
    -			}
    -			
    -			var availableItem = this._cloneWithData(item);
    -			succ ? availableItem.insertBefore($(succ)) : availableItem.appendTo(this.availableList);
    -			item[this.options.hide](this.options.animated, function() { $(this).remove(); });
    -			availableItem.hide()[this.options.show](this.options.animated);
    -			
    -			this._applyItemState(availableItem, false);
    -			return availableItem;
    -		}
    -	},
    -	_applyItemState: function(item, selected) {
    -		if (selected) {
    -			if (this.options.sortable)
    -				item.children('span').addClass('ui-icon-arrowthick-2-n-s').removeClass('ui-helper-hidden').addClass('ui-icon');
    -			else
    -				item.children('span').removeClass('ui-icon-arrowthick-2-n-s').addClass('ui-helper-hidden').removeClass('ui-icon');
    -			item.find('a.action span').addClass('ui-icon-minus').removeClass('ui-icon-plus');
    -			this._registerRemoveEvents(item.find('a.action'));
    -			
    -		} else {
    -			item.children('span').removeClass('ui-icon-arrowthick-2-n-s').addClass('ui-helper-hidden').removeClass('ui-icon');
    -			item.find('a.action span').addClass('ui-icon-plus').removeClass('ui-icon-minus');
    -			this._registerAddEvents(item.find('a.action'));
    -		}
    -		
    -		this._registerDoubleClickEvents(item);
    -		this._registerHoverEvents(item);
    -	},
    -	// taken from John Resig's liveUpdate script
    -	_filter: function(list) {
    -		var input = $(this);
    -		var rows = list.children('li'),
    -			cache = rows.map(function(){
    -				
    -				return $(this).text().toLowerCase();
    -			});
    -		
    -		var term = $.trim(input.val().toLowerCase()), scores = [];
    -		
    -		if (!term) {
    -			rows.show();
    -		} else {
    -			rows.hide();
    -
    -			cache.each(function(i) {
    -				if (this.indexOf(term)>-1) { scores.push(i); }
    -			});
    -
    -			$.each(scores, function() {
    -				$(rows[this]).show();
    -			});
    -		}
    -	},
    -	_registerDoubleClickEvents: function(elements) {
    -		if (!this.options.doubleClickable) return;
    -		elements.dblclick(function() {
    -			elements.find('a.action').click();
    -		});
    -	},
    -	_registerHoverEvents: function(elements) {
    -		elements.removeClass('ui-state-hover');
    -		elements.mouseover(function() {
    -			$(this).addClass('ui-state-hover');
    -		});
    -		elements.mouseout(function() {
    -			$(this).removeClass('ui-state-hover');
    -		});
    -	},
    -	_registerAddEvents: function(elements) {
    -		var that = this;
    -		elements.click(function() {
    -			var item = that._setSelected($(this).parent(), true);
    -			that.count += 1;
    -			that._updateCount();
    -			return false;
    -		});
    -		
    -		// make draggable
    -		if (this.options.sortable) {
    -  		elements.each(function() {
    -  			$(this).parent().draggable({
    -  	      connectToSortable: that.selectedList,
    -  				helper: function() {
    -  					var selectedItem = that._cloneWithData($(this)).width($(this).width() - 50);
    -  					selectedItem.width($(this).width());
    -  					return selectedItem;
    -  				},
    -  				appendTo: that.container,
    -  				containment: that.container,
    -  				revert: 'invalid'
    -  	    });
    -  		});		  
    -		}
    -	},
    -	_registerRemoveEvents: function(elements) {
    -		var that = this;
    -		elements.click(function() {
    -			that._setSelected($(this).parent(), false);
    -			that.count -= 1;
    -			that._updateCount();
    -			return false;
    -		});
    - 	},
    -	_registerSearchEvents: function(input) {
    -		var that = this;
    -
    -		input.focus(function() {
    -			$(this).addClass('ui-state-active');
    -		})
    -		.blur(function() {
    -			$(this).removeClass('ui-state-active');
    -		})
    -		.keypress(function(e) {
    -			if (e.keyCode == 13)
    -				return false;
    -		})
    -		.keyup(function() {
    -			that._filter.apply(this, [that.availableList]);
    -		});
    -	}
    -});
    -		
    -$.extend($.ui.multiselect, {
    -	locale: {
    -		addAll:'Add all',
    -		removeAll:'Remove all',
    -		itemsCount:'items selected'
    -	}
    -});
    -
    -
    -})(jQuery);
    diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLERead.php b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLERead.php
    index 261bdde5812..444d8ec641f 100644
    --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLERead.php
    +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLERead.php
    @@ -289,7 +289,6 @@ class PHPExcel_Shared_OLERead {
     
     			$offset += self::PROPERTY_STORAGE_BLOCK_SIZE;
     		}
    -
     	}
     
     	/**
    diff --git a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php
    index 4846910fa29..93e85582d5c 100644
    --- a/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php
    +++ b/htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php
    @@ -1042,7 +1042,6 @@ class PHPExcel_Writer_Excel2007_Chart extends
         }
     
         $objWriter->endElement();
    -
       }
     
       /**
    @@ -1322,7 +1321,6 @@ class PHPExcel_Writer_Excel2007_Chart extends
           $objWriter->endElement();
         }
         $objWriter->endElement();
    -
       }
     
       /**
    diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css
    index dc02468fdc0..ea3a4153c15 100644
    --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css
    +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css
    @@ -1231,7 +1231,7 @@
       cursor: pointer;
     }
     .swagger-section #header {
    -  background-color: #646257;
    +  background-color: rgb(163, 188, 210);
       padding: 14px;
     }
     .swagger-section #input_baseUrl {
    @@ -1278,7 +1278,7 @@
       font-size: 1.5em;
       font-weight: bold;
       text-decoration: none;
    -  background: transparent url(../images/logo_small.png) no-repeat left center;
    +  background: transparent url(../../../../theme/eldy/img/favicon.ico) no-repeat left center;
       padding: 20px 0 20px 40px;
       color: white;
     }
    diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html b/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html
    index c73f1981cc9..01fb8ee2a0e 100644
    --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html
    +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html
    @@ -3,7 +3,7 @@
     <html>
     <head>
       <meta charset="UTF-8">
    -  <title>Api Explorer</title>
    +  <title>REST API Explorer</title>
       <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
       <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
       <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
    @@ -73,6 +73,7 @@
             docExpansion: "none",
             jsonEditor: false,
             apisSorter: "alpha",
    +        operationsSorter: "alpha",
             defaultModelRendering: 'schema',
             showRequestHeaders: false
           });
    @@ -126,7 +127,7 @@
     <body class="swagger-section">
     <div id='header'>
       <div class="swagger-ui-wrap">
    -    <a id="logo" href="#">API Explorer</a>
    +    <a id="logo" href="#">Dolibarr REST API Explorer</a>
         <form id='api_selector'>
           <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
           <div class='input'><input placeholder="DOLAPIKEY" id="input_apiKey" name="apiKey" type="text"/></div>
    diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.js
    index fee54e49324..b1c2e3f2767 100644
    --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.js
    +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.js
    @@ -1193,7 +1193,7 @@ var reservedApiTags = [
       'path',
       'tag'
     ];
    -var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put'];
    +var supportedOperationMethods = ['head', 'options', 'get', 'post', 'put', 'patch', 'delete'];
     var SwaggerClient = module.exports = function (url, options) {
       this.authorizations = null;
       this.authorizationScheme = null;
    @@ -26327,4 +26327,4 @@ SwaggerUi.Views.StatusCodeView = Backbone.View.extend({
         }
         return this;
       }
    -});}).call(this);
    \ No newline at end of file
    +});}).call(this);
    diff --git a/htdocs/includes/tcpdi/tcpdi_parser.php b/htdocs/includes/tcpdi/tcpdi_parser.php
    index 038994568ac..cdeaf4f94e6 100644
    --- a/htdocs/includes/tcpdi/tcpdi_parser.php
    +++ b/htdocs/includes/tcpdi/tcpdi_parser.php
    @@ -484,7 +484,7 @@ class tcpdi_parser {
     			$v = $sarr[$key];
     			if (($key == '/Type') AND ($v[0] == PDF_TYPE_TOKEN AND ($v[1] == 'XRef'))) {
     				$valid_crs = true;
    -			} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1] >= 2))) {
    +			} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) {
     				// first object number in the subsection
     				$index_first = intval($v[1][0][1]);
     				// number of entries in the subsection
    diff --git a/htdocs/includes/tecnickcom/tcpdf/tcpdf.php b/htdocs/includes/tecnickcom/tcpdf/tcpdf.php
    index ef411a17dee..3cdfff4f227 100644
    --- a/htdocs/includes/tecnickcom/tcpdf/tcpdf.php
    +++ b/htdocs/includes/tecnickcom/tcpdf/tcpdf.php
    @@ -17783,7 +17783,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
     											// justify block
     											if (!TCPDF_STATIC::empty_string($this->lispacer)) {
     												$this->lispacer = '';
    -												continue;
    +												break;
     											}
     											preg_match('/([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]([0-9\.\+\-]*)[\s]('.$strpiece[1][0].')[\s](re)([\s]*)/x', $pmid, $xmatches);
     											if (!isset($xmatches[1])) {
    diff --git a/htdocs/index.php b/htdocs/index.php
    index 9ca5585d0ca..14f72774d92 100644
    --- a/htdocs/index.php
    +++ b/htdocs/index.php
    @@ -358,7 +358,7 @@ print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     /*
      * Dolibarr Working Board with weather
      */
    -$showweather=empty($conf->global->MAIN_DISABLE_METEO)?1:0;
    +$showweather=(empty($conf->global->MAIN_DISABLE_METEO) || $conf->global->MAIN_DISABLE_METEO == 2) ? 1 : 0;
     
     //Array that contains all WorkboardResponse classes to process them
     $dashboardlines=array();
    @@ -536,7 +536,7 @@ $boxwork.='</tr>'."\n";
     if ($showweather)
     {
         $boxwork.='<tr class="nohover">';
    -    $boxwork.='<td class="nohover hideonsmartphone center valignmiddle">';
    +    $boxwork.='<td class="nohover'.($conf->global->MAIN_DISABLE_METEO == 2 ?' hideonsmartphone' : '').' center valignmiddle">';
         $text='';
         if ($totallate > 0) $text=$langs->transnoentitiesnoconv("WarningYouHaveAtLeastOneTaskLate").' ('.$langs->transnoentitiesnoconv("NActionsLate",$totallate.(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? '%' : '')).')';
         else $text=$langs->transnoentitiesnoconv("NoItemLate");
    @@ -565,6 +565,10 @@ if (! empty($valid_dashboardlines))
             $sep=($conf->dol_use_jmobile?'<br>':' ');
             $boxwork .= '<span class="boxstatstext" title="'.dol_escape_htmltag($board->label).'">'.$board->img.' '.$board->label.'</span><br>';
             $boxwork .= '<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0)?' dashboardlineok':'').'">'.$board->nbtodo.'</span></a>';
    +        if ($board->total > 0 && ! empty($conf->global->MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX))
    +	{
    +		$boxwork .= '&nbsp;/&nbsp;<a class="valignmiddle dashboardlineindicator" href="'.$board->url.'"><span class="dashboardlineindicator'.(($board->nbtodo == 0)?' dashboardlineok':'').'">'.price($board->total)	.'</span></a>';
    +	}
             $boxwork .= '</div>';
             if ($board->nbtodolate > 0)
             {
    @@ -675,8 +679,8 @@ if ($user->admin && empty($conf->global->MAIN_REMOVE_INSTALL_WARNING))
     
     //print 'mem='.memory_get_usage().' - '.memory_get_peak_usage();
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    @@ -699,15 +703,27 @@ function showWeather($totallate,$text,$options)
     
         $used_conf = !empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE) ? 'MAIN_METEO_PERCENTAGE_LEVEL' : 'MAIN_METEO_LEVEL';
     
    -    $level0=$offset;           if (! empty($conf->global->{$used_conf.'0'})) $level0=$conf->global->{$used_conf.'0'};
    -    $level1=$offset+1*$factor; if (! empty($conf->global->{$used_conf.'1'})) $level1=$conf->global->{$used_conf.'1'};
    -    $level2=$offset+2*$factor; if (! empty($conf->global->{$used_conf.'2'})) $level2=$conf->global->{$used_conf.'2'};
    -    $level3=$offset+3*$factor; if (! empty($conf->global->{$used_conf.'3'})) $level3=$conf->global->{$used_conf.'3'};
    +    $level0=$offset;
    +    if (! empty($conf->global->{$used_conf.'0'})) {
    +        $level0=$conf->global->{$used_conf.'0'};
    +    }
    +    $level1=$offset+1*$factor;
    +    if (! empty($conf->global->{$used_conf.'1'})) {
    +        $level1=$conf->global->{$used_conf.'1'};
    +    }
    +    $level2=$offset+2*$factor;
    +    if (! empty($conf->global->{$used_conf.'2'})) {
    +        $level2=$conf->global->{$used_conf.'2'};
    +    }
    +    $level3=$offset+3*$factor;
    +    if (! empty($conf->global->{$used_conf.'3'})) {
    +        $level3=$conf->global->{$used_conf.'3'};
    +    }
     
         if ($totallate <= $level0) $out.=img_weather($text,'weather-clear.png',$options);
    -    if ($totallate > $level0 && $totallate <= $level1) $out.=img_weather($text,'weather-few-clouds.png',$options);
    -    if ($totallate > $level1 && $totallate <= $level2) $out.=img_weather($text,'weather-clouds.png',$options);
    -    if ($totallate > $level2 && $totallate <= $level3) $out.=img_weather($text,'weather-many-clouds.png',$options);
    -    if ($totallate > $level3) $out.=img_weather($text,'weather-storm.png',$options);
    +    elseif ($totallate > $level0 && $totallate <= $level1) $out.=img_weather($text,'weather-few-clouds.png',$options);
    +    elseif ($totallate > $level1 && $totallate <= $level2) $out.=img_weather($text,'weather-clouds.png',$options);
    +    elseif ($totallate > $level2 && $totallate <= $level3) $out.=img_weather($text,'weather-many-clouds.png',$options);
    +    elseif ($totallate > $level3) $out.=img_weather($text,'weather-storm.png',$options);
         return $out;
     }
    diff --git a/htdocs/install/check.php b/htdocs/install/check.php
    index 10ff1b603bb..c2eb06bffb7 100644
    --- a/htdocs/install/check.php
    +++ b/htdocs/install/check.php
    @@ -40,7 +40,7 @@ $langs->setDefaultLang($setuplang);
     
     $langs->load("install");
     
    -// Now we load forced value from install.forced.php file.
    +// Now we load forced/pre-set values from install.forced.php file.
     $useforcedwizard=false;
     $forcedfile="./install.forced.php";
     if ($conffile == "/etc/dolibarr/conf.php") $forcedfile="/etc/dolibarr/install.forced.php";
    @@ -49,14 +49,14 @@ if (@file_exists($forcedfile)) {
     	include_once $forcedfile;
     }
     
    -dolibarr_install_syslog("--- check: Dolibarr install/upgrade process started");
    +dolibarr_install_syslog("- check: Dolibarr install/upgrade process started");
     
     
     /*
      *	View
      */
     
    -pHeader('','');     // No next step for navigation buttons. Next step is defined by clik on links.
    +pHeader('','');     // No next step for navigation buttons. Next step is defined by click on links.
     
     
     //print "<br>\n";
    @@ -233,13 +233,13 @@ else
     		else dolibarr_install_syslog("check: failed to create a new file " . $conffile . " into current dir " . getcwd() . ". Please check permissions.", LOG_ERR);
     	}
     
    -	// First install, we can't upgrade
    +	// First install: no upgrade necessary/required
     	$allowupgrade=false;
     }
     
     
     
    -// File is missng and can't be created
    +// File is missing and cannot be created
     if (! file_exists($conffile))
     {
     	print '<img src="../theme/eldy/img/error.png" alt="Error"> '.$langs->trans("ConfFileDoesNotExistsAndCouldNotBeCreated",$conffiletoshow);
    @@ -258,7 +258,7 @@ else
     
     		$allowinstall=0;
     	}
    -	// File exists but can't be modified
    +	// File exists but cannot be modified
     	elseif (!is_writable($conffile))
     	{
     		if ($confexists)
    @@ -294,7 +294,7 @@ else
     	}
     	print "<br>\n";
     
    -	// Requirements ok, we display the next step button
    +	// Requirements met/all ok: display the next step button
     	if ($checksok)
     	{
     		$ok=0;
    @@ -307,7 +307,7 @@ else
     			{
     				if (! file_exists($dolibarr_main_document_root."/core/lib/admin.lib.php"))
     				{
    -				    print '<font class="error">A '.$conffiletoshow.' file exists with a dolibarr_main_document_root to '.$dolibarr_main_document_root.' that seems wrong. Try to fix or remove the '.$conffiletoshow.' file.</font><br>'."\n";
    +                    print '<span class="error">A '.$conffiletoshow.' file exists with a dolibarr_main_document_root to '.$dolibarr_main_document_root.' that seems wrong. Try to fix or remove the '.$conffiletoshow.' file.</span><br>'."\n";
     				    dol_syslog("A '" . $conffiletoshow . "' file exists with a dolibarr_main_document_root to " . $dolibarr_main_document_root . " that seems wrong. Try to fix or remove the '" . $conffiletoshow . "' file.", LOG_WARNING);
     				}
     				else
    @@ -326,7 +326,7 @@ else
                     else $dolibarr_main_db_pass = dol_decode($dolibarr_main_db_encrypted_pass);
                 }
     
    -    				// $conf is already instancied inside inc.php
    +    				// $conf already created in inc.php
         				$conf->db->type = $dolibarr_main_db_type;
         				$conf->db->host = $dolibarr_main_db_host;
         				$conf->db->port = $dolibarr_main_db_port;
    @@ -342,7 +342,7 @@ else
     			}
     		}
     
    -		// If a database access is available, we set more variable
    +		// If database access is available, we set more variables
     		if ($ok)
     		{
     			if (empty($dolibarr_main_db_encryption)) $dolibarr_main_db_encryption=0;
    @@ -364,8 +364,8 @@ else
     		// Show title
     		if (! empty($conf->global->MAIN_VERSION_LAST_UPGRADE) || ! empty($conf->global->MAIN_VERSION_LAST_INSTALL))
     		{
    -			print $langs->trans("VersionLastUpgrade").': <b><font class="ok">'.(empty($conf->global->MAIN_VERSION_LAST_UPGRADE)?$conf->global->MAIN_VERSION_LAST_INSTALL:$conf->global->MAIN_VERSION_LAST_UPGRADE).'</font></b><br>';
    -			print $langs->trans("VersionProgram").': <b><font class="ok">'.DOL_VERSION.'</font></b>';
    +            print $langs->trans("VersionLastUpgrade").': <b><span class="ok">'.(empty($conf->global->MAIN_VERSION_LAST_UPGRADE)?$conf->global->MAIN_VERSION_LAST_INSTALL:$conf->global->MAIN_VERSION_LAST_UPGRADE).'</span></b><br>';
    +            print $langs->trans("VersionProgram").': <b><span class="ok">'.DOL_VERSION.'</span></b>';
     			//print ' '.img_warning($langs->trans("RunningUpdateProcessMayBeRequired"));
     			print '<br>';
     			print '<br>';
    @@ -375,7 +375,7 @@ else
     		print $langs->trans("InstallEasy")." ";
     		print $langs->trans("ChooseYourSetupMode");
     
    -        print '<br><br>';
    +        print '<br>';
     
     		$foundrecommandedchoice=0;
     
    @@ -383,9 +383,9 @@ else
             $notavailable_choices = array();
     
     		// Show first install line
    -		$choice = '<tr class="listofchoices"><td class="listofchoices nowrap" align="center"><b>'.$langs->trans("FreshInstall").'</b>';
    +        $choice = "\n".'<tr><td class="nowrap center"><b>'.$langs->trans("FreshInstall").'</b>';
     		$choice .= '</td>';
    -		$choice .= '<td class="listofchoices listofchoicesdesc">';
    +        $choice .= '<td class="listofchoicesdesc">';
     		$choice .= $langs->trans("FreshInstallDesc");
     		if (empty($dolibarr_main_db_host))	// This means install process was not run
     		{
    @@ -397,7 +397,7 @@ else
     		}
     
             $choice .= '</td>';
    -        $choice .= '<td class="listofchoices" align="center">';
    +        $choice .= '<td class="center">';
     		if ($allowinstall)
     		{
                 $choice .= '<a class="button" href="fileconf.php?selectlang='.$setuplang.'">'.$langs->trans("Start").'</a>';
    @@ -436,7 +436,8 @@ else
     								array('from'=>'4.0.0', 'to'=>'5.0.0'),
     								array('from'=>'5.0.0', 'to'=>'6.0.0'),
     								array('from'=>'6.0.0', 'to'=>'7.0.0'),
    -								array('from'=>'7.0.0', 'to'=>'8.0.0')
    +								array('from'=>'7.0.0', 'to'=>'8.0.0'),
    +								array('from'=>'8.0.0', 'to'=>'9.0.0')
     		);
     
     		$count=0;
    @@ -464,7 +465,7 @@ else
     
                 if ($ok)
                 {
    -                if (count($dolibarrlastupgradeversionarray) >= 2)	// If a database access is available and last upgrade version is known
    +                if (count($dolibarrlastupgradeversionarray) >= 2)	// If database access is available and last upgrade version is known
                     {
                         // Now we check if this is the first qualified choice
                         if ($allowupgrade && empty($foundrecommandedchoice) &&
    @@ -476,22 +477,23 @@ else
                         }
                     }
                     else {
    -                    // We can not recommand a choice.
    +                    // We cannot recommend a choice.
                         // A version of install may be known, but we need last upgrade.
                     }
                 }
     
    -            $choice .= '<tr class="listofchoices '.($recommended_choice ? 'choiceselected' : '').'">';
    -            $choice .= '<td class="listofchoices nowrap" align="center"><b>'.$langs->trans("Upgrade").'<br>'.$newversionfrom.$newversionfrombis.' -> '.$newversionto.'</b></td>';
    -            $choice .= '<td class="listofchoices listofchoicesdesc">';
    +            $choice .= "\n".'<tr'.($recommended_choice ? ' class="choiceselected"' : '').'>';
    +            $choice .= '<td class="nowrap center"><b>'.$langs->trans("Upgrade").'<br>'.$newversionfrom.$newversionfrombis.' -> '.$newversionto.'</b></td>';
    +            $choice .= '<td class="listofchoicesdesc">';
                 $choice .= $langs->trans("UpgradeDesc");
     
                 if ($recommended_choice)
                 {
                     $choice .= '<br>';
                     //print $langs->trans("InstallChoiceRecommanded",DOL_VERSION,$conf->global->MAIN_VERSION_LAST_UPGRADE);
    -                $choice .= '<div class="center"><div class="ok">'.$langs->trans("InstallChoiceSuggested").'</div>';
    -                if ($count < count($migarray))	// There is other choices after
    +                $choice .= '<div class="center">';
    +                $choice .=  '<div class="ok">'.$langs->trans("InstallChoiceSuggested").'</div>';
    +                if ($count < count($migarray))	// There are other choices after
                     {
                         print $langs->trans("MigrateIsDoneStepByStep",DOL_VERSION);
                     }
    @@ -499,7 +501,7 @@ else
                 }
     
                 $choice .= '</td>';
    -            $choice .= '<td class="listofchoices" align="center">';
    +            $choice .= '<td class="center">';
     			if ($allowupgrade)
     			{
     				$disabled=false;
    @@ -511,8 +513,14 @@ else
     				{
     					$foundrecommandedchoice = 2;
     				}
    -				if ($disabled) $choice .= '<span class="buttonDisable runupgrade"'.($disabled?' disabled="disabled"':'').' href="#">'.$langs->trans("NotAvailable").'</span>';
    -				else $choice .= '<a class="button runupgrade"'.($disabled?' disabled="disabled"':'').' href="upgrade.php?action=upgrade'.($count<count($migrationscript)?'_'.$versionto:'').'&amp;selectlang='.$setuplang.'&amp;versionfrom='.$versionfrom.'&amp;versionto='.$versionto.'">'.$langs->trans("Start").'</a>';
    +				if ($disabled)
    +                {
    +                    $choice .= '<span class="button">'.$langs->trans("NotAvailable").'</span>';
    +                }
    +				else
    +                {
    +                    $choice .= '<a class="button runupgrade" href="upgrade.php?action=upgrade'.($count<count($migrationscript)?'_'.$versionto:'').'&amp;selectlang='.$setuplang.'&amp;versionfrom='.$versionfrom.'&amp;versionto='.$versionto.'">'.$langs->trans("Start").'</a>';
    +                }
     			}
     			else
     			{
    @@ -536,33 +544,31 @@ else
     		}
     
             // Array of install choices
    +        print"\n";
             print '<table width="100%" class="listofchoices">';
             foreach ($available_choices as $choice) {
                 print $choice;
             }
     
    -        print '</table>';
    +        print '</table>'."\n";
     
             if (count($notavailable_choices)) {
     
    -            print '<br>';
                 print '<div id="AShowChoices">';
    -            print '<img src="../theme/eldy/img/1downarrow.png"> <a href="#">'.$langs->trans('ShowNotAvailableOptions').'</a>';
    +            print '<img src="../theme/eldy/img/1downarrow.png">';
                 print '</div>';
     
                 print '<div id="navail_choices" style="display:none">';
    -            print '<br>';
    +            print "<br>\n";
                 print '<table width="100%" class="listofchoices">';
                 foreach ($notavailable_choices as $choice) {
                     print $choice;
                 }
     
    -            print '</table>';
    +            print '</table>'."\n";
                 print '</div>';
             }
    -
     	}
    -
     }
     
     print '<script type="text/javascript">
    @@ -589,6 +595,5 @@ $(".runupgrade").click(function() {
     
     </script>';
     
    -dolibarr_install_syslog("--- check: end");
    +dolibarr_install_syslog("- check: end");
     pFooter(1);	// Never display next button
    -
    diff --git a/htdocs/install/default.css b/htdocs/install/default.css
    index e23a36ddd21..2e005a30b21 100644
    --- a/htdocs/install/default.css
    +++ b/htdocs/install/default.css
    @@ -1,5 +1,5 @@
    -/* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org> 
    - * Copyright (C) 2009-2017 Laurent Destailleur  <eldy@users.sourceforge.net> 
    +/* Copyright (C) 2004      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    + * Copyright (C) 2009-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
      *
      * 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
    @@ -89,16 +89,16 @@ div.soustitre {
     	body {
     		margin: 15px 4px 4px;
     	}
    -	
    -	input, input[type=text], input[type=password], select, textarea     { 
    -		min-width: 20px; 
    +
    +	input, input[type=text], input[type=password], select, textarea     {
    +		min-width: 20px;
         	min-height: 1.4em;
         	line-height: 1.4em;
         	padding: .4em .1em;
         	border: 1px solid #BBB;
         	/* max-width: inherit; why this ? */
          }
    -     
    +
         .hideonsmartphone { display: none; }
         .noenlargeonsmartphone { width : 50px !important; display: inline !important; }
         .maxwidthonsmartphone { max-width: 100px; }
    @@ -120,13 +120,13 @@ div.soustitre {
         	padding-left: 0;
         	padding-right: 0;
     	}
    -	
    +
     	table.main-inside {
     		padding-left: 1px;
     		padding-right: 1px;
     		line-height: 20px;
     	}
    -	
    +
     	span.titre {
     	    font-size: 90%;
     	    font-weight: normal;
    @@ -146,7 +146,7 @@ input:disabled
     	padding: 0 0 0 0;
     	margin: 0 0 0 0;
     	color: #AAA !important;
    -	cursor: not-allowed !important; 
    +	cursor: not-allowed !important;
     }
     
     input[type=submit] {
    @@ -199,7 +199,7 @@ input:-webkit-autofill {
         -webkit-box-shadow: 0 0 0 50px #FBFFEA inset;
     }
     
    -table.listofchoices, tr.listofchoices, td.listofchoices {
    +table.listofchoices, table.listofchoices tr, table.listofchoices td {
     	border-collapse: collapse;
         padding: 4px;
         color: #000000;
    @@ -207,15 +207,12 @@ table.listofchoices, tr.listofchoices, td.listofchoices {
     	line-height: 18px;
     }
     
    -tr.listofchoices {
    -    height: 42px;	
    -}
     .listofchoicesdesc {
     	color: #999 !important;
     }
     .blinkwait {
     	font-weight: bold;
    -	text-decoration:blink !important;	
    +	text-decoration:blink !important;
     }
     
     .installchoices table tr td  {
    @@ -230,7 +227,7 @@ tr.listofchoices {
     div.ok {
     	color: #114466;
     }
    -font.ok {
    +span.ok {
     	color: #114466;
     }
     
    @@ -238,7 +235,7 @@ font.ok {
     div.warning {
     	color: #777711;
     }
    -font.warning {
    +span.warning {
     	color: #777711;
     }
     
    @@ -249,7 +246,7 @@ div.error {
     	padding: 0.2em 0.2em 0.2em 0;
     	margin: 0.5em 0 0.5em 0;
     }
    -font.error {
    +span.error {
     	color: #550000;
     	font-weight: bold;
     }
    diff --git a/htdocs/install/doctemplates/shipment/index.html b/htdocs/install/doctemplates/shipments/index.html
    similarity index 100%
    rename from htdocs/install/doctemplates/shipment/index.html
    rename to htdocs/install/doctemplates/shipments/index.html
    diff --git a/htdocs/install/doctemplates/shipment/template_shipment.odt b/htdocs/install/doctemplates/shipments/template_shipment.odt
    similarity index 100%
    rename from htdocs/install/doctemplates/shipment/template_shipment.odt
    rename to htdocs/install/doctemplates/shipments/template_shipment.odt
    diff --git a/htdocs/install/doctemplates/supplier_proposal/index.html b/htdocs/install/doctemplates/supplier_proposals/index.html
    similarity index 100%
    rename from htdocs/install/doctemplates/supplier_proposal/index.html
    rename to htdocs/install/doctemplates/supplier_proposals/index.html
    diff --git a/htdocs/install/doctemplates/supplier_proposal/template_supplier_proposal.odt b/htdocs/install/doctemplates/supplier_proposals/template_supplier_proposal.odt
    similarity index 100%
    rename from htdocs/install/doctemplates/supplier_proposal/template_supplier_proposal.odt
    rename to htdocs/install/doctemplates/supplier_proposals/template_supplier_proposal.odt
    diff --git a/htdocs/install/doctemplates/websites/index.html b/htdocs/install/doctemplates/websites/index.html
    new file mode 100644
    index 00000000000..e69de29bb2d
    diff --git a/htdocs/install/doctemplates/websites/website_template-corporate.zip b/htdocs/install/doctemplates/websites/website_template-corporate.zip
    new file mode 100644
    index 00000000000..0c45f47e84f
    Binary files /dev/null and b/htdocs/install/doctemplates/websites/website_template-corporate.zip differ
    diff --git a/htdocs/install/fileconf.php b/htdocs/install/fileconf.php
    index b0affb2218a..fd902b540fd 100644
    --- a/htdocs/install/fileconf.php
    +++ b/htdocs/install/fileconf.php
    @@ -24,7 +24,7 @@
     /**
      *       \file       htdocs/install/fileconf.php
      *       \ingroup    install
    - *       \brief      Ask all informations required to build Dolibarr htdocs/conf/conf.php file (will be wrote on disk on next page step1)
    + *       \brief      Ask all information required to build Dolibarr htdocs/conf/conf.php file (will be written to disk on next page step1)
      */
     
     include_once 'inc.php';
    @@ -36,10 +36,9 @@ $err=0;
     $setuplang=GETPOST("selectlang",'',3)?GETPOST("selectlang",'',3):(isset($_GET["lang"])?$_GET["lang"]:'auto');
     $langs->setDefaultLang($setuplang);
     
    -$langs->load("install");
    -$langs->load("errors");
    +$langs->loadLangs(array("install", "errors"));
     
    -dolibarr_install_syslog("--- fileconf: entering fileconf.php page");
    +dolibarr_install_syslog("- fileconf: entering fileconf.php page");
     
     // You can force preselected values of the config step of Dolibarr by adding a file
     // install.forced.php into directory htdocs/install (This is the case with some wizard
    @@ -56,7 +55,7 @@ if (! isset($force_install_databaselogin))		$force_install_databaselogin='';
     if (! isset($force_install_databasepass))		$force_install_databasepass='';
     if (! isset($force_install_databaserootlogin))	$force_install_databaserootlogin='';
     if (! isset($force_install_databaserootpass))	$force_install_databaserootpass='';
    -// Now we load forced value from install.forced.php file.
    +// Now we load forced values from install.forced.php file.
     $useforcedwizard=false;
     $forcedfile="./install.forced.php";
     if ($conffile == "/etc/dolibarr/conf.php") $forcedfile="/etc/dolibarr/install.forced.php";	// Must be after inc.php
    @@ -71,7 +70,7 @@ if (@file_exists($forcedfile)) {
      *	View
      */
     
    -session_start();	// To be able to keep info into session (used for not loosing pass during navigation. pass must not transit throug parmaeters)
    +session_start();	// To be able to keep info into session (used for not losing pass during navigation. pass must not transit through parmaeters)
     
     pHeader($langs->trans("ConfigurationFile"), "step1", "set", "", (empty($force_dolibarr_js_JQUERY)?'':$force_dolibarr_js_JQUERY.'/'), 'main-inside-bis');
     
    @@ -80,7 +79,7 @@ if (! is_writable($conffile))
     {
         print $langs->trans("ConfFileIsNotWritable", $conffiletoshow);
     	dolibarr_install_syslog("fileconf: config file is not writable", LOG_WARNING);
    -	dolibarr_install_syslog("--- fileconf: end");
    +    dolibarr_install_syslog("- fileconf: end");
         pFooter(1,$setuplang,'jscheckparam');
         exit;
     }
    @@ -117,20 +116,18 @@ if (! empty($force_install_message))
     
     	<!-- Documents root $dolibarr_main_document_root -->
     	<tr>
    -	<?php
    -	print '<td class="tdtop label"><b>';
    -	print $langs->trans("WebPagesDirectory");
    -	print "</b></td>";
    -
    +        <td class="label"><label for="main_dir"><b><?php print $langs->trans("WebPagesDirectory"); ?></b></label></td>
    +<?php
     	if (empty($dolibarr_main_url_root)) {
     		$dolibarr_main_document_root = detect_dolibarr_main_document_root();
     	}
     	?>
    -		<td class="label tdtop">
    +		<td class="label">
     			<input type="text"
     			       class="minwidth300"
    -			       value="<?php print $dolibarr_main_document_root ?>"
    -			       name="main_dir"
    +                   id="main_dir"
    +                   name="main_dir"
    +                   value="<?php print $dolibarr_main_document_root ?>"
     				<?php if (!empty($force_install_noedit)) {
     					print ' disabled';
     				} ?>
    @@ -149,19 +146,19 @@ if (! empty($force_install_message))
     
     	<!-- Documents URL $dolibarr_main_data_root -->
     	<tr>
    -		<td class="tdtop label"><b> <?php print $langs->trans("DocumentsDirectory"); ?></b>
    -		</td>
    +		<td class="label"><label for="main_data_dir"><b><?php print $langs->trans("DocumentsDirectory"); ?></b></label></td>
     		<?php
     		$dolibarr_main_data_root = @$force_install_main_data_root;
     		if (empty($dolibarr_main_data_root)) {
     			$dolibarr_main_data_root = detect_dolibarr_main_data_root($dolibarr_main_document_root);
     		}
     		?>
    -		<td class="label tdtop">
    +		<td class="label">
     			<input type="text"
     			       class="minwidth300"
    -			       value="<?php print $dolibarr_main_data_root ?>"
    -			       name="main_data_dir"
    +                   id="main_data_dir"
    +                   name="main_data_dir"
    +                   value="<?php print $dolibarr_main_data_root ?>"
     				<?php if (!empty($force_install_noedit)) {
     					print ' disabled';
     				} ?>
    @@ -174,7 +171,7 @@ if (! empty($force_install_message))
     		?>
     		<ul>
     			<li>/var/lib/dolibarr/documents</li>
    -			<li>C:/My Documents/dolibarr/</li>
    +			<li>C:/My Documents/dolibarr/documents</li>
     		</ul>
     		</td>
     	</tr>
    @@ -186,12 +183,13 @@ if (! empty($force_install_message))
     	}
     	?>
     	<tr>
    -		<td class="tdtop label"><b> <?php echo $langs->trans("URLRoot"); ?></b>
    +        <td class="label"><label for="main_url"><b><?php echo $langs->trans("URLRoot"); ?></b></label>
     		</td>
    -		<td class="tdtop label">
    +		<td class="label">
     			<input type="text"
     			       class="minwidth300"
    -			       name="main_url"
    +			       id="main_url"
    +                   name="main_url"
     			       value="<?php print $dolibarr_main_url_root; ?> "
     				<?php if (!empty($force_install_noedit)) {
     					print ' disabled';
    @@ -202,6 +200,7 @@ if (! empty($force_install_message))
     		<ul>
     			<li>http://localhost/</li>
     			<li>http://www.myserver.com:8180/dolibarr</li>
    +			<li>https://www.myvirtualfordolibarr.com/</li>
     		</ul>
     		</td>
     	</tr>
    @@ -210,10 +209,11 @@ if (! empty($force_install_message))
     	if (! empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') {   // Enabled if the installation process is "https://"
     	    ?>
     	<tr>
    -		<td class="tdtop label"><?php echo $langs->trans("ForceHttps"); ?></td>
    -		<td class="label tdtop">
    -			<input type="checkbox"
    -			       name="main_force_https"
    +                    <td class="label"><label for="main_force_https"><?php echo $langs->trans("ForceHttps"); ?></label></td>
    +                    <td class="label">
    +                        <input type="checkbox"
    +                               id="main_force_https"
    +                               name="main_force_https"
     				<?php if (!empty($force_install_mainforcehttps)) {
     					print ' checked';
     				} ?>
    @@ -239,11 +239,11 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr>
    -		<td class="label tdtop"><b> <?php echo $langs->trans("DatabaseName"); ?>
    -		</b></td>
    -		<td class="label tdtop">
    -			<input type="text" id="db_name"
    -			       name="db_name"
    +        <td class="label"><label for="db_name"><b><?php echo $langs->trans("DatabaseName"); ?></b></label></td>
    +		<td class="label">
    +			<input type="text"
    +			       id="db_name"
    +                   name="db_name"
     			       value="<?php echo (!empty($dolibarr_main_db_name)) ? $dolibarr_main_db_name : ($force_install_database ? $force_install_database : 'dolibarr'); ?>"
     				<?php if ($force_install_noedit == 2 && $force_install_database !== null) {
     					print ' disabled';
    @@ -262,8 +262,7 @@ if (! empty($force_install_message))
     	?>
     	<tr>
     		<!-- Driver type -->
    -		<td class="tdtop label"><b> <?php echo $langs->trans("DriverType"); ?>
    -		</b></td>
    +		<td class="label"><label for="db_type"><b><?php echo $langs->trans("DriverType"); ?></b></label></td>
     
     		<td class="label">
     		<?php
    @@ -338,10 +337,10 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="tdtop label"><b> <?php echo $langs->trans("DatabaseServer"); ?>
    -		</b></td>
    -		<td class="tdtop label">
    +		<td class="label"><label for="db_host"><b><?php echo $langs->trans("DatabaseServer"); ?></b></label></td>
    +		<td class="label">
     			<input type="text"
    +                   id="db_host"
     			       name="db_host"
     			       value="<?php print (!empty($force_install_dbserver) ? $force_install_dbserver : (!empty($dolibarr_main_db_host) ? $dolibarr_main_db_host : 'localhost')); ?>"
     				<?php if ($force_install_noedit == 2 && $force_install_dbserver !== null) {
    @@ -355,8 +354,8 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="tdtop label"><?php echo $langs->trans("Port"); ?></td>
    -		<td class="tdtop label">
    +        <td class="label"><label for="db_port"><?php echo $langs->trans("Port"); ?></label></td>
    +		<td class="label">
     			<input type="text"
     			       name="db_port"
     			       id="db_port"
    @@ -372,10 +371,10 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="label tdtop"><?php echo $langs->trans("DatabasePrefix"); ?>
    -		</td>
    -		<td class="label tdtop">
    -			<input type="text" id="db_prefix"
    +        <td class="label"><label for="db_prefix"><?php echo $langs->trans("DatabasePrefix"); ?></label></td>
    +		<td class="label">
    +			<input type="text"
    +                   id="db_prefix"
     			       name="db_prefix"
     			       value="<?php echo(!empty($force_install_prefix) ? $force_install_prefix : (!empty($dolibarr_main_db_prefix) ? $dolibarr_main_db_prefix : 'llx_')); ?>"
     				<?php if ($force_install_noedit == 2 && $force_install_prefix !== null) {
    @@ -383,13 +382,12 @@ if (! empty($force_install_message))
     				} ?>
     			>
     		</td>
    -		<td class="comment"><?php echo $langs->trans("DatabasePrefix"); ?></td>
    +		<td class="comment"><?php echo $langs->trans("DatabasePrefixDescription"); ?></td>
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="label tdtop"><?php echo $langs->trans("CreateDatabase"); ?>
    -		</td>
    -		<td class="label tdtop">
    +        <td class="label"><label for="db_create_database"><?php echo $langs->trans("CreateDatabase"); ?></label></td>
    +		<td class="label">
     			<input type="checkbox"
     			       id="db_create_database"
     			       name="db_create_database"
    @@ -406,10 +404,10 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="label tdtop"><b><?php echo $langs->trans("Login"); ?></b>
    -		</td>
    -		<td class="label tdtop">
    -			<input type="text" id="db_user"
    +		<td class="label"><label for="db_user"><b><?php echo $langs->trans("Login"); ?></b></label></td>
    +		<td class="label">
    +			<input type="text"
    +                   id="db_user"
     			       name="db_user"
     			       value="<?php print (!empty($force_install_databaselogin)) ? $force_install_databaselogin : $dolibarr_main_db_user; ?>"
     				<?php if ($force_install_noedit == 2 && $force_install_databaselogin !== null) {
    @@ -421,10 +419,10 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="label tdtop"><b><?php echo $langs->trans("Password"); ?></b>
    -		</td>
    -		<td class="label tdtop">
    -			<input type="password" id="db_pass" autocomplete="off"
    +		<td class="label"><label for="db_pass"><b><?php echo $langs->trans("Password"); ?></b></label></td>
    +		<td class="label">
    +			<input type="password"
    +                   id="db_pass" autocomplete="off"
     			       name="db_pass"
     			       value="<?php
     			       // If $force_install_databasepass is on, we don't want to set password, we just show '***'. Real value will be extracted from the forced install file at step1.
    @@ -443,11 +441,11 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite">
    -		<td class="label tdtop"><?php echo $langs->trans("CreateUser"); ?>
    -		</td>
    -		<td class="label tdtop">
    +		<td class="label"><label for="db_create_user"><?php echo $langs->trans("CreateUser"); ?></label></td>
    +		<td class="label">
     			<input type="checkbox"
    -			       id="db_create_user" name="db_create_user"
    +			       id="db_create_user"
    +                   name="db_create_user"
     				<?php if (!empty($force_install_createuser)) {
     					print ' checked';
     				} ?>
    @@ -473,8 +471,8 @@ if (! empty($force_install_message))
     	</tr>
     
     	<tr class="hidesqlite hideroot">
    -		<td class="label tdtop"><b><?php echo $langs->trans("Login"); ?></b></td>
    -		<td class="label tdtop">
    +		<td class="label"><label for="db_user_root"><b><?php echo $langs->trans("Login"); ?></b></label></td>
    +		<td class="label">
     			<input type="text"
     			       id="db_user_root"
     			       name="db_user_root"
    @@ -497,28 +495,27 @@ if (! empty($force_install_message))
     
     	</tr>
     	<tr class="hidesqlite hideroot">
    -		<td class="label tdtop"><b><?php echo $langs->trans("Password"); ?></b>
    -		</td>
    -		<td class="label tdtop">
    +		<td class="label"><label for="db_pass_root"><b><?php echo $langs->trans("Password"); ?></b></label></td>
    +		<td class="label">
     			<input type="password"
     			       autocomplete="off"
     			       id="db_pass_root"
     			       name="db_pass_root"
     			       class="needroot"
     			       value="<?php
    -			       // If $force_install_databaserootpass is on, we don't want to set password here, we just show '***'. Real value will be extracted from the forced install file at step1.
    -			       $autofill = ((!empty($force_install_databaserootpass)) ? str_pad('', strlen($force_install_databaserootpass), '*') : @$db_pass_root);
    -			       if (!empty($dolibarr_main_prod)) {
    -				       $autofill = '';
    -			       }
    -				   // Do not autofill password if instance is a production instance
    -			       if (!empty($_SERVER["SERVER_NAME"]) && !in_array($_SERVER["SERVER_NAME"],
    -					       array('127.0.0.1', 'localhost', 'localhostgit'))
    -			       ) {
    -				       $autofill = '';
    -			       }    // Do not autofill password for remote access
    -			       print dol_escape_htmltag($autofill);
    -			       ?>"
    +			        // If $force_install_databaserootpass is on, we don't want to set password here, we just show '***'. Real value will be extracted from the forced install file at step1.
    +			        $autofill = ((!empty($force_install_databaserootpass)) ? str_pad('', strlen($force_install_databaserootpass), '*') : @$db_pass_root);
    +			        if (!empty($dolibarr_main_prod)) {
    +				        $autofill = '';
    +			        }
    +				    // Do not autofill password if instance is a production instance
    +			        if (!empty($_SERVER["SERVER_NAME"]) && !in_array($_SERVER["SERVER_NAME"],
    +					    array('127.0.0.1', 'localhost', 'localhostgit'))
    +			        ) {
    +				        $autofill = '';
    +			        }    // Do not autofill password for remote access
    +			        print dol_escape_htmltag($autofill);
    +			        ?>"
     				<?php if ($force_install_noedit > 0 && ! empty($force_install_databaserootpass)) {
     					print ' disabled';     // May be removed by javascript
     				} ?>
    @@ -648,5 +645,5 @@ function jscheckparam()
     
     // $db->close();	Not database connexion yet
     
    -dolibarr_install_syslog("--- fileconf: end");
    +dolibarr_install_syslog("- fileconf: end");
     pFooter($err,$setuplang,'jscheckparam');
    diff --git a/htdocs/install/inc.php b/htdocs/install/inc.php
    index 0a2a6866f26..c1581d37392 100644
    --- a/htdocs/install/inc.php
    +++ b/htdocs/install/inc.php
    @@ -149,7 +149,7 @@ if ($suburi == '/') $suburi = '';   // If $suburi is /, it is now ''
     define('DOL_URL_ROOT', $suburi);    // URL relative root ('', '/dolibarr', ...)
     
     
    -if (empty($conf->file->character_set_client))      	$conf->file->character_set_client="UTF-8";
    +if (empty($conf->file->character_set_client))      	$conf->file->character_set_client="utf-8";
     if (empty($conf->db->character_set))  				$conf->db->character_set='utf8';
     if (empty($conf->db->dolibarr_main_db_collation))  	$conf->db->dolibarr_main_db_collation='utf8_unicode_ci';
     if (empty($conf->db->dolibarr_main_db_encryption)) 	$conf->db->dolibarr_main_db_encryption=0;
    @@ -566,7 +566,7 @@ function detect_dolibarr_main_url_root()
     		$dolibarr_main_url_root = $_SERVER["SERVER_URL"] . $_SERVER["DOCUMENT_URI"];
     	} // If SCRIPT_URI, SERVER_URL, DOCUMENT_URI not defined (Ie: Apache 2.0.44 for Windows)
     	else {
    -		$proto = 'http';
    +        $proto = ( (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') || $_SERVER['SERVER_PORT'] == 443) ? 'https' : 'http';
     		if (!empty($_SERVER["HTTP_HOST"])) {
     			$serverport = $_SERVER["HTTP_HOST"];
     		} else {
    diff --git a/htdocs/install/index.php b/htdocs/install/index.php
    index 82dcd87b030..46e60be52ec 100644
    --- a/htdocs/install/index.php
    +++ b/htdocs/install/index.php
    @@ -55,7 +55,7 @@ print '<br><br><div class="center">';
     print '<table>';
     
     print '<tr>';
    -print '<td>'.$langs->trans("DefaultLanguage").' : </td><td align="left">';
    +print '<td>'.$langs->trans("DefaultLanguage").' : </td><td>';
     print $formadmin->select_language('auto','selectlang',1,0,0,1);
     print '</td>';
     print '</tr>';
    diff --git a/htdocs/install/lib/repair.lib.php b/htdocs/install/lib/repair.lib.php
    index 5e81b15ce10..39221c3a089 100644
    --- a/htdocs/install/lib/repair.lib.php
    +++ b/htdocs/install/lib/repair.lib.php
    @@ -136,7 +136,6 @@ function clean_data_ecm_directories()
     				$resqlupdate=$db->query($sqlupdate);
     				if (! $resqlupdate) dol_print_error($db,'Failed to update');
     			}
    -
     		}
     	}
     	else dol_print_error($db,'Failed to run request');
    diff --git a/htdocs/install/mysql/data/llx_accounting_abc.sql b/htdocs/install/mysql/data/llx_accounting_abc.sql
    index 9e933816ac5..526c62693e2 100644
    --- a/htdocs/install/mysql/data/llx_accounting_abc.sql
    +++ b/htdocs/install/mysql/data/llx_accounting_abc.sql
    @@ -7,6 +7,7 @@
     -- Copyright (C) 2007      Patrick Raguin       <patrick.raguin@gmail.com>
     -- Copyright (C) 2011-2018 Alexandre Spangaro   <aspangaro@zendsi.com>
     -- Copyright (C) 2015-2017 Juanjo Menent        <jmenent@2byte.es>
    +-- Copyright (C) 2018      Abbes bahfir         <dolipar@dolipar.org>
     --
     -- 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
    @@ -126,3 +127,5 @@ INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUE
     -- Description of chart of account RO RO-BASE
     INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES (  188, 'RO-BASE', 'Plan de conturi romanesc', 1);
     
    +-- Description of chart of account DZ NSCF
    +INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES (  13, 'NSCF', 'Nouveau système comptable financier', 1);
    diff --git a/htdocs/install/mysql/data/llx_accounting_account_dz.sql b/htdocs/install/mysql/data/llx_accounting_account_dz.sql
    new file mode 100644
    index 00000000000..bdb36303f3a
    --- /dev/null
    +++ b/htdocs/install/mysql/data/llx_accounting_account_dz.sql
    @@ -0,0 +1,838 @@
    +-- Copyright (C) 2018 Abbes Bahfir         <dolipar@dolipar.org>
    +--
    +-- 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 <http://www.gnu.org/licenses/>.
    +--
    +--
    +
    +--
    +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors
    +-- de l'install et tous les sigles '--' sont supprimés.
    +--
    +
    +-- Descriptif du système comptable financier DZ NSCF
    +-- ID 15000 - 15811
    +-- ADD 1300000 to rowid # Do no remove this comment --
    +
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (17000,'NSCF','CAPIT','XXXXXX','1',0,'Comptes de capitaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15001,'NSCF','CAPIT','XXXXXX','10',17000,'Capital, réserves et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15002,'NSCF','CAPIT','XXXXXX','101',15001,'Capital émis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15003,'NSCF','CAPIT','XXXXXX','1011',15002,'Capital souscrit, non appelé','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15004,'NSCF','CAPIT','XXXXXX','1012',15002,'Capital souscrit, appelé, non versé','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15005,'NSCF','CAPIT','XXXXXX','1013',15002,'Capital souscrit, appelé, versé','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15006,'NSCF','CAPIT','XXXXXX','10131',15005,'Capital non amorti','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15007,'NSCF','CAPIT','XXXXXX','10132',15005,'Capital amorti','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15008,'NSCF','CAPIT','XXXXXX','1018',15002,'Capital souscrit, soumis à des réglementations particulières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15009,'NSCF','CAPIT','XXXXXX','103',15001,'Primes liées au capital social','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15010,'NSCF','CAPIT','XXXXXX','1031',15009,'Primes d''émission','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15011,'NSCF','CAPIT','XXXXXX','1032',15009,'Primes de fusion','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15012,'NSCF','CAPIT','XXXXXX','1033',15009,'Primes d''apport','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15013,'NSCF','CAPIT','XXXXXX','1034',15009,'Primes de conversion d''obligations en actions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15014,'NSCF','CAPIT','XXXXXX','104',15001,'Ecart d''évaluation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15015,'NSCF','CAPIT','XXXXXX','105',15001,'Ecart de réévaluation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15016,'NSCF','CAPIT','XXXXXX','1050',15015,'Ecart de réévaluation : Immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15017,'NSCF','CAPIT','XXXXXX','10503',15016,'Ecart de réévaluation : Frais de recherche et de développement immobilisés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15018,'NSCF','CAPIT','XXXXXX','10504',15016,'Ecart de réévaluation : Logiciels informatiques et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15019,'NSCF','CAPIT','XXXXXX','10505',15016,'Ecart de réévaluation : Concessions et droits similaires, brevets, licences et marques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15020,'NSCF','CAPIT','XXXXXX','10507',15016,'Ecarts de réévaluation : Fonds commercial – goodwill','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15021,'NSCF','CAPIT','XXXXXX','10508',15016,'Ecart de réévaluation : Immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15022,'NSCF','CAPIT','XXXXXX','1051',15015,'Ecart de réévaluation :Immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15023,'NSCF','CAPIT','XXXXXX','10511',15022,'Ecart de réévaluation : Terrains','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15024,'NSCF','CAPIT','XXXXXX','10512',15022,'Ecart de réévaluation : Agencements et  aménagements de terrains','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15025,'NSCF','CAPIT','XXXXXX','10513',15022,'Ecart de réévaluation : Constructions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15026,'NSCF','CAPIT','XXXXXX','10515',15022,'Ecarts de réévaluation : Installations techniques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15027,'NSCF','CAPIT','XXXXXX','10518',15022,'Ecart de réévaluation : Autres Immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15028,'NSCF','CAPIT','XXXXXX','1052',15015,'Ecart de réévaluation sur immobilisations financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15029,'NSCF','CAPIT','XXXXXX','10526',15028,'Ecart de réévaluation : Titres de filiale','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15030,'NSCF','CAPIT','XXXXXX','10527',15028,'Ecart de réévaluation : Autres immobilisations financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15031,'NSCF','CAPIT','XXXXXX','106',15001,'Réserves','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15032,'NSCF','CAPIT','XXXXXX','1061',15031,'Réserve légale','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15033,'NSCF','CAPIT','XXXXXX','1062',15031,'Réserve statutaire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15034,'NSCF','CAPIT','XXXXXX','1063',15031,'Réserve ordinaire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15035,'NSCF','CAPIT','XXXXXX','1064',15031,'Réserve réglementée','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15036,'NSCF','CAPIT','XXXXXX','10641',15035,'Réserve réglementée proprement dits','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15037,'NSCF','CAPIT','XXXXXX','10642',15035,'Plus-values nettes à long terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15038,'NSCF','CAPIT','XXXXXX','1068',15031,'Autres réserves','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15039,'NSCF','CAPIT','XXXXXX','107',15001,'Ecart d''équivalence','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15040,'NSCF','CAPIT','XXXXXX','108',15001,'Compte de l''exploitant','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15041,'NSCF','CAPIT','XXXXXX','109',15001,'Capital souscrit - non appelé (Solde débiteur à l''actif du bilan)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15042,'NSCF','CAPIT','XXXXXX','11',17000,'Report à nouveau (solde créditeur ou débiteur)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15043,'NSCF','CAPIT','XXXXXX','110',15042,'Report à nouveau (solde créditeur)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15044,'NSCF','CAPIT','XXXXXX','119',15042,'Report à nouveau (solde débiteur)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15045,'NSCF','CAPIT','XXXXXX','12',17000,'Résultat de l''exercice (bénéfice ou perte)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15046,'NSCF','CAPIT','XXXXXX','120',15045,'Résultat de l''exercice (bénéfice)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15047,'NSCF','CAPIT','XXXXXX','129',15045,'Résultat de l''exercice (perte)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15048,'NSCF','CAPIT','XXXXXX','13',17000,'Produits et charges différés – hors cycle d''exploitation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15049,'NSCF','CAPIT','XXXXXX','131',15048,'Subventions d''équipements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15050,'NSCF','CAPIT','XXXXXX','1312',15049,'Subventions d''équipements – Transfert gratuit d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15051,'NSCF','CAPIT','XXXXXX','1314',15049,'Subventions d''équipements – Financement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15052,'NSCF','CAPIT','XXXXXX','1319',15049,'Subventions d''investissement inscrites au compte de résultat','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15053,'NSCF','CAPIT','XXXXXX','132',15048,'Autres subventions d''investissements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15054,'NSCF','CAPIT','XXXXXX','133',15048,'Impôts différés actif','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15055,'NSCF','CAPIT','XXXXXX','134',15048,'Impôts différés passif','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15056,'NSCF','CAPIT','XXXXXX','138',15048,'Autres produits et charges différés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15057,'NSCF','CAPIT','XXXXXX','15',17000,'Provisions pour charges - passifs non courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15058,'NSCF','CAPIT','XXXXXX','153',15057,'Provisions pour pensions et obligations similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15059,'NSCF','CAPIT','XXXXXX','155',15057,'Provisions pour impôts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15060,'NSCF','CAPIT','XXXXXX','156',15057,'Provisions pour renouvellement des immobilisations en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15061,'NSCF','CAPIT','XXXXXX','1560',15060,'Provisions pour renouvellement d''immobilisation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15062,'NSCF','CAPIT','XXXXXX','1562',15060,'Provisions pour renouvellement de gisements miniers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15063,'NSCF','CAPIT','XXXXXX','158',15057,'Autres provisions pour charges – passifs non courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15064,'NSCF','CAPIT','XXXXXX','1581',15063,'Provisions réglementées relatives aux immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15065,'NSCF','CAPIT','XXXXXX','1583',15063,'Provisions pour risques environnementaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15066,'NSCF','CAPIT','XXXXXX','16',17000,'Emprunts et dettes assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15067,'NSCF','CAPIT','XXXXXX','161',15066,'Titres participatifs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15068,'NSCF','CAPIT','XXXXXX','162',15066,'Emprunts obligataires convertibles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15069,'NSCF','CAPIT','XXXXXX','163',15066,'Autres emprunts obligataires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15070,'NSCF','CAPIT','XXXXXX','164',15066,'Emprunts auprès des établissements de crédit','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15071,'NSCF','CAPIT','XXXXXX','165',15066,'Dépôts et cautionnements reçus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15072,'NSCF','CAPIT','XXXXXX','1651',15071,'Dépôts reçus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15073,'NSCF','CAPIT','XXXXXX','1655',15071,'Cautionnements reçus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15074,'NSCF','CAPIT','XXXXXX','167',15066,'Dettes sur contrat de location - financement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15075,'NSCF','CAPIT','XXXXXX','168',15066,'Autres emprunts et dettes assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15076,'NSCF','CAPIT','XXXXXX','1681',15075,'Autres emprunts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15077,'NSCF','CAPIT','XXXXXX','1682',15075,'Emprunts auprès d''organismes internationaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15078,'NSCF','CAPIT','XXXXXX','1688',15075,'Intérêts courus sur emprunts et dettes assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15079,'NSCF','CAPIT','XXXXXX','169',15066,'Primes de remboursement des obligations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15080,'NSCF','CAPIT','XXXXXX','17',17000,'Dettes rattachées à des participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15081,'NSCF','CAPIT','XXXXXX','171',15080,'Dettes rattachées à des participations groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15082,'NSCF','CAPIT','XXXXXX','172',15080,'Dettes rattachées à des participations hors groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15083,'NSCF','CAPIT','XXXXXX','173',15080,'Dettes rattachées à des sociétés en participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15084,'NSCF','CAPIT','XXXXXX','1731',15083,'Principal','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15085,'NSCF','CAPIT','XXXXXX','1738',15083,'Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15086,'NSCF','CAPIT','XXXXXX','178',15080,'Autres dettes rattachées à des participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15087,'NSCF','CAPIT','XXXXXX','18',17000,'Comptes de liaison des établissements et sociétés en participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15088,'NSCF','CAPIT','XXXXXX','187',15087,'Biens et prestations de services échangés entre établissements (produits)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15089,'NSCF','CAPIT','XXXXXX','188',15087,'Comptes de liaison entre sociétés en participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15090,'NSCF','IMMO','XXXXXX','2',0,'COMPTES D''IMMOBILISATIONS','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15091,'NSCF','IMMO','XXXXXX','20',15090,'Immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15092,'NSCF','IMMO','XXXXXX','203',15091,'Frais de développement immobilisables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15093,'NSCF','IMMO','XXXXXX','204',15091,'Logiciels informatiques et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15094,'NSCF','IMMO','XXXXXX','205',15091,'Concessions et droits similaires, brevets, licences, marques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15095,'NSCF','IMMO','XXXXXX','2051',15094,'Logiciels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15096,'NSCF','IMMO','XXXXXX','2052',15094,'Brevets','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15097,'NSCF','IMMO','XXXXXX','2053',15094,'Marques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15098,'NSCF','IMMO','XXXXXX','2056',15094,'Licence','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15099,'NSCF','IMMO','XXXXXX','2058',15094,'Concession - autres droits similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15100,'NSCF','IMMO','XXXXXX','207',15091,'Ecart d''acquisition - goodwill','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15101,'NSCF','IMMO','XXXXXX','208',15091,'Autres immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15102,'NSCF','IMMO','XXXXXX','21',15090,'Immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15103,'NSCF','IMMO','XXXXXX','211',15102,'Terrains','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15104,'NSCF','IMMO','XXXXXX','2110',15103,'Terrains de construction et chantiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15105,'NSCF','IMMO','XXXXXX','2111',15103,'Terrains nus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15106,'NSCF','IMMO','XXXXXX','2112',15103,'Terrains aménagés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15107,'NSCF','IMMO','XXXXXX','2114',15103,'Terrains bâtis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15108,'NSCF','IMMO','XXXXXX','2115',15103,'Carrières et gisements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15109,'NSCF','IMMO','XXXXXX','2118',15103,'Autres terrains','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15110,'NSCF','IMMO','XXXXXX','212',15102,'Agencements et aménagements de terrains (même ventilation que celle du compte 211)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15111,'NSCF','IMMO','XXXXXX','213',15102,'Constructions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15112,'NSCF','IMMO','XXXXXX','2131',15111,'Bâtiments','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15113,'NSCF','IMMO','XXXXXX','21311',15112,'Bâtiments industriels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15114,'NSCF','IMMO','XXXXXX','21312',15112,'Bâtiments administratifs et commerciaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15115,'NSCF','IMMO','XXXXXX','21318',15112,'Autres ensembles immobiliers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15116,'NSCF','IMMO','XXXXXX','213181',15115,'Affectés aux opérations professionnelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15117,'NSCF','IMMO','XXXXXX','213188',15115,'Affectés aux opérations non professionnelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15118,'NSCF','IMMO','XXXXXX','2135',15111,'Installations générales - agencements - aménagements des constructions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15119,'NSCF','IMMO','XXXXXX','21351',15118,'Installation d''eau','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15120,'NSCF','IMMO','XXXXXX','21352',15118,'Installation d''électricité','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15121,'NSCF','IMMO','XXXXXX','21353',15118,'Installation de gaz','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15122,'NSCF','IMMO','XXXXXX','21354',15118,'Installation de vapeur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15123,'NSCF','IMMO','XXXXXX','21355',15118,'Installation de protection et de sécurité','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15124,'NSCF','IMMO','XXXXXX','21356',15118,'Installation de télécommunication','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15125,'NSCF','IMMO','XXXXXX','21357',15118,'Installation d''aération, chauffage et climatisation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15126,'NSCF','IMMO','XXXXXX','21358',15118,'Autres agencements et installations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15127,'NSCF','IMMO','XXXXXX','2138',15111,'Ouvrages d''infrastructures','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15128,'NSCF','IMMO','XXXXXX','21381',15127,'Voies de terre','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15129,'NSCF','IMMO','XXXXXX','21382',15127,'Voies de fer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15130,'NSCF','IMMO','XXXXXX','21383',15127,'Voies d''eau','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15131,'NSCF','IMMO','XXXXXX','21384',15127,'Barrages - puits d''eau','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15132,'NSCF','IMMO','XXXXXX','21385',15127,'Pistes d''aérodromes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15133,'NSCF','IMMO','XXXXXX','215',15102,'Installations techniques, matériel et outillage industriels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15134,'NSCF','IMMO','XXXXXX','2151',15133,'Installations complexes spécialisées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15135,'NSCF','IMMO','XXXXXX','2153',15133,'Installations à caractère spécifique','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15136,'NSCF','IMMO','XXXXXX','2154',15133,'Matériel industriel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15137,'NSCF','IMMO','XXXXXX','2155',15133,'Outillage industriel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15138,'NSCF','IMMO','XXXXXX','2157',15133,'Agencements et aménagements des matériels et outillage industriels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15139,'NSCF','IMMO','XXXXXX','218',15102,'Autres immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15140,'NSCF','IMMO','XXXXXX','2181',15139,'Installations générales, agencements, aménagements divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15141,'NSCF','IMMO','XXXXXX','2182',15139,'Matériel de transport','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15142,'NSCF','IMMO','XXXXXX','2183',15139,'Matériel de bureau et matériel informatique','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15143,'NSCF','IMMO','XXXXXX','2184',15139,'Mobilier','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15144,'NSCF','IMMO','XXXXXX','2185',15139,'Cheptel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15145,'NSCF','IMMO','XXXXXX','2186',15139,'Emballages récupérables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15146,'NSCF','IMMO','XXXXXX','22',15090,'Immobilisations mises en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15147,'NSCF','IMMO','XXXXXX','221',15146,'Terrains en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15148,'NSCF','IMMO','XXXXXX','222',15146,'Agencements et aménagements de terrains en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15149,'NSCF','IMMO','XXXXXX','223',15146,'Constructions en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15150,'NSCF','IMMO','XXXXXX','225',15146,'Installations techniques en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15151,'NSCF','IMMO','XXXXXX','228',15146,'Autres immobilisations corporelles en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15152,'NSCF','IMMO','XXXXXX','229',15146,'Droits du concédant','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15153,'NSCF','IMMO','XXXXXX','23',15090,'Immobilisations en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15154,'NSCF','IMMO','XXXXXX','232',15153,'Immobilisations corporelles en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15155,'NSCF','IMMO','XXXXXX','2322',15154,'Agencements et aménagements de Terrains en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15156,'NSCF','IMMO','XXXXXX','2323',15154,'Constructions en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15157,'NSCF','IMMO','XXXXXX','2325',15154,'Installations techniques, matériel et outillage industriels en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15158,'NSCF','IMMO','XXXXXX','2328',15154,'Autres immobilisations corporelles en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15159,'NSCF','IMMO','XXXXXX','237',15153,'Immobilisations incorporelles en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15160,'NSCF','IMMO','XXXXXX','238',15153,'Avances et acomptes versés sur commandes d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15161,'NSCF','IMMO','XXXXXX','2382',15160,'Avances et acomptes versés sur commandes d''immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15162,'NSCF','IMMO','XXXXXX','2387',15160,'Avances et acomptes versés sur commandes d''immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15163,'NSCF','IMMO','XXXXXX','26',15090,'Participations et créances rattachées à des participations (entreprises associées)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15164,'NSCF','IMMO','XXXXXX','261',15163,'Titres de filiales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15165,'NSCF','IMMO','XXXXXX','2611',15164,'Actions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15166,'NSCF','IMMO','XXXXXX','2618',15164,'Autres titres','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15167,'NSCF','IMMO','XXXXXX','262',15163,'Autres titres de participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15168,'NSCF','IMMO','XXXXXX','265',15163,'Titres de participation évalués par équivalence','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15169,'NSCF','IMMO','XXXXXX','266',15163,'Créances rattachées à des participations groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15170,'NSCF','IMMO','XXXXXX','2661',15169,'Créances liées à des participations groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15171,'NSCF','IMMO','XXXXXX','2665',15169,'Versements représentatifs d''apports non capitalisés (appel de fonds)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15172,'NSCF','IMMO','XXXXXX','2666',15169,'Avances consolidables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15173,'NSCF','IMMO','XXXXXX','2668',15169,'Dividendes à percevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15174,'NSCF','IMMO','XXXXXX','267',15163,'Créances rattachées à des participations hors groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15175,'NSCF','IMMO','XXXXXX','2671',15174,'Créances liées à des participations hors groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15176,'NSCF','IMMO','XXXXXX','2675',15174,'Versements représentatifs d''apports non capitalisés (appel de fonds)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15177,'NSCF','IMMO','XXXXXX','2676',15174,'Avances consolidables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15178,'NSCF','IMMO','XXXXXX','2677',15174,'Autres créances rattachées à des participations hors groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15179,'NSCF','IMMO','XXXXXX','2678',15174,'Dividendes et intérêts à percevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15180,'NSCF','IMMO','XXXXXX','268',15163,'Créances rattachées à des sociétés en participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15181,'NSCF','IMMO','XXXXXX','2681',15180,'Principal','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15182,'NSCF','IMMO','XXXXXX','2688',15180,'Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15183,'NSCF','IMMO','XXXXXX','269',15163,'Versements restant à effectuer sur titres de participation non libérés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15184,'NSCF','IMMO','XXXXXX','27',15090,'Autres immobilisations financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15185,'NSCF','IMMO','XXXXXX','271',15184,'Titres immobilisés autres que les titres immobilisés de l''activité de portefeuille','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15186,'NSCF','IMMO','XXXXXX','2711',15185,'Actions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15187,'NSCF','IMMO','XXXXXX','2718',15185,'Autres titres','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15188,'NSCF','IMMO','XXXXXX','272',15184,'Titres représentatifs de droit de créance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15189,'NSCF','IMMO','XXXXXX','2721',15188,'Obligations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15190,'NSCF','IMMO','XXXXXX','2722',15188,'Bons','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15191,'NSCF','IMMO','XXXXXX','273',15184,'Titres immobilisés de l''activité de portefeuille','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15192,'NSCF','IMMO','XXXXXX','2731',15191,'Actions immobilisées de l''activité de portefeuille','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15193,'NSCF','IMMO','XXXXXX','2732',15191,'Obligations remboursables en actions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15194,'NSCF','IMMO','XXXXXX','2733',15191,'Obligations convertibles en actions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15195,'NSCF','IMMO','XXXXXX','274',15184,'Prêts et créances sur contrat de location – financement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15196,'NSCF','IMMO','XXXXXX','2741',15195,'Prêts participatifs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15197,'NSCF','IMMO','XXXXXX','2742',15195,'Prêts aux associés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15198,'NSCF','IMMO','XXXXXX','2743',15195,'Prêts au personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15199,'NSCF','IMMO','XXXXXX','2745',15195,'Créances sur contrat de location - financement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15200,'NSCF','IMMO','XXXXXX','2748',15195,'Autres prêts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15201,'NSCF','IMMO','XXXXXX','275',15184,'Dépôts et cautionnements versés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15202,'NSCF','IMMO','XXXXXX','2751',15201,'Dépôts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15203,'NSCF','IMMO','XXXXXX','2755',15201,'Cautionnements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15204,'NSCF','IMMO','XXXXXX','276',15184,'Autres créances immobilisées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15205,'NSCF','IMMO','XXXXXX','2761',15204,'Créances diverses','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15206,'NSCF','IMMO','XXXXXX','2768',15204,'Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15207,'NSCF','IMMO','XXXXXX','27682',15206,'Autres créances sur titres immobilisés (droit de créance)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15208,'NSCF','IMMO','XXXXXX','27684',15206,'Autres créances sur prêts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15209,'NSCF','IMMO','XXXXXX','27685',15206,'Autres créances sur dépôts et cautionnements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15210,'NSCF','IMMO','XXXXXX','27688',15206,'Autres créances sur créances diverses','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15211,'NSCF','IMMO','XXXXXX','279',15184,'Versements restant à effectuer sur titres immobilisés non libérés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15212,'NSCF','IMMO','XXXXXX','28',15090,'Amortissement des immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15213,'NSCF','IMMO','XXXXXX','280',15212,'Amortissement des immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15214,'NSCF','IMMO','XXXXXX','2803',15213,'Amortissement des frais de recherche et de développement immobilisables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15215,'NSCF','IMMO','XXXXXX','2804',15213,'Amortissement. des logiciels informatiques et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15216,'NSCF','IMMO','XXXXXX','2805',15213,'Amortissement concessions et droits similaires, brevets, licences, marques.','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15217,'NSCF','IMMO','XXXXXX','2807',15213,'Amortissement écart d''acquisition - Goodwill','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15218,'NSCF','IMMO','XXXXXX','2808',15213,'Amortissement autres immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15219,'NSCF','IMMO','XXXXXX','281',15212,'Amortissement des immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15220,'NSCF','IMMO','XXXXXX','2812',15219,'Amortissement des agencements et aménagement de terrains','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15221,'NSCF','IMMO','XXXXXX','2813',15219,'Amortissement des constructions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15222,'NSCF','IMMO','XXXXXX','2815',15219,'Amortissement des installations techniques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15223,'NSCF','IMMO','XXXXXX','2818',15219,'Amortissement des autres immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15224,'NSCF','IMMO','XXXXXX','282',15212,'Amortissement des immobilisations mises en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15225,'NSCF','IMMO','XXXXXX','29',15090,'Pertes de valeur sur immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15226,'NSCF','IMMO','XXXXXX','290',15225,'Pertes de valeur sur immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15227,'NSCF','IMMO','XXXXXX','2903',15226,'Pertes de valeurs sur frais de recherche et de développement immobilisables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15228,'NSCF','IMMO','XXXXXX','2904',15226,'Pertes de valeur sur logiciels informatiques et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15229,'NSCF','IMMO','XXXXXX','2905',15226,'Pertes de valeur sur concessions et droits similaires, brevets, licences, marques.','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15230,'NSCF','IMMO','XXXXXX','2907',15226,'Pertes de valeur sur écart d''acquisition – Goodwill','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15231,'NSCF','IMMO','XXXXXX','2908',15226,'Pertes de valeur sur autres immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15232,'NSCF','IMMO','XXXXXX','291',15225,'Pertes de valeurs sur immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15233,'NSCF','IMMO','XXXXXX','2912',15232,'Pertes de valeur sur agencements et aménagements de terrains','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15234,'NSCF','IMMO','XXXXXX','2913',15232,'Pertes de valeur sur constructions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15235,'NSCF','IMMO','XXXXXX','2915',15232,'Pertes de valeur sur installations techniques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15236,'NSCF','IMMO','XXXXXX','2918',15232,'Pertes de valeur sur autres immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15237,'NSCF','IMMO','XXXXXX','292',15225,'Pertes de valeur sur immobilisations mises en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15238,'NSCF','IMMO','XXXXXX','293',15225,'Pertes de valeur sur immobilisations en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15239,'NSCF','IMMO','XXXXXX','2931',15238,'Pertes de valeur sur immobilisations corporelles en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15240,'NSCF','IMMO','XXXXXX','2932',15238,'Pertes de valeur sur immobilisations incorporelles en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15241,'NSCF','IMMO','XXXXXX','296',15225,'Pertes de valeur sur participations et créances rattachées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15242,'NSCF','IMMO','XXXXXX','2961',15241,'Pertes de valeur sur titres de filiales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15243,'NSCF','IMMO','XXXXXX','2962',15241,'Pertes de valeur sur autres formes de participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15244,'NSCF','IMMO','XXXXXX','2965',15241,'Pertes de valeur sur titres de participations évalués par équivalence','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15245,'NSCF','IMMO','XXXXXX','2966',15241,'Pertes de valeur sur créances rattachées à des participations groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15246,'NSCF','IMMO','XXXXXX','2967',15241,'Pertes de valeur sur créances rattachées à des participations hors groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15247,'NSCF','IMMO','XXXXXX','2968',15241,'Pertes de valeur sur créances rattachées à des sociétés en participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15248,'NSCF','IMMO','XXXXXX','297',15225,'Pertes de valeur sur autres titres immobilisés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15249,'NSCF','IMMO','XXXXXX','2971',15248,'Pertes de valeur sur titres immobilisés autres que les titres immobilisés autres que TIAP (droits de propriété)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15250,'NSCF','IMMO','XXXXXX','2972',15248,'Pertes de valeur sur titres représentatifs de droit de créance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15251,'NSCF','IMMO','XXXXXX','2973',15248,'Pertes de valeur sur titres immobilisés de l''activité de portefeuille','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15252,'NSCF','IMMO','XXXXXX','2974',15248,'Pertes de valeur sur contrat de location – financement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15253,'NSCF','IMMO','XXXXXX','2975',15248,'Pertes de valeur sur dépôts et cautionnements versés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15254,'NSCF','IMMO','XXXXXX','2976',15248,'Pertes de valeur sur autres créances immobilisées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15255,'NSCF','IMMO','XXXXXX','298',15225,'Pertes de valeur sur autres instruments financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15256,'NSCF','STOCK','XXXXXX','3',0,'COMPTES DE STOCKS ET ENCOURS','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15257,'NSCF','STOCK','XXXXXX','30',15256,'Stocks de marchandises','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15258,'NSCF','STOCK','XXXXXX','31',15256,'Matières premières et fournitures','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15259,'NSCF','STOCK','XXXXXX','311',15258,'Matières (ou groupe) A','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15260,'NSCF','STOCK','XXXXXX','312',15258,'Matières (ou groupe) B','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15261,'NSCF','STOCK','XXXXXX','313',15258,'Matières ...','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15262,'NSCF','STOCK','XXXXXX','32',15256,'Autres approvisionnements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15263,'NSCF','STOCK','XXXXXX','321',15262,'Matières consommables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15264,'NSCF','STOCK','XXXXXX','322',15262,'Fournitures consommables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15265,'NSCF','STOCK','XXXXXX','326',15262,'Emballages','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15266,'NSCF','STOCK','XXXXXX','3261',15265,'Emballages perdus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15267,'NSCF','STOCK','XXXXXX','3265',15265,'Emballages récupérables non identifiables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15268,'NSCF','STOCK','XXXXXX','3267',15265,'Emballages à usage mixte','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15269,'NSCF','STOCK','XXXXXX','33',15256,'En-cours de production de biens','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15270,'NSCF','STOCK','XXXXXX','331',15269,'Produits en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15271,'NSCF','STOCK','XXXXXX','335',15269,'Travaux en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15272,'NSCF','STOCK','XXXXXX','34',15256,'En-cours de production de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15273,'NSCF','STOCK','XXXXXX','341',15272,'Etudes en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15274,'NSCF','STOCK','XXXXXX','345',15272,'Prestations de services en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15275,'NSCF','STOCK','XXXXXX','35',15256,'Stocks de produits','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15276,'NSCF','STOCK','XXXXXX','351',15275,'Produits intermédiaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15277,'NSCF','STOCK','XXXXXX','355',15275,'Produits finis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15278,'NSCF','STOCK','XXXXXX','358',15275,'Produits résiduels ou matières de récupération','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15279,'NSCF','STOCK','XXXXXX','3581',15278,'Déchets','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15280,'NSCF','STOCK','XXXXXX','3585',15278,'Rebuts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15281,'NSCF','STOCK','XXXXXX','3586',15278,'Matières de récupération','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15282,'NSCF','STOCK','XXXXXX','36',15256,'Stocks provenant d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15283,'NSCF','STOCK','XXXXXX','37',15256,'Stocks à l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15284,'NSCF','STOCK','XXXXXX','370',15283,'Stocks de marchandises l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15285,'NSCF','STOCK','XXXXXX','3700',15284,'Stocks en cours de route','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15286,'NSCF','STOCK','XXXXXX','3701',15284,'Stocks de marchandises en dépôt à l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15287,'NSCF','STOCK','XXXXXX','3702',15284,'Stocks de marchandises en consignation à l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15288,'NSCF','STOCK','XXXXXX','371',15283,'Stocks de matières premières et fournitures à l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15289,'NSCF','STOCK','XXXXXX','375',15283,'Stocks de produits à l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15290,'NSCF','STOCK','XXXXXX','38',15256,'Achats stockés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15291,'NSCF','STOCK','XXXXXX','380',15290,'Marchandises stockées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15292,'NSCF','STOCK','XXXXXX','381',15290,'Matières premières et fournitures stockées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15293,'NSCF','STOCK','XXXXXX','382',15290,'Autres approvisionnements stockés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15294,'NSCF','STOCK','XXXXXX','39',15256,'Pertes de valeur sur stocks et en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15295,'NSCF','STOCK','XXXXXX','390',15294,'Pertes de valeur sur stocks de marchandises','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15296,'NSCF','STOCK','XXXXXX','391',15294,'Pertes de valeur sur matières premières et fournitures de biens','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15297,'NSCF','STOCK','XXXXXX','392',15294,'Pertes de valeur sur autres approvisionnements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15298,'NSCF','STOCK','XXXXXX','393',15294,'Pertes de valeur sur en-cours de production de de biens','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15299,'NSCF','STOCK','XXXXXX','394',15294,'Pertes de valeur sur en-cours de production de de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15300,'NSCF','STOCK','XXXXXX','395',15294,'Pertes de valeur sur stocks de produits','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15301,'NSCF','STOCK','XXXXXX','397',15294,'Pertes de valeur sur stocks à l''extérieur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15302,'NSCF','THIRDPARTY','XXXXXX','4',0,'COMPTES DE TIERS','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15303,'NSCF','THIRDPARTY','XXXXXX','40',15302,'Fournisseurs et comptes rattachés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15304,'NSCF','THIRDPARTY','XXXXXX','401',15303,'Fournisseurs de stocks et services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15305,'NSCF','THIRDPARTY','XXXXXX','4011',15304,'Fournisseurs - Achats de biens et prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15306,'NSCF','THIRDPARTY','XXXXXX','4017',15304,'Fournisseurs - Retenues de garantie','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15307,'NSCF','THIRDPARTY','XXXXXX','403',15303,'Fournisseurs - Effets à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15308,'NSCF','THIRDPARTY','XXXXXX','404',15303,'Fournisseurs d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15309,'NSCF','THIRDPARTY','XXXXXX','4041',15308,'Fournisseurs - Achats d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15310,'NSCF','THIRDPARTY','XXXXXX','4047',15308,'Fournisseurs d''immobilisations – Retenues de garantie','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15311,'NSCF','THIRDPARTY','XXXXXX','405',15303,'Fournisseurs d''immobilisations - Effets à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15312,'NSCF','THIRDPARTY','XXXXXX','408',15303,'Fournisseurs - factures non parvenues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15313,'NSCF','THIRDPARTY','XXXXXX','4081',15312,'Fournisseurs de stocks - Factures non parvenues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15314,'NSCF','THIRDPARTY','XXXXXX','4084',15312,'Fournisseurs d''immobilisations – Factures non parvenues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15315,'NSCF','THIRDPARTY','XXXXXX','4088',15312,'Fournisseurs - Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15316,'NSCF','THIRDPARTY','XXXXXX','409',15303,'Fournisseurs débiteurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15317,'NSCF','THIRDPARTY','XXXXXX','4091',15316,'Fournisseurs - Avances et acomptes versés sur commandes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15318,'NSCF','THIRDPARTY','XXXXXX','4096',15316,'Fournisseurs - Créances pour emballages et matériel à rendre ','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15319,'NSCF','THIRDPARTY','XXXXXX','4097',15316,'Fournisseurs - Autres avoirs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15320,'NSCF','THIRDPARTY','XXXXXX','4098',15316,'Rabais, remises, ristournes à obtenir et autres avoirs non encore reçus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15321,'NSCF','THIRDPARTY','XXXXXX','41',15302,'Clients et comptes rattachés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15322,'NSCF','THIRDPARTY','XXXXXX','411',15321,'Clients','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15323,'NSCF','THIRDPARTY','XXXXXX','4111',15322,'Clients - Ventes de biens ou de prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15324,'NSCF','THIRDPARTY','XXXXXX','4117',15322,'Clients - Retenues de garantie','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15325,'NSCF','THIRDPARTY','XXXXXX','413',15321,'Clients - Effets à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15326,'NSCF','THIRDPARTY','XXXXXX','416',15321,'Clients douteux (litigieux)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15327,'NSCF','THIRDPARTY','XXXXXX','417',15321,'Créances sur travaux ou prestations en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15328,'NSCF','THIRDPARTY','XXXXXX','418',15321,'Clients - Produits non encore facturés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15329,'NSCF','THIRDPARTY','XXXXXX','4181',15328,'Clients - Factures à établir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15330,'NSCF','THIRDPARTY','XXXXXX','4188',15328,'Clients - Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15331,'NSCF','THIRDPARTY','XXXXXX','419',15321,'Clients créditeurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15332,'NSCF','THIRDPARTY','XXXXXX','4191',15331,'Clients - Avances et acomptes reçus sur commandes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15333,'NSCF','THIRDPARTY','XXXXXX','4196',15331,'Clients - Dettes sur emballages et matériels consignés autres avoirs à établir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15334,'NSCF','THIRDPARTY','XXXXXX','4197',15331,'Clients - Autres avoirs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15335,'NSCF','THIRDPARTY','XXXXXX','4198',15331,'Rabais, remises, ristournes à accorder et','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15336,'NSCF','THIRDPARTY','XXXXXX','42',15302,'Personnel et comptes rattachés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15337,'NSCF','THIRDPARTY','XXXXXX','421',15336,'Personnel - Rémunérations dues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15338,'NSCF','THIRDPARTY','XXXXXX','422',15336,'Fonds des œuvres sociales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15339,'NSCF','THIRDPARTY','XXXXXX','423',15336,'Participation des salariés aux résultats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15340,'NSCF','THIRDPARTY','XXXXXX','425',15336,'Personnel - Avances et acomptes accordés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15341,'NSCF','THIRDPARTY','XXXXXX','426',15336,'Personnel - Dépôts reçus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15342,'NSCF','THIRDPARTY','XXXXXX','427',15336,'Personnel - Oppositions sur salaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15343,'NSCF','THIRDPARTY','XXXXXX','428',15336,'Personnel - Charges à payer et produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15344,'NSCF','THIRDPARTY','XXXXXX','4286',15343,'Personnel, charges à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15345,'NSCF','THIRDPARTY','XXXXXX','4287',15343,'Personnel, produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15346,'NSCF','THIRDPARTY','XXXXXX','43',15302,'Organismes sociaux et comptes rattachés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15347,'NSCF','THIRDPARTY','XXXXXX','431',15346,'Sécurité sociale','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15348,'NSCF','THIRDPARTY','XXXXXX','432',15346,'Autres organismes sociaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15349,'NSCF','THIRDPARTY','XXXXXX','438',15346,'Organismes sociaux - Charges à payer et produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15350,'NSCF','THIRDPARTY','XXXXXX','4386',15349,'Organismes sociaux, charges à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15351,'NSCF','THIRDPARTY','XXXXXX','4387',15349,'Organismes sociaux, produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15352,'NSCF','THIRDPARTY','XXXXXX','44',15302,'État, collectivités publiques, organismes internationaux et comptes rattachés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15353,'NSCF','THIRDPARTY','XXXXXX','441',15352,'État et collectivités publiques, subventions à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15354,'NSCF','THIRDPARTY','XXXXXX','4411',15353,'Subventions d''investissement à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15355,'NSCF','THIRDPARTY','XXXXXX','4417',15353,'Subventions d''exploitation à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15356,'NSCF','THIRDPARTY','XXXXXX','4418',15353,'Subventions d''équilibre à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15357,'NSCF','THIRDPARTY','XXXXXX','4419',15353,'Avances sur subventions à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15358,'NSCF','THIRDPARTY','XXXXXX','442',15352,'Impôts et taxes recouvrables sur des tiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15359,'NSCF','THIRDPARTY','XXXXXX','443',15352,'Opérations particulières avec l''Etat et les collectivités publiques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15360,'NSCF','THIRDPARTY','XXXXXX','444',15352,'Etat - Impôts sur les résultats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15361,'NSCF','THIRDPARTY','XXXXXX','445',15352,'Etat - Taxes sur le chiffre d''affaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15362,'NSCF','THIRDPARTY','XXXXXX','4451',15361,'Taxes sur le chiffre d''affaires à décaisser','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15363,'NSCF','THIRDPARTY','XXXXXX','44511',15362,'T.V.A. à décaisser','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15364,'NSCF','THIRDPARTY','XXXXXX','44518',15362,'Autres taxes assimilées à décaisser','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15365,'NSCF','THIRDPARTY','XXXXXX','4456',15361,'Taxes sur le chiffre d''affaires déductibles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15366,'NSCF','THIRDPARTY','XXXXXX','44562',15365,'T.V.A. sur immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15367,'NSCF','THIRDPARTY','XXXXXX','44566',15365,'T.V.A. sur autres biens et services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15368,'NSCF','THIRDPARTY','XXXXXX','44567',15365,'Crédit de T.V.A. à reporter','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15369,'NSCF','THIRDPARTY','XXXXXX','4457',15361,'Taxes sur le chiffre d''affaires collectées par l''entreprise','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15370,'NSCF','THIRDPARTY','XXXXXX','44571',15369,'T.V.A. collectée','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15371,'NSCF','THIRDPARTY','XXXXXX','44578',15369,'Autres taxes collectée assimilées à la T.V.A.','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15372,'NSCF','THIRDPARTY','XXXXXX','4458',15361,'Taxes sur le chiffre d''affaires à régulariser ou en attente','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15373,'NSCF','THIRDPARTY','XXXXXX','44586',15372,'Taxes sur le chiffre d''affaires sur factures non parvenues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15374,'NSCF','THIRDPARTY','XXXXXX','44587',15372,'Taxes sur le chiffre d''affaires sur factures à établir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15375,'NSCF','THIRDPARTY','XXXXXX','446',15352,'Organismes internationaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15376,'NSCF','THIRDPARTY','XXXXXX','447',15352,'Autres impôts, taxes et versements assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15377,'NSCF','THIRDPARTY','XXXXXX','448',15352,'Etat - Charges à payer et produits à recevoir (hors impôts)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15378,'NSCF','THIRDPARTY','XXXXXX','4486',15377,'Etat, charges à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15379,'NSCF','THIRDPARTY','XXXXXX','4487',15377,'Etat, produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15380,'NSCF','THIRDPARTY','XXXXXX','4488',15377,'Obligations cautionnées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15381,'NSCF','THIRDPARTY','XXXXXX','45',15302,'Groupe et associés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15382,'NSCF','THIRDPARTY','XXXXXX','451',15381,'Opérations groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15383,'NSCF','THIRDPARTY','XXXXXX','4510',15382,'Groupe, avances accordées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15384,'NSCF','THIRDPARTY','XXXXXX','4511',15382,'Groupe, avances reçues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15385,'NSCF','THIRDPARTY','XXXXXX','455',15381,'Associés - Comptes courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15386,'NSCF','THIRDPARTY','XXXXXX','4551',15385,'Principal','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15387,'NSCF','THIRDPARTY','XXXXXX','4558',15385,'Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15388,'NSCF','THIRDPARTY','XXXXXX','456',15381,'Associés - Opérations sur le capital','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15389,'NSCF','THIRDPARTY','XXXXXX','4561',15388,'Associés - Comptes d''apport en société','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15390,'NSCF','THIRDPARTY','XXXXXX','45611',15389,'Apports en nature','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15391,'NSCF','THIRDPARTY','XXXXXX','45615',15389,'Apports en numéraire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15392,'NSCF','THIRDPARTY','XXXXXX','4562',15388,'Apporteurs - Capital appelé, non versé','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15393,'NSCF','THIRDPARTY','XXXXXX','45621',15392,'Actionnaires - Capital souscrit et appelé, non versé','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15394,'NSCF','THIRDPARTY','XXXXXX','45625',15392,'Associés - Capital appelé, non versé','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15395,'NSCF','THIRDPARTY','XXXXXX','4563',15388,'Associés - versements reçus sur augmentation de capital','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15396,'NSCF','THIRDPARTY','XXXXXX','4564',15388,'Associés - Versements anticipés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15397,'NSCF','THIRDPARTY','XXXXXX','4566',15388,'Actionnaires défaillants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15398,'NSCF','THIRDPARTY','XXXXXX','4567',15388,'Associés - Capital à rembourser','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15399,'NSCF','THIRDPARTY','XXXXXX','457',15381,'Associés - Dividendes à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15400,'NSCF','THIRDPARTY','XXXXXX','458',15381,'Associés - Opérations faites en commun ou en groupement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15401,'NSCF','THIRDPARTY','XXXXXX','4581',15400,'Opérations courantes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15402,'NSCF','THIRDPARTY','XXXXXX','4588',15400,'Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15403,'NSCF','THIRDPARTY','XXXXXX','46',15302,'Débiteurs divers et créditeurs divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15404,'NSCF','THIRDPARTY','XXXXXX','462',15403,'Créances sur cessions d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15405,'NSCF','THIRDPARTY','XXXXXX','464',15403,'Dettes sur acquisitions valeurs mobilières de placement et instruments financiers dérivés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15406,'NSCF','THIRDPARTY','XXXXXX','465',15403,'Créances sur cessions valeurs mobilières de placement et instruments financiers dérivés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15407,'NSCF','THIRDPARTY','XXXXXX','467',15403,'Autres comptes débiteurs ou créditeurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15408,'NSCF','THIRDPARTY','XXXXXX','468',15403,'Diverses charges à payer et produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15409,'NSCF','THIRDPARTY','XXXXXX','4686',15408,'Diverses charges à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15410,'NSCF','THIRDPARTY','XXXXXX','4687',15408,'Divers produits à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15411,'NSCF','THIRDPARTY','XXXXXX','47',15302,'Comptes transitoires ou d''attente','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15412,'NSCF','THIRDPARTY','XXXXXX','471',15411,'Compte d''attente 1','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15413,'NSCF','THIRDPARTY','XXXXXX','472',15411,'Compte d''attente 2','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15414,'NSCF','THIRDPARTY','XXXXXX','473',15411,'Compte d''attente 3','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15415,'NSCF','THIRDPARTY','XXXXXX','474',15411,'Compte d''attente 4','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15416,'NSCF','THIRDPARTY','XXXXXX','475',15411,'Compte d''attente 5','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15417,'NSCF','THIRDPARTY','XXXXXX','476',15411,'Différence de conversion - Actif','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15418,'NSCF','THIRDPARTY','XXXXXX','4761',15417,'Diminution des créances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15419,'NSCF','THIRDPARTY','XXXXXX','4762',15417,'Augmentation des dettes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15420,'NSCF','THIRDPARTY','XXXXXX','4768',15417,'Différences compensées par couverture de change','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15421,'NSCF','THIRDPARTY','XXXXXX','477',15411,'Différences de conversion - Passif','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15422,'NSCF','THIRDPARTY','XXXXXX','4771',15421,'Augmentation des créances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15423,'NSCF','THIRDPARTY','XXXXXX','4772',15421,'Diminution des dettes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15424,'NSCF','THIRDPARTY','XXXXXX','4778',15421,'Différences compensées par couverture de change','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15425,'NSCF','THIRDPARTY','XXXXXX','478',15411,'Autres comptes transitoires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15426,'NSCF','THIRDPARTY','XXXXXX','48',15302,'Charges ou produits constatés d''avance et provisions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15427,'NSCF','THIRDPARTY','XXXXXX','481',15426,'Provisions, passifs courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15428,'NSCF','THIRDPARTY','XXXXXX','486',15426,'Charges constatées d''avance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15429,'NSCF','THIRDPARTY','XXXXXX','487',15426,'Produits constatés d''avance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15430,'NSCF','THIRDPARTY','XXXXXX','49',15302,'Pertes de valeur sur comptes de tiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15431,'NSCF','THIRDPARTY','XXXXXX','491',15430,'Pertes de valeur sur comptes de clients','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15432,'NSCF','THIRDPARTY','XXXXXX','495',15430,'Pertes de valeur sur comptes du groupe et sur associés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15433,'NSCF','THIRDPARTY','XXXXXX','4951',15432,'Pertes de valeur sur comptes du groupe','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15434,'NSCF','THIRDPARTY','XXXXXX','4955',15432,'Pertes de valeur sur comptes courants des associés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15435,'NSCF','THIRDPARTY','XXXXXX','496',15430,'Pertes de valeur sur comptes de débiteurs divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15436,'NSCF','THIRDPARTY','XXXXXX','4962',15435,'Créances sur cessions d''immobilisations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15437,'NSCF','THIRDPARTY','XXXXXX','4965',15435,'Créances sur cessions de valeurs mobilières de placement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15438,'NSCF','THIRDPARTY','XXXXXX','4967',15435,'Autres comptes débiteurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15439,'NSCF','THIRDPARTY','XXXXXX','498',15430,'Pertes de valeur sur comptes de débiteurs divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15440,'NSCF','FINAN','XXXXXX','5',0,'COMPTES FINANCIERS','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15441,'NSCF','FINAN','XXXXXX','50',15440,'Valeurs mobilières de placement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15442,'NSCF','FINAN','XXXXXX','501',15441,'Parts dans des entreprises liées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15443,'NSCF','FINAN','XXXXXX','502',15441,'Actions propres','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15444,'NSCF','FINAN','XXXXXX','503',15441,'Autres actions ou titres conférant un droit de propriété','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15445,'NSCF','FINAN','XXXXXX','5031',15444,'Titres cotés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15446,'NSCF','FINAN','XXXXXX','5032',15444,'Titres non cotés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15447,'NSCF','FINAN','XXXXXX','506',15441,'Obligations, bons du Trésor et bons de caisse à court terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15448,'NSCF','FINAN','XXXXXX','5061',15447,'Obligations à court termes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15449,'NSCF','FINAN','XXXXXX','5062',15447,'Bons du trésor à court terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15450,'NSCF','FINAN','XXXXXX','5063',15447,'Bons de caisse à court terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15451,'NSCF','FINAN','XXXXXX','508',15441,'Autres valeurs mobilières de placement et créances assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15452,'NSCF','FINAN','XXXXXX','5088',15451,'Autres valeurs mobilières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15453,'NSCF','FINAN','XXXXXX','5082',15451,'Bons de souscription','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15454,'NSCF','FINAN','XXXXXX','5083',15451,'Intérêts courus sur obligations, bons et valeurs assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15455,'NSCF','FINAN','XXXXXX','509',15441,'Versements restant à effectuer sur valeurs mobilières de placement non libérées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15456,'NSCF','FINAN','XXXXXX','51',15440,'Banques, établissements financiers et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15457,'NSCF','FINAN','XXXXXX','511',15456,'Valeurs à l''encaissement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15458,'NSCF','FINAN','XXXXXX','5111',15457,'Coupons échus à l''encaissement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15459,'NSCF','FINAN','XXXXXX','5112',15457,'Chèques à encaisser','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15460,'NSCF','FINAN','XXXXXX','5113',15457,'Effets à l''encaissement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15461,'NSCF','FINAN','XXXXXX','5114',15457,'Effets à l''escompte','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15462,'NSCF','FINAN','XXXXXX','5115',15457,'Cartes bancaires à l''encaissement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15463,'NSCF','FINAN','XXXXXX','512',15456,'Banques comptes courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15464,'NSCF','FINAN','XXXXXX','514',15456,'Chèques postaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15465,'NSCF','FINAN','XXXXXX','515',15456,'Caisses du Trésor et des établissements publics','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15466,'NSCF','FINAN','XXXXXX','516',15456,'Sociétés de bourse','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15467,'NSCF','FINAN','XXXXXX','517',15456,'Autres organismes financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15468,'NSCF','FINAN','XXXXXX','518',15456,'Intérêts courus','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15469,'NSCF','FINAN','XXXXXX','5181',15468,'Intérêts courus à payer','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15470,'NSCF','FINAN','XXXXXX','5188',15468,'Intérêts courus à recevoir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15471,'NSCF','FINAN','XXXXXX','519',15456,'Concours bancaires courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15472,'NSCF','FINAN','XXXXXX','5191',15471,'Crédit de mobilisation de créances commerciales (CMCC)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15473,'NSCF','FINAN','XXXXXX','5192',15471,'Crédit documentaire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15474,'NSCF','FINAN','XXXXXX','5193',15471,'Mobilisation de créances nées à l''étranger','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15475,'NSCF','FINAN','XXXXXX','5198',15471,'Intérêts courus sur concours bancaires courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15476,'NSCF','FINAN','XXXXXX','52',15440,'Instruments de trésorerie','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15477,'NSCF','FINAN','XXXXXX','53',15440,'Caisse','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15478,'NSCF','FINAN','XXXXXX','54',15440,'Régies d''avance et accréditifs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15479,'NSCF','FINAN','XXXXXX','541',15478,'Régie d''avance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15480,'NSCF','FINAN','XXXXXX','542',15478,'Accréditifs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15481,'NSCF','FINAN','XXXXXX','58',15440,'Virements internes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15482,'NSCF','FINAN','XXXXXX','581',15481,'Virements de fonds','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15483,'NSCF','FINAN','XXXXXX','588',15481,'Autres virements internes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15484,'NSCF','FINAN','XXXXXX','59',15440,'Pertes de valeur des actifs financiers courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15485,'NSCF','FINAN','XXXXXX','591',15484,'Pertes de valeur des dépôts en banque et autres établissements financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15486,'NSCF','FINAN','XXXXXX','594',15484,'Pertes de valeur sur des régies d''avance et accréditifs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15487,'NSCF','EXPENSE','XXXXXX','6',0,'COMPTES DE CHARGES','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15488,'NSCF','EXPENSE','XXXXXX','60',15487,'Achats consommées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15489,'NSCF','EXPENSE','XXXXXX','600',15488,'Achats de marchandises vendues','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15490,'NSCF','EXPENSE','XXXXXX','601',15488,'Matières premières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15491,'NSCF','EXPENSE','XXXXXX','602',15488,'Autres approvisionnements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15492,'NSCF','EXPENSE','XXXXXX','603',15488,'Variations des stocks ','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15493,'NSCF','EXPENSE','XXXXXX','6030',15492,'Variations des stocks de marchandises','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15494,'NSCF','EXPENSE','XXXXXX','6031',15492,'Variations des stocks de matières premières et fournitures','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15495,'NSCF','EXPENSE','XXXXXX','6032',15492,'Variations des stocks d''autres approvisionnements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15496,'NSCF','EXPENSE','XXXXXX','604',15488,'Achats d''études  et prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15497,'NSCF','EXPENSE','XXXXXX','605',15488,'Achats de matériel, équipements et travaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15498,'NSCF','EXPENSE','XXXXXX','607',15488,'Achats non stockés de matière et fournitures','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15499,'NSCF','EXPENSE','XXXXXX','6071',15498,'Fournitures non stockables (eau, énergie)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15500,'NSCF','EXPENSE','XXXXXX','6073',15498,'Fournitures d''entretien et de petit équipement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15501,'NSCF','EXPENSE','XXXXXX','6074',15498,'Fournitures administratives','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15502,'NSCF','EXPENSE','XXXXXX','6078',15498,'Autres matières et fournitures','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15503,'NSCF','EXPENSE','XXXXXX','608',15488,'Frais accessoires sur achats (FAA)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15504,'NSCF','EXPENSE','XXXXXX','609',15488,'Rabais, remises et ristournes obtenus sur achats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15505,'NSCF','EXPENSE','XXXXXX','61',15487,'Services extérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15506,'NSCF','EXPENSE','XXXXXX','611',15505,'Sous-traitance générale','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15507,'NSCF','EXPENSE','XXXXXX','613',15505,'Locations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15508,'NSCF','EXPENSE','XXXXXX','6132',15507,'Locations immobilières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15509,'NSCF','EXPENSE','XXXXXX','6135',15507,'Locations mobilières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15510,'NSCF','EXPENSE','XXXXXX','6136',15507,'Malis sur emballages','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15511,'NSCF','EXPENSE','XXXXXX','614',15505,'Charges locatives et charges de copropriété','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15512,'NSCF','EXPENSE','XXXXXX','615',15505,'Entretien, réparations et maintenance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15513,'NSCF','EXPENSE','XXXXXX','6152',15512,'Sur biens immobiliers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15514,'NSCF','EXPENSE','XXXXXX','6155',15512,'Sur biens mobiliers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15515,'NSCF','EXPENSE','XXXXXX','6156',15512,'Maintenance','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15516,'NSCF','EXPENSE','XXXXXX','616',15505,'Primes d''assurances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15517,'NSCF','EXPENSE','XXXXXX','6161',15516,'Multirisques','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15518,'NSCF','EXPENSE','XXXXXX','6162',15516,'Assurance obligatoire dommage construction','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15519,'NSCF','EXPENSE','XXXXXX','6163',15516,'Assurance-transport','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15520,'NSCF','EXPENSE','XXXXXX','61636',15519,'sur achats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15521,'NSCF','EXPENSE','XXXXXX','61637',15519,'sur ventes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15522,'NSCF','EXPENSE','XXXXXX','61638',15519,'sur autres biens','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15523,'NSCF','EXPENSE','XXXXXX','6166',15516,'Assurances véhicules','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15524,'NSCF','EXPENSE','XXXXXX','6168',15516,'Autres assurances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15525,'NSCF','EXPENSE','XXXXXX','617',15505,'Etudes et recherches','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15526,'NSCF','EXPENSE','XXXXXX','618',15505,'Documentation et divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15527,'NSCF','EXPENSE','XXXXXX','6181',15526,'Documentation générale','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15528,'NSCF','EXPENSE','XXXXXX','6183',15526,'Documentation technique','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15529,'NSCF','EXPENSE','XXXXXX','6185',15526,'Frais de colloques, séminaires, conférences','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15530,'NSCF','EXPENSE','XXXXXX','619',15505,'Rabais, remises et ristournes obtenus sur services extérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15531,'NSCF','EXPENSE','XXXXXX','62',15487,'Autres services extérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15532,'NSCF','EXPENSE','XXXXXX','621',15531,'Personnel extérieur à l''entreprise','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15533,'NSCF','EXPENSE','XXXXXX','6211',15532,'Personnel intérimaire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15534,'NSCF','EXPENSE','XXXXXX','6214',15532,'Personnel détaché ou prêté à l''entreprise','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15535,'NSCF','EXPENSE','XXXXXX','622',15531,'Rémunérations d''intermédiaires et honoraires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15536,'NSCF','EXPENSE','XXXXXX','6221',15535,'Commissions et courtages sur achats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15537,'NSCF','EXPENSE','XXXXXX','6222',15535,'Commissions et courtages sur ventes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15538,'NSCF','EXPENSE','XXXXXX','6224',15535,'Rémunérations des transitaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15539,'NSCF','EXPENSE','XXXXXX','6225',15535,'Rémunérations d''affacturage (mémoire)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15540,'NSCF','EXPENSE','XXXXXX','6226',15535,'Honoraires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15541,'NSCF','EXPENSE','XXXXXX','6227',15535,'Frais d''actes et de contentieux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15542,'NSCF','EXPENSE','XXXXXX','6228',15535,'Divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15543,'NSCF','EXPENSE','XXXXXX','624',15531,'Transports de biens et transports collectifs du personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15544,'NSCF','EXPENSE','XXXXXX','6241',15543,'Transports sur achats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15545,'NSCF','EXPENSE','XXXXXX','6242',15543,'Transports sur ventes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15546,'NSCF','EXPENSE','XXXXXX','6243',15543,'Transports entre établissements ou chantiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15547,'NSCF','EXPENSE','XXXXXX','6244',15543,'Transports administratifs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15548,'NSCF','EXPENSE','XXXXXX','6247',15543,'Transports collectifs du personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15549,'NSCF','EXPENSE','XXXXXX','6248',15543,'Divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15550,'NSCF','EXPENSE','XXXXXX','625',15531,'Déplacements, missions et réceptions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15551,'NSCF','EXPENSE','XXXXXX','6251',15550,'Voyages et déplacements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15552,'NSCF','EXPENSE','XXXXXX','6255',15550,'Frais de déménagement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15553,'NSCF','EXPENSE','XXXXXX','6256',15550,'Missions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15554,'NSCF','EXPENSE','XXXXXX','6257',15550,'Réceptions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15555,'NSCF','EXPENSE','XXXXXX','626',15531,'Frais postaux et de télécommunications','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15556,'NSCF','EXPENSE','XXXXXX','627',15531,'Services bancaires et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15557,'NSCF','EXPENSE','XXXXXX','6271',15556,'Frais sur titres (achat, vente, garde)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15558,'NSCF','EXPENSE','XXXXXX','6272',15556,'Commissions et frais sur émission d''emprunts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15559,'NSCF','EXPENSE','XXXXXX','6275',15556,'Frais sur effets','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15560,'NSCF','EXPENSE','XXXXXX','6276',15556,'Location de coffres','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15561,'NSCF','EXPENSE','XXXXXX','6278',15556,'Autres frais et commissions sur prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15562,'NSCF','EXPENSE','XXXXXX','628',15531,'Cotisations et divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15563,'NSCF','EXPENSE','XXXXXX','6281',15562,'Concours divers (cotisations)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15564,'NSCF','EXPENSE','XXXXXX','6284',15562,'Frais de recrutement de personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15565,'NSCF','EXPENSE','XXXXXX','629',15531,'Rabais, remises et ristournes obtenus sur autres services extérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15566,'NSCF','EXPENSE','XXXXXX','63',15487,'Charges de personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15567,'NSCF','EXPENSE','XXXXXX','631',15566,'Rémunérations du personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15568,'NSCF','EXPENSE','XXXXXX','6311',15567,'Salaires, appointements','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15569,'NSCF','EXPENSE','XXXXXX','6312',15567,'Congés payés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15570,'NSCF','EXPENSE','XXXXXX','6313',15567,'Primes et gratifications','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15571,'NSCF','EXPENSE','XXXXXX','6314',15567,'Indemnités et avantages divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15572,'NSCF','EXPENSE','XXXXXX','6316',15567,'Contributions aux œuvres sociales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15573,'NSCF','EXPENSE','XXXXXX','634',15566,'Rémunération de l''exploitant individuel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15574,'NSCF','EXPENSE','XXXXXX','635',15566,'Cotisations aux organismes sociaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15575,'NSCF','EXPENSE','XXXXXX','6351',15574,'Cotisations CNAS','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15576,'NSCF','EXPENSE','XXXXXX','6352',15574,'Cotisations aux mutuelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15577,'NSCF','EXPENSE','XXXXXX','6353',15574,'Cotisations aux caisses de retraites','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15578,'NSCF','EXPENSE','XXXXXX','6358',15574,'Cotisations aux autres organismes sociaux (CACOBATH)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15579,'NSCF','EXPENSE','XXXXXX','636',15566,'Charges sociales de l''exploitant individuel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15580,'NSCF','EXPENSE','XXXXXX','637',15566,'Autres charges sociales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15581,'NSCF','EXPENSE','XXXXXX','6371',15580,'Prestations directes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15582,'NSCF','EXPENSE','XXXXXX','6372',15580,'Versements aux comités d''entreprise et d''établissement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15583,'NSCF','EXPENSE','XXXXXX','6374',15580,'Versements aux autres œuvres sociales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15584,'NSCF','EXPENSE','XXXXXX','6375',15580,'Médecine du travail, pharmacie','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15585,'NSCF','EXPENSE','XXXXXX','638',15566,'Autres charges de personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15586,'NSCF','EXPENSE','XXXXXX','64',15487,'Impôts, taxes et versements assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15587,'NSCF','EXPENSE','XXXXXX','641',15586,'Impôts, taxes et versements assimilés sur rémunérations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15588,'NSCF','EXPENSE','XXXXXX','6411',15587,'Taxe sur les salaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15589,'NSCF','EXPENSE','XXXXXX','6413',15587,'Participation des employeurs à la formation professionnelle','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15590,'NSCF','EXPENSE','XXXXXX','6418',15587,'Autres impôts, taxes et versements assimilés sur rémunérations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15591,'NSCF','EXPENSE','XXXXXX','642',15586,'Impôts et taxes non récupérables sur le chiffre d''affaire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15592,'NSCF','EXPENSE','XXXXXX','6421',15591,'Taxe sur l''activité professionnelle (TAP)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15593,'NSCF','EXPENSE','XXXXXX','6422',15591,'TVA non récupérable','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15594,'NSCF','EXPENSE','XXXXXX','6423',15591,'Droits de timbre et d''enregistrement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15595,'NSCF','EXPENSE','XXXXXX','6428',15591,'Autres impôts et taxes non récupérables sur le chiffre d''affaire','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15596,'NSCF','EXPENSE','XXXXXX','645',15586,'Autres impôts et taxes (hors impôts sur le résultat)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15597,'NSCF','EXPENSE','XXXXXX','6451',15596,'Taxe foncière','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15598,'NSCF','EXPENSE','XXXXXX','6452',15596,'Taxe d''assainissement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15599,'NSCF','EXPENSE','XXXXXX','6453',15596,'Droits de douane','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15600,'NSCF','EXPENSE','XXXXXX','6454',15596,'Vignettes automobiles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15601,'NSCF','EXPENSE','XXXXXX','6456',15596,'Taxe écologique','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15602,'NSCF','EXPENSE','XXXXXX','6458',15596,'Autres droits et taxes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15603,'NSCF','EXPENSE','XXXXXX','65',15487,'Autres charges opérationnelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15604,'NSCF','EXPENSE','XXXXXX','651',15603,'Redevances pour concessions, brevets, licences, logiciels et accès similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15605,'NSCF','EXPENSE','XXXXXX','6511',15604,'Redevances pour concessions, brevets, licences, marques, procédés, logiciels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15606,'NSCF','EXPENSE','XXXXXX','6516',15604,'Droits d''auteur et de reproduction','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15607,'NSCF','EXPENSE','XXXXXX','6518',15604,'Autres droits et valeurs similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15608,'NSCF','EXPENSE','XXXXXX','652',15603,'Moins-values sur sorties d''actifs immobilisés non financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15609,'NSCF','EXPENSE','XXXXXX','653',15603,'Jetons de présence','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15610,'NSCF','EXPENSE','XXXXXX','654',15603,'Pertes sur créances irrécouvrables','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15611,'NSCF','EXPENSE','XXXXXX','6541',15610,'Pertes sur créances de l''exercice','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15612,'NSCF','EXPENSE','XXXXXX','6544',15610,'Pertes sur créances des exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15613,'NSCF','EXPENSE','XXXXXX','655',15603,'Quote-part de résultat sur opérations faites en commun','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15614,'NSCF','EXPENSE','XXXXXX','6551',15613,'Quote-part de résultats de groupement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15615,'NSCF','EXPENSE','XXXXXX','6558',15613,'Amortissements de caducité des immobilisations mises en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15616,'NSCF','EXPENSE','XXXXXX','6559',15613,'Dotations aux provisions des immobilisations mises en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15617,'NSCF','EXPENSE','XXXXXX','656',15603,'Amendes et pénalités, subventions accordées dons et libéralités','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15618,'NSCF','EXPENSE','XXXXXX','6561',15617,'Amendes et pénalité','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15619,'NSCF','EXPENSE','XXXXXX','6562',15617,'Subventions accordées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15620,'NSCF','EXPENSE','XXXXXX','6563',15617,'Dons et libéralités','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15621,'NSCF','EXPENSE','XXXXXX','657',15603,'Charges exceptionnelles de gestion courante','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15622,'NSCF','EXPENSE','XXXXXX','658',15603,'Autres charges de gestion courante','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15623,'NSCF','EXPENSE','XXXXXX','66',15487,'Charges financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15624,'NSCF','EXPENSE','XXXXXX','661',15623,'Charges d''intérêts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15625,'NSCF','EXPENSE','XXXXXX','6611',15624,'Intérêts des emprunts et dettes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15626,'NSCF','EXPENSE','XXXXXX','66116',15625,'Intérêts des emprunts et dettes assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15627,'NSCF','EXPENSE','XXXXXX','66117',15625,'Intérêts des emprunts et  dettes rattachées à des participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15628,'NSCF','EXPENSE','XXXXXX','6615',15624,'Intérêts des comptes courants et des dépôts créditeurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15629,'NSCF','EXPENSE','XXXXXX','6616',15624,'Intérêts bancaires et sur opérations de financement (escompte,…)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15630,'NSCF','EXPENSE','XXXXXX','6617',15624,'Intérêts des obligations cautionnées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15631,'NSCF','EXPENSE','XXXXXX','6618',15624,'Intérêts des autres dettes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15632,'NSCF','EXPENSE','XXXXXX','66181',15631,'Intérêts des dettes commerciales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15633,'NSCF','EXPENSE','XXXXXX','66188',15631,'Intérêts des dettes diverses','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15634,'NSCF','EXPENSE','XXXXXX','664',15623,'Pertes sur créances liées à des participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15635,'NSCF','EXPENSE','XXXXXX','665',15623,'Ecarts d''évaluation sur actifs financiers – Moins-values','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15636,'NSCF','EXPENSE','XXXXXX','6651',15635,'Ecarts d''évaluation - moins-values sur des parts dans les entreprises liées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15637,'NSCF','EXPENSE','XXXXXX','6653',15635,'Ecarts d''évaluation - moins-values sur autres titres conférant un droit de propriété','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15638,'NSCF','EXPENSE','XXXXXX','6656',15635,'Ecarts d''évaluation - moins-values sur obligations, bons du trésor et bons de caisse à court terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15639,'NSCF','EXPENSE','XXXXXX','6658',15635,'Ecarts d''évaluation - moins-values sur autres valeurs mobilières et autres créances assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15640,'NSCF','EXPENSE','XXXXXX','666',15623,'Pertes de change','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15641,'NSCF','EXPENSE','XXXXXX','667',15623,'Pertes nettes sur cessions d''actifs financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15642,'NSCF','EXPENSE','XXXXXX','6671',15641,'Pertes nettes sur cession des parts dans les entreprises liées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15643,'NSCF','EXPENSE','XXXXXX','6672',15641,'Pertes nettes sur cession d''actions propres','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15644,'NSCF','EXPENSE','XXXXXX','6673',15641,'Pertes nettes sur cession d''autres titres conférant un droit de propriété','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15645,'NSCF','EXPENSE','XXXXXX','6676',15641,'Pertes nettes sur cession d''obligations, bons du trésor et bons de caisse à court terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15646,'NSCF','EXPENSE','XXXXXX','6678',15641,'Pertes nettes sur cession des autres valeurs mobilières et autres créances assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15647,'NSCF','EXPENSE','XXXXXX','668',15623,'Autres charges financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15648,'NSCF','EXPENSE','XXXXXX','67',15487,'Eléments extraordinaires - charges','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15649,'NSCF','EXPENSE','XXXXXX','672',15648,'Valeur résiduelle des immobilisations cédées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15650,'NSCF','EXPENSE','XXXXXX','676',15648,'Charges sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15651,'NSCF','EXPENSE','XXXXXX','6760',15650,'Consommations sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15652,'NSCF','EXPENSE','XXXXXX','6761',15650,'Services sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15653,'NSCF','EXPENSE','XXXXXX','6762',15650,'Autres services sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15654,'NSCF','EXPENSE','XXXXXX','6763',15650,'Charges de personnel sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15655,'NSCF','EXPENSE','XXXXXX','6764',15650,'Impôts et taxes sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15656,'NSCF','EXPENSE','XXXXXX','6765',15650,'Autres charges opérationnelles sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15657,'NSCF','EXPENSE','XXXXXX','6766',15650,'Charges financières sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15658,'NSCF','EXPENSE','XXXXXX','6768',15650,'Dotations aux amortissements, provisions et pertes de valeurs sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15659,'NSCF','EXPENSE','XXXXXX','6769',15650,'Impôts sur les bénéfices sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15660,'NSCF','EXPENSE','XXXXXX','678',15648,'Autres éléments extraordinaires - charges','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15661,'NSCF','EXPENSE','XXXXXX','6783',15660,'Malis provenant du rachat par l''entreprise d''actions et obligations émises par elle-même','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15662,'NSCF','EXPENSE','XXXXXX','6788',15660,'Autres charges extraordinaires diverses','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15663,'NSCF','EXPENSE','XXXXXX','68',15487,'Dotations aux amortissements, provisions et pertes de valeur','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15664,'NSCF','EXPENSE','XXXXXX','681',15663,'Dotations aux amortissements, provisions et pertes de valeur, actifs non courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15665,'NSCF','EXPENSE','XXXXXX','6811',15664,'Dotations aux amortissements, provisions et pertes de valeur sur immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15666,'NSCF','EXPENSE','XXXXXX','68111',15665,'Dotations aux amortissements et provisions et pertes de valeur sur immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15667,'NSCF','EXPENSE','XXXXXX','68112',15665,'Pertes de valeur sur immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15668,'NSCF','EXPENSE','XXXXXX','6812',15664,'Dotations aux amortissements, provisions et pertes de valeur sur immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15669,'NSCF','EXPENSE','XXXXXX','68121',15668,'Dotations aux amortissements et provisions et immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15670,'NSCF','EXPENSE','XXXXXX','68122',15668,'Pertes de valeur sur immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15671,'NSCF','EXPENSE','XXXXXX','68123',15668,'Pertes de valeur sur les investissements en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15672,'NSCF','EXPENSE','XXXXXX','68126',15668,'Pertes de valeur sur immobilisations financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15673,'NSCF','EXPENSE','XXXXXX','682',15663,'Dotations aux amortissements, provisions et pertes de valeur des biens mis en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15674,'NSCF','EXPENSE','XXXXXX','6821',15673,'Dotations aux amortissements, des biens mis en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15675,'NSCF','EXPENSE','XXXXXX','6822',15673,'Dotations aux provisions des biens mis-en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15676,'NSCF','EXPENSE','XXXXXX','6828',15673,'Pertes de valeur des biens mis en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15677,'NSCF','EXPENSE','XXXXXX','685',15663,'Dotations aux amortissements, provisions et pertes de valeur, actifs courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15678,'NSCF','EXPENSE','XXXXXX','6853',15677,'Dotations aux pertes de valeur sur stocks','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15679,'NSCF','EXPENSE','XXXXXX','6854',15677,'Dotations aux pertes de valeur sur créances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15680,'NSCF','EXPENSE','XXXXXX','6855',15677,'Dotations aux provisions et pertes de valeur sur comptes financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15681,'NSCF','EXPENSE','XXXXXX','686',15663,'Dotations aux amortissements, provisions et pertes de valeur, éléments financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15682,'NSCF','EXPENSE','XXXXXX','6861',15681,'Dotations aux amortissements des primes de remboursement des obligations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15683,'NSCF','EXPENSE','XXXXXX','6865',15681,'Dotations aux provisions pour risques et charges financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15684,'NSCF','EXPENSE','XXXXXX','6866',15681,'Dotations aux provisions pour dépréciations des éléments financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15685,'NSCF','EXPENSE','XXXXXX','68662',15684,'Dotations aux provisions pour dépréciations des immobilisations financières','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15686,'NSCF','EXPENSE','XXXXXX','68665',15684,'Dotations aux provisions pour les valeurs mobilières de placement','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15687,'NSCF','EXPENSE','XXXXXX','6868',15681,'Autres dotations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15688,'NSCF','EXPENSE','XXXXXX','69',15487,'Impôts sur les résultats et assimilés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15689,'NSCF','EXPENSE','XXXXXX','692',15688,'Imposition différée actif','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15690,'NSCF','EXPENSE','XXXXXX','693',15688,'Imposition différée passif','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15691,'NSCF','EXPENSE','XXXXXX','695',15688,'Impôts sur les bénéfices basés sur les résultats des activités ordinaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15692,'NSCF','EXPENSE','XXXXXX','698',15688,'Autres impôts sur les résultats','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15693,'NSCF','INCOME','XXXXXX','7',0,'COMPTES DE PRODUITS','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15694,'NSCF','INCOME','XXXXXX','70',15693,'Ventes de marchandises et de produits fabriqués, ventes de prestations de services et produits annexes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15695,'NSCF','INCOME','XXXXXX','700',15694,'Ventes de marchandises','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15696,'NSCF','INCOME','XXXXXX','701',15694,'Ventes de produits finis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15697,'NSCF','INCOME','XXXXXX','702',15694,'Ventes de produits intermédiaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15698,'NSCF','INCOME','XXXXXX','703',15694,'Ventes de produits résiduels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15699,'NSCF','INCOME','XXXXXX','704',15694,'Ventes de travaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15700,'NSCF','INCOME','XXXXXX','705',15694,'Ventes d''études ','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15701,'NSCF','INCOME','XXXXXX','706',15694,'Autres prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15702,'NSCF','INCOME','XXXXXX','708',15694,'Produits des activités annexes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15703,'NSCF','INCOME','XXXXXX','7081',15702,'Produits des services exploités dans l''intérêt du personnel','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15704,'NSCF','INCOME','XXXXXX','7082',15702,'Commissions et courtages','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15705,'NSCF','INCOME','XXXXXX','7083',15702,'Locations diverses','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15706,'NSCF','INCOME','XXXXXX','7084',15702,'Mise à disposition de personnel facturée','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15707,'NSCF','INCOME','XXXXXX','7085',15702,'Ports et frais accessoires facturés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15708,'NSCF','INCOME','XXXXXX','7086',15702,'Bonis sur reprises d''emballages consignés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15709,'NSCF','INCOME','XXXXXX','7087',15702,'Bonifications obtenues des clients et primes sur ventes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15710,'NSCF','INCOME','XXXXXX','7088',15702,'Autres produits d''activités annexes (cessions d''approvisionnements)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15711,'NSCF','INCOME','XXXXXX','709',15694,'Rabais, remises et ristournes accordés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15712,'NSCF','INCOME','XXXXXX','7090',15711,'R.RR, accordés sur ventes de marchandises','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15713,'NSCF','INCOME','XXXXXX','7091',15711,'R.RR, accordés sur ventes de produits finis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15714,'NSCF','INCOME','XXXXXX','7092',15711,'R.RR, accordés sur ventes de produits intermédiaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15715,'NSCF','INCOME','XXXXXX','7094',15711,'R.RR, accordés sur ventes de travaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15716,'NSCF','INCOME','XXXXXX','7095',15711,'R.RR, accordés sur ventes d''études ','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15717,'NSCF','INCOME','XXXXXX','7096',15711,'R.RR, accordés sur autres prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15718,'NSCF','INCOME','XXXXXX','7098',15711,'R.RR, accordés sur produits des activités annexes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15719,'NSCF','INCOME','XXXXXX','72',15693,'Production stockée ou déstockée','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15720,'NSCF','INCOME','XXXXXX','723',15719,'Variation de stocks d''encours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15721,'NSCF','INCOME','XXXXXX','7233',15720,'Variation des en-cours de production de biens','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15722,'NSCF','INCOME','XXXXXX','72331',15721,'Produits en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15723,'NSCF','INCOME','XXXXXX','72335',15721,'Travaux en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15724,'NSCF','INCOME','XXXXXX','7234',15720,'Variation des en-cours de production de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15725,'NSCF','INCOME','XXXXXX','72341',15724,'Etudes en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15726,'NSCF','INCOME','XXXXXX','72345',15724,'Autres prestations de services en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15727,'NSCF','INCOME','XXXXXX','724',15719,'Variation de stocks de produits','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15728,'NSCF','INCOME','XXXXXX','7241',15727,'Variation de stocks des produits intermédiaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15729,'NSCF','INCOME','XXXXXX','7245',15727,'Variation de stocks des produits finis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15730,'NSCF','INCOME','XXXXXX','7248',15727,'Variation des stocks des produits résiduels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15731,'NSCF','INCOME','XXXXXX','73',15693,'Production immobilisée','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15732,'NSCF','INCOME','XXXXXX','731',15731,'Production immobilisée d''actifs incorporels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15733,'NSCF','INCOME','XXXXXX','732',15731,'Production immobilisée d''actifs corporels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15734,'NSCF','INCOME','XXXXXX','74',15693,'Subventions d''exploitation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15735,'NSCF','INCOME','XXXXXX','741',15734,'Subventions d''équilibre','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15736,'NSCF','INCOME','XXXXXX','748',15734,'Autres subventions d''exploitation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15737,'NSCF','INCOME','XXXXXX','75',15693,'Autres produits opérationnels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15738,'NSCF','INCOME','XXXXXX','751',15737,'Redevances pour concessions, brevets, licences, logiciels et valeurs similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15739,'NSCF','INCOME','XXXXXX','7511',15738,'Redevances pour concessions, brevets, licences, logiciels, marques, procédés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15740,'NSCF','INCOME','XXXXXX','7516',15738,'Droits d''auteur et de reproduction','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15741,'NSCF','INCOME','XXXXXX','7518',15738,'Autres droits et valeurs similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15742,'NSCF','INCOME','XXXXXX','752',15737,'Plus-value sur sortie d''actifs immobilisés non financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15743,'NSCF','INCOME','XXXXXX','753',15737,'Jetons de présence et rémunérations d''administrateurs ou de gérants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15744,'NSCF','INCOME','XXXXXX','754',15737,'Quotes-parts de subventions d''investissements virés au résultat de l''exercice','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15745,'NSCF','INCOME','XXXXXX','755',15737,'Quotes-parts de résultat sur opérations faites en commun','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15746,'NSCF','INCOME','XXXXXX','7551',15745,'Quote-part de perte transférée (comptabilité du gérant)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15747,'NSCF','INCOME','XXXXXX','7555',15745,'Quote-part de bénéfice attribuée (comptabilité des associés non-gérants)','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15748,'NSCF','INCOME','XXXXXX','756',15737,'Rentrées sur créances amorties','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15749,'NSCF','INCOME','XXXXXX','757',15737,'Produits exceptionnels sur opérations de gestion','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15750,'NSCF','INCOME','XXXXXX','758',15737,'Autres produits de gestion courante','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15751,'NSCF','INCOME','XXXXXX','76',15693,'Produits financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15752,'NSCF','INCOME','XXXXXX','761',15751,'Produits des participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15753,'NSCF','INCOME','XXXXXX','7611',15752,'Revenus des titres de participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15754,'NSCF','INCOME','XXXXXX','7616',15752,'Revenus sur autres formes de participation','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15755,'NSCF','INCOME','XXXXXX','7617',15752,'Revenus des créances rattachées à des participations','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15756,'NSCF','INCOME','XXXXXX','762',15751,'Revenus des actifs financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15757,'NSCF','INCOME','XXXXXX','7621',15756,'Revenus des titres immobilisés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15758,'NSCF','INCOME','XXXXXX','7626',15756,'Revenus des prêts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15759,'NSCF','INCOME','XXXXXX','7627',15756,'Revenus des créances immobilisées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15760,'NSCF','INCOME','XXXXXX','763',15751,'Revenus de créances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15761,'NSCF','INCOME','XXXXXX','7631',15760,'Revenus des créances commerciales','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15762,'NSCF','INCOME','XXXXXX','7638',15760,'Revenus des créances diverses','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15763,'NSCF','INCOME','XXXXXX','765',15751,'Ecart d''évaluation sur actifs financiers - plus values','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15764,'NSCF','INCOME','XXXXXX','766',15751,'Gains de change','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15765,'NSCF','INCOME','XXXXXX','767',15751,'Produits nets sur cessions d''actifs financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15766,'NSCF','INCOME','XXXXXX','7671',15765,'Profits nets sur cession des part dans les entreprises liées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15767,'NSCF','INCOME','XXXXXX','7672',15765,'Profits nets sur cession d''actions propres','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15768,'NSCF','INCOME','XXXXXX','7673',15765,'Profits nets sur cession des autres titres conférant un droit de propriété','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15769,'NSCF','INCOME','XXXXXX','7676',15765,'Profits nets sur cession d''obligations, bons du trésor et bons de caisse à court terme','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15770,'NSCF','INCOME','XXXXXX','7678',15765,'Profits nets sur cession des autres valeurs mobilières et créances assimilées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15771,'NSCF','INCOME','XXXXXX','768',15751,'Autres produits financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15772,'NSCF','INCOME','XXXXXX','77',15693,'Eléments extraordinaires - produits','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15773,'NSCF','INCOME','XXXXXX','770',15772,'Produits sur exercices antérieurs','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15774,'NSCF','INCOME','XXXXXX','7700',15773,'Produits sur exercices antérieurs – ventes de marchandises','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15775,'NSCF','INCOME','XXXXXX','7701',15773,'Produits sur exercices antérieurs – ventes de produits finis','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15776,'NSCF','INCOME','XXXXXX','7702',15773,'Produits sur exercices antérieurs – ventes de produits intermédiaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15777,'NSCF','INCOME','XXXXXX','7703',15773,'Produits sur exercices antérieurs – ventes de produits résiduels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15778,'NSCF','INCOME','XXXXXX','7704',15773,'Produits sur exercices antérieurs – ventes de travaux','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15779,'NSCF','INCOME','XXXXXX','7705',15773,'Produits sur exercices antérieurs – ventes d''études ','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15780,'NSCF','INCOME','XXXXXX','7706',15773,'Produits sur exercices antérieurs – autres prestations de services','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15781,'NSCF','INCOME','XXXXXX','7708',15773,'Produits sur exercices antérieur - ventes de produits des activités annexes','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15782,'NSCF','INCOME','XXXXXX','775',15772,'Produits sur exercices antérieurs - autres produits opérationnels','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15783,'NSCF','INCOME','XXXXXX','7751',15782,'Redevances pour concessions, brevets, licence ; logiciels et valeurs similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15784,'NSCF','INCOME','XXXXXX','7752',15782,'Plus-values sur sorties d''actifs immobilisés non financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15785,'NSCF','INCOME','XXXXXX','7753',15782,'Jetons de présence et rémunérations d''administrateurs ou de gérants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15786,'NSCF','INCOME','XXXXXX','7754',15782,'Quotes-parts de subventions d''investissements virées au résultat de l''exercice','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15787,'NSCF','INCOME','XXXXXX','7755',15782,'Quotes-parts de résultat sur opérations faites en commun','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15788,'NSCF','INCOME','XXXXXX','7756',15782,'Rentrées sur créances amorties','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15789,'NSCF','INCOME','XXXXXX','7757',15782,'Produits exceptionnels sur opération de gestion','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15790,'NSCF','INCOME','XXXXXX','7759',15782,'Produits sur exercices antérieurs - remboursement des immobilisations expropriées détruites','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15791,'NSCF','INCOME','XXXXXX','778',15772,'Autres éléments extraordinaires - produits','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15792,'NSCF','INCOME','XXXXXX','7783',15791,'Bonis provenant du rachat par l''entreprise d''actions et d''obligations émises par elle-même','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15793,'NSCF','INCOME','XXXXXX','7788',15791,'Autres Produits extraordinaires divers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15794,'NSCF','INCOME','XXXXXX','78',15693,'Reprises sur pertes de valeur et provisions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15795,'NSCF','INCOME','XXXXXX','781',15794,'Reprises d''exploitation sur pertes de valeurs et provisions - actifs non courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15796,'NSCF','INCOME','XXXXXX','7810',15795,'Reprises sur provisions et pertes de valeur des immobilisations incorporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15797,'NSCF','INCOME','XXXXXX','7811',15795,'Reprises sur provisions et pertes de valeur des immobilisations corporelles','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15798,'NSCF','INCOME','XXXXXX','7812',15795,'Reprises sur provisions des immobilisations en concession','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15799,'NSCF','INCOME','XXXXXX','7813',15795,'Reprises sur provisions d''immobilisations en cours','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15800,'NSCF','INCOME','XXXXXX','7816',15795,'Reprise sur pertes de valeur des participations et créances rattachées','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15801,'NSCF','INCOME','XXXXXX','7817',15795,'Reprise sur perte de valeur des autres titres immobilisés','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15802,'NSCF','INCOME','XXXXXX','7818',15795,'Reprise sur pertes de valeur des autres instruments financiers','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15803,'NSCF','INCOME','XXXXXX','785',15794,'Reprises d''exploitation sur pertes de valeur et provisions - actifs courants','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15804,'NSCF','INCOME','XXXXXX','7853',15803,'Reprises sur provisions et pertes de valeur sur les comptes de stocks','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15805,'NSCF','INCOME','XXXXXX','7854',15803,'Reprises sur provisions et pertes de valeur sur les comptes de créances','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15806,'NSCF','INCOME','XXXXXX','7855',15803,'Reprises sur provisions et pertes de valeur sur les comptes de trésorerie','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15807,'NSCF','INCOME','XXXXXX','786',15794,'Reprises financières sur pertes de valeurs et provisions','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15808,'NSCF','INCOME','XXXXXX','7860',15807,'Reprises provisions sur plus-values à réinvestir','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15809,'NSCF','INCOME','XXXXXX','7863',15807,'Reprises provisions sur pensions et obligations similaires','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15810,'NSCF','INCOME','XXXXXX','7865',15807,'Reprises provisions pour impôts','1');
    +INSERT IGNORE INTO llx_accounting_account (rowid, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, active) VALUES (15811,'NSCF','INCOME','XXXXXX','7868',15807,'Reprises autres provisions pour charges - passifs non courants','1');
    diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql
    index 35077eb5bc5..6f3bb5461f8 100644
    --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql
    +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql
    @@ -36,25 +36,30 @@ delete from llx_c_action_trigger;
     -- actions enabled by default (constant created for that) when we enable module agenda
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('COMPANY_CREATE','Third party created','Executed when a third party is created','societe',1);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('COMPANY_SENTBYMAIL','Mails sent from third party card','Executed when you send email from third party card','societe',1);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('COMPANY_DELETE','Third party deleted','Executed when you delete third party','societe',1);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_VALIDATE','Customer proposal validated','Executed when a commercial proposal is validated','propal',2);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_SENTBYMAIL','Commercial proposal sent by mail','Executed when a commercial proposal is sent by mail','propal',3);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_SIGNED','Customer proposal closed signed','Executed when a customer proposal is closed signed','propal',2);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLOSE_REFUSED','Customer proposal closed refused','Executed when a customer proposal is closed refused','propal',2);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_CLASSIFY_BILLED','Customer proposal set billed','Executed when a customer proposal is set to billed','propal',2);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_DELETE','Customer proposal deleted','Executed when a customer proposal is deleted','propal',2);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_VALIDATE','Customer order validate','Executed when a customer order is validated','commande',4);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_CLOSE','Customer order classify delivered','Executed when a customer order is set delivered','commande',5);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_CLASSIFY_BILLED','Customer order classify billed','Executed when a customer order is set to billed','commande',5);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_CANCEL','Customer order canceled','Executed when a customer order is canceled','commande',5);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SENTBYMAIL','Customer order sent by mail','Executed when a customer order is sent by mail ','commande',5);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_DELETE','Customer order deleted','Executed when a customer order is deleted','commande',5);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_VALIDATE','Customer invoice validated','Executed when a customer invoice is approved','facture',6);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_PAYED','Customer invoice payed','Executed when a customer invoice is payed','facture',7);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_CANCEL','Customer invoice canceled','Executed when a customer invoice is conceled','facture',8);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SENTBYMAIL','Customer invoice sent by mail','Executed when a customer invoice is sent by mail','facture',9);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_UNVALIDATE','Customer invoice unvalidated','Executed when a customer invoice status set back to draft','facture',9);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_DELETE','Customer invoice deleted','Executed when a customer invoice is deleted','facture',9);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_VALIDATE','Price request validated','Executed when a commercial proposal is validated','proposal_supplier',10);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_SENTBYMAIL','Price request sent by mail','Executed when a commercial proposal is sent by mail','proposal_supplier',10);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_SIGNED','Price request closed signed','Executed when a customer proposal is closed signed','proposal_supplier',10);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_REFUSED','Price request closed refused','Executed when a customer proposal is closed refused','proposal_supplier',10);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_DELETE','Price request deleted','Executed when a customer proposal delete','proposal_supplier',10);
     --insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_CREATE','Supplier order created','Executed when a supplier order is created','order_supplier',11);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_VALIDATE','Supplier order validated','Executed when a supplier order is validated','order_supplier',12);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_APPROVE','Supplier order request approved','Executed when a supplier order is approved','order_supplier',13);
    @@ -63,15 +68,19 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_REFUSE','Supplier order request refused','Executed when a supplier order is refused','order_supplier',13);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_SENTBYMAIL','Supplier order sent by mail','Executed when a supplier order is sent by mail','order_supplier',14);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_CLASSIFY_BILLED','Supplier order set billed','Executed when a supplier order is set as billed','order_supplier',14);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_DELETE','Supplier order deleted','Executed when a supplier order is deleted','order_supplier',14);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_VALIDATE','Supplier invoice validated','Executed when a supplier invoice is validated','invoice_supplier',15);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_UNVALIDATE','Supplier invoice unvalidated','Executed when a supplier invoice status is set back to draft','invoice_supplier',15);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_PAYED','Supplier invoice payed','Executed when a supplier invoice is payed','invoice_supplier',16);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_SENTBYMAIL','Supplier invoice sent by mail','Executed when a supplier invoice is sent by mail','invoice_supplier',17);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_CANCELED','Supplier invoice cancelled','Executed when a supplier invoice is cancelled','invoice_supplier',17);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_DELETE','Supplier invoice deleted','Executed when a supplier invoice is deleted','invoice_supplier',17);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTRACT_VALIDATE','Contract validated','Executed when a contract is validated','contrat',18);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTRACT_SENTBYMAIL','Contract sent by mail','Executed when a contract is sent by mail','contrat',18);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTRACT_DELETE','Contract deleted','Executed when a contract is deleted','contrat',18);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_VALIDATE','Shipping validated','Executed when a shipping is validated','shipping',20);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_SENTBYMAIL','Shipping sent by mail','Executed when a shipping is sent by mail','shipping',21);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('SHIPPING_DELETE','Shipping sent is deleted','Executed when a shipping is deleted','shipping',21);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_VALIDATE','Member validated','Executed when a member is validated','member',22);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SENTBYMAIL','Mails sent from member card','Executed when you send email from member card','member',23);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MEMBER_SUBSCRIPTION_CREATE','Member subscribtion recorded','Executed when a member subscribtion is deleted','member',24);
    @@ -84,12 +93,16 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_CLASSIFY_UNBILLED','Intervention set unbilled','Executed when a intervention is set to unbilled (when option FICHINTER_CLASSIFY_BILLED is set)','ficheinter',33);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_REOPEN','Intervention opened','Executed when a intervention is re-opened','ficheinter',34);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',35);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_DELETE','Intervention is deleted','Executed when a intervention is deleted','ficheinter',35);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_CREATE','Product or service created','Executed when a product or sevice is created','product',40);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PRODUCT_DELETE','Product or service deleted','Executed when a product or sevice is deleted','product',42);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_CREATE','Expense report created','Executed when an expense report is created','expensereport',201);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_PAYED','Expense report billed','Executed when an expense report is set as billed','expensereport',204);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_DELETE','Expense report deleted','Executed when an expense report is deleted','expensereport',204);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_VALIDATE','Project validation','Executed when a project is validated','project',141);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_DELETE','Project deleted','Executed when a project is deleted','project',143);
     -- actions not enabled by default (no constant created for that) when we enable module agenda 
    diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    new file mode 100644
    index 00000000000..a7efecbdc5f
    --- /dev/null
    +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    @@ -0,0 +1,139 @@
    +--
    +-- Be carefull to requests order.
    +-- This file must be loaded by calling /install/index.php page
    +-- when current version is 9.0.0 or higher.
    +--
    +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y
    +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y
    +-- To rename a table:       ALTER TABLE llx_table RENAME TO llx_table_new;
    +-- To add a column:         ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol;
    +-- To rename a column:      ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60);
    +-- To drop a column:        ALTER TABLE llx_table DROP COLUMN oldname;
    +-- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60);
    +-- To drop a foreign key:   ALTER TABLE llx_table DROP FOREIGN KEY fk_name;
    +-- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field);
    +-- To drop an index:        -- VMYSQL4.1 DROP INDEX nomindex on llx_table
    +-- To drop an index:        -- VPGSQL8.2 DROP INDEX nomindex
    +-- To make pk to be auto increment (mysql):    -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT;
    +-- To make pk to be auto increment (postgres):
    +-- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid;
    +-- -- VPGSQL8.2 ALTER TABLE llx_table ADD PRIMARY KEY (rowid);
    +-- -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN rowid SET DEFAULT nextval('llx_table_rowid_seq');
    +-- -- VPGSQL8.2 SELECT setval('llx_table_rowid_seq', MAX(rowid)) FROM llx_table;
    +-- To set a field as NULL:                     -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL;
    +-- To set a field as NULL:                     -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL;
    +-- To set a field as NOT NULL:                 -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL;
    +-- To set a field as NOT NULL:                 -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL;
    +-- To set a field as default NULL:             -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL;
    +-- Note: fields with type BLOB/TEXT can't have default value.
    +
    +
    +-- Missing in 8.0
    +ALTER TABLE llx_accounting_account DROP FOREIGN KEY fk_accounting_account_fk_pcg_version;
    +ALTER TABLE llx_accounting_account MODIFY COLUMN fk_pcg_version varchar(32) NOT NULL;
    +ALTER TABLE llx_accounting_system MODIFY COLUMN pcg_version varchar(32) NOT NULL;
    +ALTER TABLE llx_accounting_account ADD CONSTRAINT fk_accounting_account_fk_pcg_version    FOREIGN KEY (fk_pcg_version)    REFERENCES llx_accounting_system (pcg_version);
    +
    +ALTER TABLE llx_facture ADD COLUMN module_source varchar(32);
    +ALTER TABLE llx_facture ADD COLUMN pos_source varchar(32);
    +
    +create table llx_facture_rec_extrafields
    +(
    +  rowid                     integer AUTO_INCREMENT PRIMARY KEY,
    +  tms                       timestamp,
    +  fk_object                 integer NOT NULL,
    +  import_key                varchar(14)
    +) ENGINE=innodb;
    +
    +
    +-- For 9.0
    +ALTER TABLE llx_extrafields ADD COLUMN help text NULL;
    +ALTER TABLE llx_extrafields ADD COLUMN totalizable boolean DEFAULT FALSE after list;
    +ALTER TABLE llx_product_fournisseur_price ADD COLUMN desc_fourn text after ref_fourn;
    +
    +
    +ALTER TABLE llx_user ADD COLUMN dateemploymentend date after dateemployment;
    +
    +ALTER TABLE llx_stock_mouvement ADD COLUMN fk_project integer;
    +
    +ALTER TABLE llx_c_field_list ADD COLUMN visible tinyint	DEFAULT 1 NOT NULL AFTER search;
    +
    +
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('COMPANY_DELETE','Third party deleted','Executed when you delete third party','societe',1);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPAL_DELETE','Customer proposal deleted','Executed when a customer proposal is deleted','propal',2);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_DELETE','Customer order deleted','Executed when a customer order is deleted','commande',5);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_DELETE','Customer invoice deleted','Executed when a customer invoice is deleted','facture',9);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_DELETE','Price request deleted','Executed when a customer proposal delete','proposal_supplier',10);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('ORDER_SUPPLIER_DELETE','Supplier order deleted','Executed when a supplier order is deleted','order_supplier',14);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BILL_SUPPLIER_DELETE','Supplier invoice deleted','Executed when a supplier invoice is deleted','invoice_supplier',17);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTRACT_DELETE','Contract deleted','Executed when a contract is deleted','contrat',18);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_DELETE','Intervention is deleted','Executed when a intervention is deleted','ficheinter',35);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_DELETE','Expense report deleted','Executed when an expense report is deleted','expensereport',204);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203);
    +
    +ALTER TABLE llx_payment_salary ADD COLUMN ref varchar(30) NULL after rowid;
    +ALTER TABLE llx_payment_salary ADD COLUMN fk_projet integer DEFAULT NULL after amount;
    +
    +ALTER TABLE llx_payment_various ADD COLUMN ref varchar(30) NULL after rowid;
    +
    +ALTER TABLE llx_categorie ADD COLUMN ref_ext varchar(255);
    +
    +ALTER TABLE llx_paiement ADD COLUMN ext_payment_id varchar(128);
    +ALTER TABLE llx_paiement ADD COLUMN ext_payment_site varchar(128);
    +
    +ALTER TABLE llx_societe ADD COLUMN twitter  varchar(255) after skype;
    +ALTER TABLE llx_societe ADD COLUMN facebook varchar(255) after skype;
    +ALTER TABLE llx_societe ADD COLUMN instagram  varchar(255) after skype;
    +ALTER TABLE llx_societe ADD COLUMN snapchat  varchar(255) after skype;
    +ALTER TABLE llx_societe ADD COLUMN googleplus  varchar(255) after skype;
    +ALTER TABLE llx_societe ADD COLUMN youtube  varchar(255) after skype;
    +ALTER TABLE llx_societe ADD COLUMN whatsapp  varchar(255) after skype;
    +
    +ALTER TABLE llx_socpeople ADD COLUMN twitter  varchar(255) after skype;
    +ALTER TABLE llx_socpeople ADD COLUMN facebook varchar(255) after skype;
    +ALTER TABLE llx_socpeople ADD COLUMN instagram  varchar(255) after skype;
    +ALTER TABLE llx_socpeople ADD COLUMN snapchat  varchar(255) after skype;
    +ALTER TABLE llx_socpeople ADD COLUMN googleplus  varchar(255) after skype;
    +ALTER TABLE llx_socpeople ADD COLUMN youtube  varchar(255) after skype;
    +ALTER TABLE llx_socpeople ADD COLUMN whatsapp  varchar(255) after skype;
    +
    +ALTER TABLE llx_adherent ADD COLUMN skype  varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN twitter  varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN facebook varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN instagram  varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN snapchat  varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN googleplus  varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN youtube  varchar(255);
    +ALTER TABLE llx_adherent ADD COLUMN whatsapp  varchar(255);
    +
    +ALTER TABLE llx_user ADD COLUMN skype  varchar(255);
    +ALTER TABLE llx_user ADD COLUMN twitter  varchar(255);
    +ALTER TABLE llx_user ADD COLUMN facebook varchar(255);
    +ALTER TABLE llx_user ADD COLUMN instagram  varchar(255);
    +ALTER TABLE llx_user ADD COLUMN snapchat  varchar(255);
    +ALTER TABLE llx_user ADD COLUMN googleplus  varchar(255);
    +ALTER TABLE llx_user ADD COLUMN youtube  varchar(255);
    +ALTER TABLE llx_user ADD COLUMN whatsapp  varchar(255);
    +
    +
    +ALTER TABLE llx_website CHANGE COLUMN fk_user_create fk_user_creat integer;
    +ALTER TABLE llx_website_page CHANGE COLUMN fk_user_create fk_user_creat integer;
    +
    +ALTER TABLE llx_website ADD COLUMN maincolor varchar(16);
    +ALTER TABLE llx_website ADD COLUMN maincolorbis varchar(16);
    +
    +
    +CREATE TABLE llx_takepos_floor_tables(
    +    rowid integer AUTO_INCREMENT PRIMARY KEY,
    +    entity integer DEFAULT 1 NOT NULL,
    +    label varchar(255),
    +    leftpos float,
    +    toppos float,
    +    floor smallint
    +) ENGINE=innodb;
    +
    +
    +UPDATE llx_c_payment_term SET decalage = nbjour, nbjour = 0 where decalage IS NULL AND type_cdr = 2;
    +
    +UPDATE llx_holiday SET ref = rowid WHERE ref IS NULL;
    diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql
    index 4169b858536..af6cd66826d 100644
    --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql
    +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql
    @@ -22,8 +22,8 @@ CREATE TABLE llx_accounting_bookkeeping
       rowid                 integer NOT NULL AUTO_INCREMENT PRIMARY KEY,
       entity                integer DEFAULT 1 NOT NULL,	-- 					| multi company id
       doc_date              date NOT NULL,				-- FEC:PieceDate
    -  doc_type              varchar(30) NOT NULL,		-- FEC:PieceRef		| facture_client/reglement_client/facture_fournisseur/reglement_fournisseur
    -  doc_ref               varchar(300) NOT NULL,		-- 					| facture_client/reglement_client/... reference number
    +  doc_type              varchar(30) NOT NULL,		-- 					| facture_client/reglement_client/facture_fournisseur/reglement_fournisseur
    +  doc_ref               varchar(300) NOT NULL,		-- FEC:PieceRef		| facture_client/reglement_client/... reference number
       fk_doc                integer NOT NULL,			-- 					| facture_client/reglement_client/... rowid
       fk_docdet             integer NOT NULL,			-- 					| facture_client/reglement_client/... line rowid
       thirdparty_code       varchar(32),                -- Third party code (customer or supplier) when record is saved (may help debug) 
    diff --git a/htdocs/install/mysql/tables/llx_adherent.sql b/htdocs/install/mysql/tables/llx_adherent.sql
    index 37b01a59dc3..3417e1b5792 100644
    --- a/htdocs/install/mysql/tables/llx_adherent.sql
    +++ b/htdocs/install/mysql/tables/llx_adherent.sql
    @@ -46,7 +46,16 @@ create table llx_adherent
       state_id         integer,
       country          integer,
       email            varchar(255),
    +
       skype            varchar(255),
    +  twitter          varchar(255),                        		--
    +  facebook         varchar(255),                        		--
    +  instagram        varchar(255),                        		--
    +  snapchat         varchar(255),                        		--
    +  googleplus       varchar(255),                        		--
    +  youtube          varchar(255),                        		--
    +  whatsapp         varchar(255),                        		--
    +
       phone            varchar(30),
       phone_perso      varchar(30),
       phone_mobile     varchar(30),
    diff --git a/htdocs/install/mysql/tables/llx_c_field_list.sql b/htdocs/install/mysql/tables/llx_c_field_list.sql
    index b22f98b52ec..21adba42cfa 100644
    --- a/htdocs/install/mysql/tables/llx_c_field_list.sql
    +++ b/htdocs/install/mysql/tables/llx_c_field_list.sql
    @@ -1,5 +1,5 @@
     -- ========================================================================
    --- Copyright (C) 2010 Regis Houssin  <regis.houssin@capnetworks.com>
    +-- Copyright (C) 2010-2018 Regis Houssin  <regis.houssin@capnetworks.com>
     --
     -- 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
    @@ -33,6 +33,7 @@ create table llx_c_field_list
       align			varchar(6)		DEFAULT 'left',				-- align (left,center,right)
       sort			tinyint 		DEFAULT 1  	NOT NULL,		-- add sort field
       search		tinyint 		DEFAULT 0  	NOT NULL,		-- add search field
    +  visible		tinyint			DEFAULT 1	NOT NULL,		-- visibility of field. 0=Never visible, 1=Visible on list and forms, 2=Visible on list only
       enabled       varchar(255)	DEFAULT 1,					-- Condition to show or hide
       rang      	integer 		DEFAULT 0
       
    diff --git a/htdocs/install/mysql/tables/llx_categorie.sql b/htdocs/install/mysql/tables/llx_categorie.sql
    index fe2b03b2429..5493d2cfc8c 100644
    --- a/htdocs/install/mysql/tables/llx_categorie.sql
    +++ b/htdocs/install/mysql/tables/llx_categorie.sql
    @@ -24,7 +24,8 @@ create table llx_categorie
     	rowid 		    integer AUTO_INCREMENT PRIMARY KEY,
     	entity          integer DEFAULT 1 NOT NULL,			-- multi company id
     	fk_parent		integer DEFAULT 0 NOT NULL,
    -	label 		    varchar(180) NOT NULL,				-- category name
    +	label 		    varchar(180) NOT NULL,				-- category ref/name
    +	ref_ext			varchar(255),						-- reference into an external system (not used by dolibarr)
     	type	        tinyint DEFAULT 1 NOT NULL,			-- category type (product, supplier, customer, member)
     	description 	text,								-- description of the category
         color           varchar(8),                         -- color
    diff --git a/htdocs/install/mysql/tables/llx_extrafields.sql b/htdocs/install/mysql/tables/llx_extrafields.sql
    index 9acf239ee64..9f37383957a 100644
    --- a/htdocs/install/mysql/tables/llx_extrafields.sql
    +++ b/htdocs/install/mysql/tables/llx_extrafields.sql
    @@ -36,7 +36,9 @@ create table llx_extrafields
     	alwayseditable  integer DEFAULT 0,							-- 1 if field can be edited whatever is element status
     	param			text,										-- extra parameters to define possible values of field
     	list			varchar(255) DEFAULT '1',					-- visibility of field. 0=Never visible, 1=Visible on list and forms, 2=Visible on list only. Using a negative value means field is not shown by default on list but can be selected for viewing
    +    totalizable     boolean DEFAULT FALSE,                      -- is extrafield totalizable on list
     	langs			varchar(64),								-- example: fileofmymodule@mymodule
    +	help            text,                                       -- to store help tooltip
     	fk_user_author	integer,									-- user making creation
     	fk_user_modif	integer,	                                -- user making last change
     	datec			datetime,									-- date de creation
    diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql
    index c0783a7bbd8..c001d459b48 100644
    --- a/htdocs/install/mysql/tables/llx_facture.sql
    +++ b/htdocs/install/mysql/tables/llx_facture.sql
    @@ -63,16 +63,18 @@ create table llx_facture
       fk_user_modif         integer,                                -- user making last change
       fk_user_valid			integer,								-- user validating
     
    +  module_source			varchar(32),							-- name of module when invoice generated by a dedicated module (POS, ...)
    +  pos_source			varchar(32),							-- name of POS station when invoice is generated by a POS module
       fk_fac_rec_source		integer,								-- facture rec source
       fk_facture_source		integer,								-- facture origin if credit notes or replacement invoice
    -  fk_projet				integer DEFAULT NULL,					-- projet auquel est associee la facture
    +  fk_projet				integer DEFAULT NULL,					-- project invoice is linked to
     
       fk_account			integer,								-- bank account
       fk_currency			varchar(3),								-- currency code
       
    -  fk_cond_reglement		integer  DEFAULT 1 NOT NULL,			-- condition de reglement (30 jours, fin de mois ...)
    -  fk_mode_reglement		integer,								-- mode de reglement (Virement, Prelevement)
    -  date_lim_reglement	date,									-- date limite de reglement
    +  fk_cond_reglement		integer  DEFAULT 1 NOT NULL,			-- payment term (30 days, end of month...)
    +  fk_mode_reglement		integer,								-- payment mode (Virement, Prelevement)
    +  date_lim_reglement	date,									-- due date
     
       note_private			text,
       note_public			text,
    diff --git a/htdocs/install/mysql/tables/llx_fichinter_rec.key.sql b/htdocs/install/mysql/tables/llx_fichinter_rec.key.sql
    new file mode 100644
    index 00000000000..0c420fd6395
    --- /dev/null
    +++ b/htdocs/install/mysql/tables/llx_fichinter_rec.key.sql
    @@ -0,0 +1,30 @@
    +-- ============================================================================
    +-- Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    +-- Copyright (C) 2004-2006 Laurent Destailleur  <eldy@users.sourceforge.net>
    +-- Copyright (C) 2009      Regis Houssin        <regis.houssin@capnetworks.com>
    +-- Copyright (C) 2018      Charlene Benke        <charlie@patas-monkey.com>
    +--
    +-- 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 <http://www.gnu.org/licenses/>.
    +--
    +-- ============================================================================
    +
    +
    +ALTER TABLE llx_fichinter_rec ADD UNIQUE INDEX idx_fichinter_rec_uk_titre (titre, entity);
    +
    +ALTER TABLE llx_fichinter_rec ADD INDEX idx_fichinter_rec_fk_soc (fk_soc);
    +ALTER TABLE llx_fichinter_rec ADD INDEX idx_fichinter_rec_fk_user_author (fk_user_author);
    +ALTER TABLE llx_fichinter_rec ADD INDEX idx_fichinter_rec_fk_projet (fk_projet);
    +
    +ALTER TABLE llx_fichinter_rec ADD CONSTRAINT fk_fichinter_rec_fk_user_author    FOREIGN KEY (fk_user_author) REFERENCES llx_user (rowid);
    +ALTER TABLE llx_fichinter_rec ADD CONSTRAINT fk_fichinter_rec_fk_projet         FOREIGN KEY (fk_projet) REFERENCES llx_projet (rowid);
    diff --git a/htdocs/install/mysql/tables/llx_fichinter_rec.sql b/htdocs/install/mysql/tables/llx_fichinter_rec.sql
    new file mode 100644
    index 00000000000..10dacbde4ee
    --- /dev/null
    +++ b/htdocs/install/mysql/tables/llx_fichinter_rec.sql
    @@ -0,0 +1,48 @@
    +-- ===========================================================================
    +-- Copyright (C) 2003      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    +-- Copyright (C) 2012-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
    +-- Copyright (C) 2009      Regis Houssin        <regis.houssin@capnetworks.com>
    +-- Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
    +-- Copyright (C) 2018      Charlene Benke		    <charlie@patas-monkey.com>
    +-- 
    +-- 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 <http://www.gnu.org/licenses/>.
    +--
    +-- ===========================================================================
    +
    +create table llx_fichinter_rec
    +(
    +	rowid				integer AUTO_INCREMENT PRIMARY KEY,
    +	titre				varchar(50) NOT NULL,
    +	entity				integer DEFAULT 1 NOT NULL,	 -- multi company id
    +	fk_soc				integer DEFAULT NULL,
    +	datec				datetime,  -- date de creation
    +	
    +	fk_contrat			integer DEFAULT 0,          -- contrat auquel est rattache la fiche
    +	fk_user_author		integer,             -- createur
    +	fk_projet			integer,             -- projet auquel est associe la facture
    +	duree				real,                       -- duree totale de l'intervention
    +	description			text,
    +	modelpdf			varchar(50),
    +	note_private		text,
    +	note_public			text,
    +
    +	frequency			integer,					-- frequency (for example: 3 for every 3 month)
    +	unit_frequency		varchar(2) DEFAULT 'm',		-- 'm' for month (date_when must be a day <= 28), 'y' for year, ... 
    +	date_when			datetime DEFAULT NULL,		-- date for next gen (when an invoice is generated, this field must be updated with next date)
    +	date_last_gen		datetime DEFAULT NULL,		-- date for last gen (date with last successfull generation of invoice)
    +	nb_gen_done			integer DEFAULT NULL,		-- nb of generation done (when an invoice is generated, this field must incremented)
    +	nb_gen_max			integer DEFAULT NULL,		-- maximum number of generation
    +	auto_validate		integer NULL DEFAULT NULL	-- statut of the generated intervention
    +
    +)ENGINE=innodb;
    diff --git a/htdocs/install/mysql/tables/llx_fichinterdet_rec.sql b/htdocs/install/mysql/tables/llx_fichinterdet_rec.sql
    new file mode 100644
    index 00000000000..682453f2dfd
    --- /dev/null
    +++ b/htdocs/install/mysql/tables/llx_fichinterdet_rec.sql
    @@ -0,0 +1,63 @@
    +-- ===================================================================
    +-- Copyright (C) 2003		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    +-- Copyright (C) 2009-2014	Laurent Destailleur		<eldy@users.sourceforge.net>
    +-- Copyright (C) 2010		Juanjo Menent			<jmenent@2byte.es>
    +-- Copyright (C) 2010-2012	Regis Houssin			<regis.houssin@capnetworks.com>
    +-- Copyright (C) 2012		Cédric Salvador			<csalvador@gpcsolutions.fr>
    +-- Copyright (C) 2016-2018	Charlene Benke			<charlie@patas-monkey.com>
    +--
    +-- 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 <http://www.gnu.org/licenses/>.
    +--
    +-- ===================================================================
    +
    +create table llx_fichinterdet_rec
    +(
    +	rowid				integer AUTO_INCREMENT PRIMARY KEY,
    +	fk_fichinter		integer NOT NULL,
    +	date				datetime,				-- date de la ligne d'intervention
    +	description			text,					-- description de la ligne d'intervention
    +	duree				integer,				-- duree de la ligne d'intervention
    +	rang				integer DEFAULT 0,		-- ordre affichage sur la fiche
    +	total_ht			DOUBLE(24, 8) NULL DEFAULT NULL,
    +	subprice			DOUBLE(24, 8) NULL DEFAULT NULL,
    +	fk_parent_line		integer NULL DEFAULT NULL,
    +	fk_product			integer NULL DEFAULT NULL,
    +	label				varchar(255) NULL DEFAULT NULL,
    +	tva_tx				DOUBLE(6, 3) NULL DEFAULT NULL,
    +	localtax1_tx		DOUBLE(6, 3) NULL DEFAULT 0,
    +	localtax1_type		VARCHAR(1) NULL DEFAULT NULL,
    +	localtax2_tx		DOUBLE(6, 3) NULL DEFAULT 0,
    +	localtax2_type		VARCHAR(1) NULL DEFAULT NULL,
    +	qty					double NULL DEFAULT NULL,
    +	remise_percent		double NULL DEFAULT 0,
    +	remise				double NULL DEFAULT 0,
    +	fk_remise_except	integer NULL DEFAULT NULL,
    +	price				DOUBLE(24, 8) NULL DEFAULT NULL,
    +	total_tva			DOUBLE(24, 8) NULL DEFAULT NULL,
    +	total_localtax1		DOUBLE(24, 8) NULL DEFAULT 0,
    +	total_localtax2		DOUBLE(24, 8) NULL DEFAULT 0,
    +	total_ttc			DOUBLE(24, 8) NULL DEFAULT NULL,
    +	product_type		INTEGER NULL DEFAULT 0,
    +	date_start			datetime NULL DEFAULT NULL,
    +	date_end			datetime NULL DEFAULT NULL,
    +	info_bits			INTEGER NULL DEFAULT 0,
    +	buy_price_ht		DOUBLE(24, 8) NULL DEFAULT 0,
    +	fk_product_fournisseur_price	integer NULL DEFAULT NULL,
    +	fk_code_ventilation	integer NOT NULL DEFAULT 0,
    +	fk_export_commpta	integer NOT NULL DEFAULT 0,
    +	special_code		integer UNSIGNED NULL DEFAULT 0,
    +	fk_unit				integer NULL DEFAULT NULL,	
    +	import_key			varchar(14) NULL DEFAULT NULL
    +
    +)ENGINE=innodb;
    diff --git a/htdocs/install/mysql/tables/llx_holiday.sql b/htdocs/install/mysql/tables/llx_holiday.sql
    index f6994810021..47c68647ffb 100644
    --- a/htdocs/install/mysql/tables/llx_holiday.sql
    +++ b/htdocs/install/mysql/tables/llx_holiday.sql
    @@ -32,9 +32,9 @@ date_debut     DATE NOT NULL,
     date_fin       DATE NOT NULL,
     halfday        integer DEFAULT 0,				-- 0=start morning and end afternoon, -1=start afternoon end afternoon, 1=start morning and end morning, 2=start afternoon and end morning
     statut         integer NOT NULL DEFAULT '1',
    -fk_validator   integer NOT NULL,
    -date_valid     DATETIME DEFAULT NULL,
    -fk_user_valid  integer DEFAULT NULL,
    +fk_validator   integer NOT NULL,				-- who should approve
    +date_valid     DATETIME DEFAULT NULL,			-- date approval
    +fk_user_valid  integer DEFAULT NULL,			-- user approval
     date_refuse    DATETIME DEFAULT NULL,
     fk_user_refuse integer DEFAULT NULL,
     date_cancel    DATETIME DEFAULT NULL,
    diff --git a/htdocs/install/mysql/tables/llx_paiement.sql b/htdocs/install/mysql/tables/llx_paiement.sql
    index 2a287ac7e89..25c0097f10e 100644
    --- a/htdocs/install/mysql/tables/llx_paiement.sql
    +++ b/htdocs/install/mysql/tables/llx_paiement.sql
    @@ -21,7 +21,7 @@
     create table llx_paiement
     (
       rowid            integer AUTO_INCREMENT PRIMARY KEY,
    -  ref              varchar(30) NOT NULL, -- payment reference number
    +  ref              varchar(30) NULL,                    -- payment reference number
       entity           integer   DEFAULT 1 NOT NULL,		-- Multi company id
       datec            datetime,							-- date de creation
       tms              timestamp,
    @@ -31,9 +31,11 @@ create table llx_paiement
       fk_paiement      integer NOT NULL,
       num_paiement     varchar(50),
       note             text,
    +  ext_payment_id   varchar(128),						-- external id of payment (for example Stripe charge id)
    +  ext_payment_site varchar(128),						-- name of external paymentmode (for example 'stripe')
       fk_bank          integer NOT NULL DEFAULT 0,
       fk_user_creat    integer,								-- utilisateur qui a cree l'info
       fk_user_modif    integer,								-- utilisateur qui a modifie l'info
    -  statut           smallint DEFAULT 0 NOT NULL,		-- Satut, 0 ou 1, 1 n'est plus supprimable
    +  statut           smallint DEFAULT 0 NOT NULL,			-- Satut, 0 ou 1, 1 n'est plus supprimable
       fk_export_compta integer DEFAULT 0 NOT NULL			-- fk_export_compta 0 pas exporte
     )ENGINE=innodb;
    diff --git a/htdocs/install/mysql/tables/llx_payment_salary.sql b/htdocs/install/mysql/tables/llx_payment_salary.sql
    index e3bcd0a9c4a..c56e6459aa0 100644
    --- a/htdocs/install/mysql/tables/llx_payment_salary.sql
    +++ b/htdocs/install/mysql/tables/llx_payment_salary.sql
    @@ -19,6 +19,7 @@
     create table llx_payment_salary
     (
       rowid           integer AUTO_INCREMENT PRIMARY KEY,
    +  ref             varchar(30) NOT NULL,       -- payment reference number
       tms             timestamp,
       datec           datetime,                   -- Create date
       fk_user         integer NOT NULL,
    @@ -26,11 +27,12 @@ create table llx_payment_salary
       datev           date,                       -- value date (this field should not be here, only into bank tables)
       salary          double(24,8),               -- salary of user when payment was done
       amount          double(24,8) NOT NULL DEFAULT 0,
    +  fk_projet       integer DEFAULT NULL,
       fk_typepayment  integer NOT NULL,
    -  num_payment     varchar(50),                -- ref
    +  num_payment     varchar(50),                -- num cheque or other
       label           varchar(255),
       datesp          date,                       -- date start period
    -  dateep          date,                       -- date end period    
    +  dateep          date,                       -- date end period
       entity          integer DEFAULT 1 NOT NULL, -- multi company id
       note            text,
       fk_bank         integer,
    diff --git a/htdocs/install/mysql/tables/llx_payment_various.sql b/htdocs/install/mysql/tables/llx_payment_various.sql
    index e719dae7d8c..d3351287e58 100644
    --- a/htdocs/install/mysql/tables/llx_payment_various.sql
    +++ b/htdocs/install/mysql/tables/llx_payment_various.sql
    @@ -19,7 +19,8 @@
     create table llx_payment_various
     (
       rowid                 integer AUTO_INCREMENT PRIMARY KEY,
    -  num_payment           varchar(50),				-- ref
    +  ref                   varchar(30) NOT NULL,       -- payment reference number
    +  num_payment           varchar(50),				-- num cheque or other
       label                 varchar(255),
       tms                   timestamp,
       datec                 datetime,                   -- Create date
    diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql
    index ab2efba1455..daccb2d7927 100755
    --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql
    +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql
    @@ -28,6 +28,7 @@ create table llx_product_fournisseur_price
       fk_product			integer,
       fk_soc				integer,
       ref_fourn				varchar(30),
    +  desc_fourn            text,
       fk_availability		integer,	   
       price					double(24,8) DEFAULT 0,		-- price without tax for quantity
       quantity				double,
    diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql
    index f1714021fb8..a05051024eb 100644
    --- a/htdocs/install/mysql/tables/llx_societe.sql
    +++ b/htdocs/install/mysql/tables/llx_societe.sql
    @@ -50,7 +50,16 @@ create table llx_societe
       fax                      varchar(20),                         		-- fax number
       url                      varchar(255),                        		--
       email                    varchar(128),                        		--
    +  
       skype                    varchar(255),                        		--
    +  twitter                  varchar(255),                        		--
    +  facebook                 varchar(255),                        		--
    +  instagram                varchar(255),                        		--
    +  snapchat                 varchar(255),                        		--
    +  googleplus               varchar(255),                        		--
    +  youtube                  varchar(255),                        		--
    +  whatsapp                 varchar(255),                        		--
    +  
       fk_effectif              integer        DEFAULT 0,            		--
       fk_typent                integer        DEFAULT 0,            		--
       fk_forme_juridique       integer        DEFAULT 0,            		-- juridical status
    diff --git a/htdocs/install/mysql/tables/llx_socpeople.sql b/htdocs/install/mysql/tables/llx_socpeople.sql
    index 51848b33b48..e0e99993f47 100644
    --- a/htdocs/install/mysql/tables/llx_socpeople.sql
    +++ b/htdocs/install/mysql/tables/llx_socpeople.sql
    @@ -41,8 +41,17 @@ create table llx_socpeople
       phone_mobile		varchar(30),
       fax				varchar(30),
       email				varchar(255),
    +  
       jabberid			varchar(255),
       skype				varchar(255),
    +  twitter			varchar(255),                        		--
    +  facebook			varchar(255),                        		--
    +  instagram                varchar(255),                        		--
    +  snapchat                 varchar(255),                        		--
    +  googleplus               varchar(255),                        		--
    +  youtube                  varchar(255),                        		--
    +  whatsapp                 varchar(255),                        		--
    +  
       photo				varchar(255),
       no_email			smallint NOT NULL DEFAULT 0,
       priv				smallint NOT NULL DEFAULT 0,
    diff --git a/htdocs/install/mysql/tables/llx_stock_mouvement.sql b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
    index 1e78e7a9820..fdeab913268 100644
    --- a/htdocs/install/mysql/tables/llx_stock_mouvement.sql
    +++ b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
    @@ -33,6 +33,7 @@ create table llx_stock_mouvement
       fk_user_author  integer,							-- Id user making movement
       label           varchar(255),						-- Comment on movement
       inventorycode   varchar(128),						-- Code used to group different movement line into one operation (may be an inventory, a mass picking)
    +  fk_project	  integer,
       fk_origin       integer,
       origintype      varchar(32),
       model_pdf       varchar(255)
    diff --git a/htdocs/install/mysql/tables/llx_takepos_floor_tables.sql b/htdocs/install/mysql/tables/llx_takepos_floor_tables.sql
    new file mode 100644
    index 00000000000..c8cae17b5a2
    --- /dev/null
    +++ b/htdocs/install/mysql/tables/llx_takepos_floor_tables.sql
    @@ -0,0 +1,26 @@
    +-- Copyright (C) 2018 SuperAdmin
    +--
    +-- 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 http://www.gnu.org/licenses/.
    +
    +
    +CREATE TABLE llx_takepos_floor_tables(
    +    -- BEGIN MODULEBUILDER FIELDS
    +    rowid integer AUTO_INCREMENT PRIMARY KEY,
    +    entity integer DEFAULT 1 NOT NULL,
    +    label varchar(255),
    +    leftpos float,
    +    toppos float,
    +    floor smallint
    +    -- END MODULEBUILDER FIELDS
    +) ENGINE=innodb;
    diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql
    index 2ecb52511d4..56a03f81782 100644
    --- a/htdocs/install/mysql/tables/llx_user.sql
    +++ b/htdocs/install/mysql/tables/llx_user.sql
    @@ -49,11 +49,21 @@ create table llx_user
       fk_country        integer        DEFAULT 0,
       birth             date,						-- birthday
       job				varchar(128),
    -  skype             varchar(255),
       office_phone      varchar(20),
       office_fax        varchar(20),
       user_mobile       varchar(20),
       email             varchar(255),
    +  
    +  jabberid			varchar(255),
    +  skype				varchar(255),
    +  twitter			varchar(255),                        		--
    +  facebook			varchar(255),                        		--
    +  instagram                varchar(255),                        		--
    +  snapchat                 varchar(255),                        		--
    +  googleplus               varchar(255),                        		--
    +  youtube                  varchar(255),                        		--
    +  whatsapp                 varchar(255),                        		--
    +  
       signature         text DEFAULT NULL,
       admin             smallint DEFAULT 0,
       module_comm       smallint DEFAULT 1,
    @@ -84,6 +94,7 @@ create table llx_user
       salary			double(24,8),				-- denormalized value coming from llx_user_employment
       salaryextra		double(24,8),				-- denormalized value coming from llx_user_employment
       dateemployment	date,						-- denormalized value coming from llx_user_employment
    +  dateemploymentend	date,						-- denormalized value coming from llx_user_employment
       weeklyhours		double(16,8),				-- denormalized value coming from llx_user_employment
     
       import_key        varchar(14),				-- import key
    diff --git a/htdocs/install/mysql/tables/llx_website.sql b/htdocs/install/mysql/tables/llx_website.sql
    index dd35116a91f..697e76b22a2 100644
    --- a/htdocs/install/mysql/tables/llx_website.sql
    +++ b/htdocs/install/mysql/tables/llx_website.sql
    @@ -24,12 +24,14 @@ CREATE TABLE llx_website
     	entity        integer NOT NULL DEFAULT 1,
     	ref	          varchar(128) NOT NULL,
     	description   varchar(255),
    +	maincolor     varchar(16),
    +	maincolorbis  varchar(16),
     	status		  integer DEFAULT 1,
     	fk_default_home integer, 
     	virtualhost   varchar(255), 
    -    fk_user_create integer,
    -    fk_user_modif  integer,
    -    date_creation  datetime,
    -	tms            timestamp,
    -    import_key     varchar(14)      -- import key	
    +    fk_user_creat integer,
    +    fk_user_modif integer,
    +    date_creation datetime,
    +	tms           timestamp,
    +    import_key    varchar(14)      -- import key	
     ) ENGINE=innodb;
    diff --git a/htdocs/install/mysql/tables/llx_website_page.sql b/htdocs/install/mysql/tables/llx_website_page.sql
    index c795fa254dc..3c872f00dac 100644
    --- a/htdocs/install/mysql/tables/llx_website_page.sql
    +++ b/htdocs/install/mysql/tables/llx_website_page.sql
    @@ -32,10 +32,10 @@ CREATE TABLE llx_website_page
     	htmlheader	  text,
     	content		  mediumtext,		-- text is not enough in size
         status        integer DEFAULT 1,
    -	grabbed_from   varchar(255),
    -    fk_user_create integer,
    -    fk_user_modif  integer,
    -    date_creation  datetime,
    -	tms            timestamp,
    -    import_key     varchar(14)      -- import key
    +	grabbed_from  varchar(255),
    +    fk_user_creat integer,
    +    fk_user_modif integer,
    +    date_creation datetime,
    +	tms           timestamp,
    +    import_key    varchar(14)      -- import key
     ) ENGINE=innodb;
    diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php
    index 1fbda8e8abb..9014fe1924b 100644
    --- a/htdocs/install/repair.php
    +++ b/htdocs/install/repair.php
    @@ -549,11 +549,11 @@ if ($ok && GETPOST('clean_menus','alpha'))
     								dol_print_error($db);
     							}
     							else
    -								print ' - <font class="warning">Cleaned</font>';
    +								print ' - <span class="warning">Cleaned</span>';
     						}
     						else
     						{
    -							print ' - <font class="warning">Canceled (test mode)</font>';
    +							print ' - <span class="warning">Canceled (test mode)</span>';
     						}
     					}
     					else
    @@ -648,7 +648,6 @@ if ($ok && GETPOST('clean_orphelin_dir','alpha'))
                 $object_instance=new ChargeSociales($db);
             }
     
    -        $var=true;
             foreach($filearray as $key => $file)
             {
                 if (!is_dir($file['name'])
    @@ -898,7 +897,6 @@ if ($ok && GETPOST('set_empty_time_spent_amount','alpha'))
         {
             dol_print_error($db);
         }
    -
     }
     
     
    @@ -984,11 +982,11 @@ if ($ok && GETPOST('force_disable_of_modules_not_found','alpha'))
     	                                    dol_print_error($db);
     	                                }
     	                                else
    -	                                    print ' - <font class="warning">Cleaned</font>';
    +	                                    print ' - <span class="warning">Cleaned</span>';
     	                            }
     	                            else
     	                            {
    -	                                print ' - <font class="warning">Canceled (test mode)</font>';
    +	                                print ' - <span class="warning">Canceled (test mode)</span>';
     	                            }
     	                        }
     	                        else
    diff --git a/htdocs/install/step1.php b/htdocs/install/step1.php
    index 6f1143d6f10..34bd117504a 100644
    --- a/htdocs/install/step1.php
    +++ b/htdocs/install/step1.php
    @@ -36,9 +36,7 @@ $action=GETPOST('action','aZ09')?GETPOST('action','aZ09'):(empty($argv[1])?'':$a
     $setuplang=GETPOST('selectlang','aZ09',3)?GETPOST('selectlang','aZ09',3):(empty($argv[2])?'auto':$argv[2]);
     $langs->setDefaultLang($setuplang);
     
    -$langs->load("admin");
    -$langs->load("install");
    -$langs->load("errors");
    +$langs->loadLangs(array("admin", "install", "errors"));
     
     // Dolibarr pages directory
     $main_dir = GETPOST('main_dir')?GETPOST('main_dir'):(empty($argv[3])?'':$argv[3]);
    @@ -46,7 +44,7 @@ $main_dir = GETPOST('main_dir')?GETPOST('main_dir'):(empty($argv[3])?'':$argv[3]
     $main_data_dir = GETPOST('main_data_dir') ? GETPOST('main_data_dir') : (empty($argv[4])? ($main_dir . '/documents') :$argv[4]);
     // Dolibarr root URL
     $main_url = GETPOST('main_url')?GETPOST('main_url'):(empty($argv[5])?'':$argv[5]);
    -// Database login informations
    +// Database login information
     $userroot=GETPOST('db_user_root','alpha')?GETPOST('db_user_root','alpha'):(empty($argv[6])?'':$argv[6]);
     $passroot=GETPOST('db_pass_root','none')?GETPOST('db_pass_root','none'):(empty($argv[7])?'':$argv[7]);
     // Database server
    @@ -68,18 +66,18 @@ $main_alt_dir_name = ((GETPOST("main_alt_dir_name",'alpha') && GETPOST("main_alt
     
     session_start();    // To be able to keep info into session (used for not losing password during navigation. The password must not transit through parameters)
     
    -// Save a flag to tell to restore input value if we do back
    +// Save a flag to tell to restore input value if we go back
     $_SESSION['dol_save_pass']=$db_pass;
     //$_SESSION['dol_save_passroot']=$passroot;
     
    -// Now we load forced value from install.forced.php file.
    +// Now we load forced values from install.forced.php file.
     $useforcedwizard=false;
     $forcedfile="./install.forced.php";
     if ($conffile == "/etc/dolibarr/conf.php") $forcedfile="/etc/dolibarr/install.forced.php";
     if (@file_exists($forcedfile)) {
     	$useforcedwizard = true;
     	include_once $forcedfile;
    -	// If forced install is enabled, let's replace post values. These are empty because form fields are disabled.
    +	// If forced install is enabled, replace the post values. These are empty because form fields are disabled.
     	if ($force_install_noedit) {
     		$main_dir = detect_dolibarr_main_document_root();
     		if (!empty($force_install_main_data_root)) {
    @@ -204,7 +202,7 @@ if (! $error) {
         $result=@include_once $main_dir."/core/db/".$db_type.'.class.php';
         if ($result)
         {
    -        // If we ask database or user creation we need to connect as root, so we need root login
    +        // If we require database or user creation we need to connect as root, so we need root login credentials
             if (!empty($db_create_database) && !$userroot) {
                 print '<div class="error">'.$langs->trans("YouAskDatabaseCreationSoDolibarrNeedToConnect",$db_name).'</div>';
                 print '<br>';
    @@ -397,7 +395,7 @@ if (! $error && $db->connected && $action == "set")
                 print "<tr><td>".$langs->trans("ErrorDirDoesNotExists",$main_data_dir);
                 print ' '.$langs->trans("YouMustCreateItAndAllowServerToWrite");
                 print '</td><td>';
    -            print '<font class="error">'.$langs->trans("Error").'</font>';
    +            print '<span class="error">'.$langs->trans("Error").'</span>';
                 print "</td></tr>";
                 print '<tr><td colspan="2"><br>'.$langs->trans("CorrectProblemAndReloadPage",$_SERVER['PHP_SELF'].'?testget=ok').'</td></tr>';
                 $error++;
    @@ -420,7 +418,7 @@ if (! $error && $db->connected && $action == "set")
                     }
                 }
     
    -            // Les documents sont en dehors de htdocs car ne doivent pas pouvoir etre telecharges en passant outre l'authentification
    +            // Documents are stored above the web pages root to prevent being downloaded without authentification
                 $dir=array();
                 $dir[] = $main_data_dir."/mycompany";
                 $dir[] = $main_data_dir."/medias";
    @@ -431,7 +429,7 @@ if (! $error && $db->connected && $action == "set")
                 $dir[] = $main_data_dir."/produit";
                 $dir[] = $main_data_dir."/doctemplates";
     
    -            // Boucle sur chaque repertoire de dir[] pour les creer s'ils nexistent pas
    +            // Loop on each directory of dir [] to create them if they do not exist
                 $num=count($dir);
                 for ($i = 0; $i < $num; $i++)
                 {
    @@ -469,7 +467,7 @@ if (! $error && $db->connected && $action == "set")
                     print "<tr><td>".$langs->trans("ErrorDirDoesNotExists",$main_data_dir);
                     print ' '.$langs->trans("YouMustCreateItAndAllowServerToWrite");
                     print '</td><td>';
    -                print '<font class="error">'.$langs->trans("Error").'</font>';
    +                print '<span class="error">'.$langs->trans("Error").'</span>';
                     print "</td></tr>";
                     print '<tr><td colspan="2"><br>'.$langs->trans("CorrectProblemAndReloadPage",$_SERVER['PHP_SELF'].'?testget=ok').'</td></tr>';
                 }
    @@ -485,8 +483,8 @@ if (! $error && $db->connected && $action == "set")
                 		'products' => 'product',
                 		'projects' => 'project',
                 		'proposals' => 'proposal',
    -            		'shipment' => 'shipment',
    -            		'supplier_proposal' => 'supplier_proposal',
    +            		'shipments' => 'shipment',
    +            		'supplier_proposals' => 'supplier_proposal',
                 		'tasks' => 'task_summary',
                 		'thirdparties' => 'thirdparty',
                 		'usergroups' => 'usergroups',
    @@ -519,7 +517,7 @@ if (! $error && $db->connected && $action == "set")
             // Save old conf file on disk
             if (file_exists("$conffile"))
             {
    -            // We must ignore errors as an existing old file may already exists and not be replacable or
    +            // We must ignore errors as an existing old file may already exist and not be replaceable or
                 // the installer (like for ubuntu) may not have permission to create another file than conf.php.
                 // Also no other process must be able to read file or we expose the new file, so content with password.
                 @dol_copy($conffile, $conffile.'.old', '0400');
    @@ -539,7 +537,7 @@ if (! $error && $db->connected && $action == "set")
             print '</td>';
             print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
     
    -        // Si creation utilisateur admin demandee, on le cree
    +        // Create database user if requested
             if (isset($db_create_user) && ($db_create_user == "1" || $db_create_user == "on")) {
                 dolibarr_install_syslog("step1: create database user: " . $dolibarr_main_db_user);
     
    @@ -558,7 +556,7 @@ if (! $error && $db->connected && $action == "set")
                     $databasefortest='master';
                 }
     
    -            // Creation handler de base, verification du support et connexion
    +            // Check database connection
     
                 $db=getDoliDBInstance($conf->db->type,$conf->db->host,$userroot,$passroot,$databasefortest,$conf->db->port);
     
    @@ -629,7 +627,7 @@ if (! $error && $db->connected && $action == "set")
                         print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td>';
                         print '</tr>';
     
    -                    // Affiche aide diagnostique
    +                    // warning message due to connection failure
                         print '<tr><td colspan="2"><br>';
                         print $langs->trans("YouAskDatabaseCreationSoDolibarrNeedToConnect",$dolibarr_main_db_user,$dolibarr_main_db_host,$userroot);
                         print '<br>';
    @@ -640,10 +638,10 @@ if (! $error && $db->connected && $action == "set")
                         $error++;
                     }
                 }
    -        }   // Fin si "creation utilisateur"
    +        }   // end of user account creation
     
     
    -        // If database creation is asked, we create it
    +        // If database creation was asked, we create it
             if (!$error && (isset($db_create_database) && ($db_create_database == "1" || $db_create_database == "on"))) {
                 dolibarr_install_syslog("step1: create database: " . $dolibarr_main_db_name . " " . $dolibarr_main_db_character_set . " " . $dolibarr_main_db_collation . " " . $dolibarr_main_db_user);
             	$newdb=getDoliDBInstance($conf->db->type,$conf->db->host,$userroot,$passroot,'',$conf->db->port);
    @@ -672,7 +670,7 @@ if (! $error && $db->connected && $action == "set")
                     }
                     else
                     {
    -                    // Affiche aide diagnostique
    +                    // warning message
                         print '<tr><td colspan="2"><br>';
                         print $langs->trans("ErrorFailedToCreateDatabase",$dolibarr_main_db_name).'<br>';
                         print $newdb->lasterror().'<br>';
    @@ -693,7 +691,7 @@ if (! $error && $db->connected && $action == "set")
                     print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td>';
                     print '</tr>';
     
    -                // Affiche aide diagnostique
    +                // warning message
                     print '<tr><td colspan="2"><br>';
                     print $langs->trans("YouAskDatabaseCreationSoDolibarrNeedToConnect",$dolibarr_main_db_user,$dolibarr_main_db_host,$userroot);
                     print '<br>';
    @@ -703,7 +701,7 @@ if (! $error && $db->connected && $action == "set")
     
                     $error++;
                 }
    -        }   // Fin si "creation database"
    +        }   // end of create database
     
     
             // We test access with dolibarr database user (not admin)
    @@ -724,7 +722,7 @@ if (! $error && $db->connected && $action == "set")
                     print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
                     print "</td></tr>";
     
    -                // si acces serveur ok et acces base ok, tout est ok, on ne va pas plus loin, on a meme pas utilise le compte root.
    +                // server access ok, basic access ok
                     if ($db->database_selected)
                     {
                         dolibarr_install_syslog("step1: connection to database " . $conf->db->name . " by user " . $conf->db->user . " ok");
    @@ -747,7 +745,7 @@ if (! $error && $db->connected && $action == "set")
                         print '<img src="../theme/eldy/img/error.png" alt="Error">';
                         print "</td></tr>";
     
    -                    // Affiche aide diagnostique
    +                    // warning message
                         print '<tr><td colspan="2"><br>';
                         print $langs->trans('CheckThatDatabasenameIsCorrect',$dolibarr_main_db_name).'<br>';
                         print $langs->trans('IfAlreadyExistsCheckOption').'<br>';
    @@ -767,7 +765,7 @@ if (! $error && $db->connected && $action == "set")
                     print '<img src="../theme/eldy/img/error.png" alt="Error">';
                     print "</td></tr>";
     
    -                // Affiche aide diagnostique
    +                // warning message
                     print '<tr><td colspan="2"><br>';
                     print $langs->trans("ErrorConnection",$conf->db->host,$conf->db->name,$conf->db->user);
                     print $langs->trans('IfLoginDoesNotExistsCheckCreateUser').'<br>';
    @@ -1023,7 +1021,7 @@ function write_conf_file($conffile)
     
     		if (file_exists("$conffile"))
     		{
    -			include $conffile;	// On force rechargement. Ne pas mettre include_once !
    +			include $conffile;	// force config reload, do not put include_once
     			conf($dolibarr_main_document_root);
     
     			print "<tr><td>";
    diff --git a/htdocs/install/step2.php b/htdocs/install/step2.php
    index 30b3ff7d64f..4b12ba49432 100644
    --- a/htdocs/install/step2.php
    +++ b/htdocs/install/step2.php
    @@ -46,8 +46,7 @@ $action=GETPOST('action','aZ09')?GETPOST('action','aZ09'):(empty($argv[1])?'':$a
     $setuplang=GETPOST('selectlang','aZ09',3)?GETPOST('selectlang','aZ09',3):(empty($argv[2])?'auto':$argv[2]);
     $langs->setDefaultLang($setuplang);
     
    -$langs->load("admin");
    -$langs->load("install");
    +$langs->loadLangs(array("admin", "install"));
     
     $choix=0;
     if ($dolibarr_main_db_type == "mysqli") $choix=1;
    @@ -58,7 +57,7 @@ if ($dolibarr_main_db_type == "sqlite3")  $choix=5;
     
     //if (empty($choix)) dol_print_error('','Database type '.$dolibarr_main_db_type.' not supported into step2.php page');
     
    -// Now we load forced value from install.forced.php file.
    +// Now we load forced values from install.forced.php file.
     $useforcedwizard=false;
     $forcedfile="./install.forced.php";
     if ($conffile == "/etc/dolibarr/conf.php") $forcedfile="/etc/dolibarr/install.forced.php";
    @@ -67,7 +66,7 @@ if (@file_exists($forcedfile)) {
     	include_once $forcedfile;
     }
     
    -dolibarr_install_syslog("--- step2: entering step2.php page");
    +dolibarr_install_syslog("- step2: entering step2.php page");
     
     
     /*
    @@ -88,7 +87,7 @@ if ($action == "set")
     {
         print '<h3><img class="valigntextbottom" src="../theme/common/octicons/build/svg/database.svg" width="20" alt="Database"> '.$langs->trans("Database").'</h3>';
     
    -    print '<table cellspacing="0" style="padding: 4px 4px 4px 0px" border="0" width="100%">';
    +    print '<table cellspacing="0" style="padding: 4px 4px 4px 0" border="0" width="100%">';
         $error=0;
     
         $db=getDoliDBInstance($conf->db->type,$conf->db->host,$conf->db->user,$conf->db->pass,$conf->db->name,$conf->db->port);
    @@ -237,7 +236,7 @@ if ($action == "set")
                             print "<tr><td>".$langs->trans("CreateTableAndPrimaryKey",$name);
                             print "<br>\n".$langs->trans("Request").' '.$requestnb.' : '.$buffer.' <br>Executed query : '.$db->lastquery;
                             print "\n</td>";
    -                        print '<td><font class="error">'.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().'</font></td></tr>';
    +                        print '<td><span class="error">'.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().'</span></td></tr>';
                             $error++;
                         }
                     }
    @@ -246,7 +245,7 @@ if ($action == "set")
                 {
                     print "<tr><td>".$langs->trans("CreateTableAndPrimaryKey",$name);
                     print "</td>";
    -                print '<td><font class="error">'.$langs->trans("Error").' Failed to open file '.$dir.$file.'</td></tr>';
    +                print '<td><span class="error">'.$langs->trans("Error").' Failed to open file '.$dir.$file.'</span></td></tr>';
                     $error++;
                     dolibarr_install_syslog("step2: failed to open file " . $dir . $file, LOG_ERR);
                 }
    @@ -384,7 +383,7 @@ if ($action == "set")
                                     print "<tr><td>".$langs->trans("CreateOtherKeysForTable",$name);
                                     print "<br>\n".$langs->trans("Request").' '.$requestnb.' : '.$db->lastqueryerror();
                                     print "\n</td>";
    -                                print '<td><font class="error">'.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().'</font></td></tr>';
    +                                print '<td><span class="error">'.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().'</span></td></tr>';
                                     $error++;
                                 }
                             }
    @@ -395,7 +394,7 @@ if ($action == "set")
                 {
                     print "<tr><td>".$langs->trans("CreateOtherKeysForTable",$name);
                     print "</td>";
    -                print '<td><font class="error">'.$langs->trans("Error")." Failed to open file ".$dir.$file."</font></td></tr>";
    +                print '<td><span class="error">'.$langs->trans("Error")." Failed to open file ".$dir.$file."</span></td></tr>";
                     $error++;
                     dolibarr_install_syslog("step2: failed to open file " . $dir . $file, LOG_ERR);
                 }
    @@ -417,7 +416,7 @@ if ($action == "set")
          ***************************************************************************************/
         if ($ok && $createfunctions)
         {
    -        // For this file, we use directory according to database type
    +        // For this file, we use a directory according to database type
             if ($choix==1) $dir = "mysql/functions/";
             elseif ($choix==2) $dir = "pgsql/functions/";
             elseif ($choix==3) $dir = "mssql/functions/";
    @@ -473,7 +472,7 @@ if ($action == "set")
                                 print "<tr><td>".$langs->trans("FunctionsCreation");
                                 print "<br>\n".$langs->trans("Request").' '.$requestnb.' : '.$buffer;
                                 print "\n</td>";
    -                            print '<td><font class="error">'.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().'</font></td></tr>';
    +                            print '<td><span class="error">'.$langs->trans("ErrorSQL")." ".$db->errno()." ".$db->error().'</span></td></tr>';
                                 $error++;
                             }
                         }
    @@ -490,7 +489,6 @@ if ($action == "set")
                     print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
                     $ok = 1 ;
                 }
    -
             }
         }
     
    @@ -594,7 +592,7 @@ if ($action == "set")
                             {
                                 $ok = 0;
                                 $okallfile = 0;
    -                            print '<font class="error">'.$langs->trans("ErrorSQL")." : ".$db->lasterrno()." - ".$db->lastqueryerror()." - ".$db->lasterror()."</font><br>";
    +                            print '<span class="error">'.$langs->trans("ErrorSQL")." : ".$db->lasterrno()." - ".$db->lastqueryerror()." - ".$db->lasterror()."</span><br>";
                             }
                         }
                     }
    @@ -627,7 +625,7 @@ $ret=0;
     if (!$ok && isset($argv[1])) $ret=1;
     dolibarr_install_syslog("Exit ".$ret);
     
    -dolibarr_install_syslog("--- step2: end");
    +dolibarr_install_syslog("- step2: end");
     
     pFooter($ok?0:1,$setuplang);
     
    @@ -635,4 +633,3 @@ if (isset($db) && is_object($db)) $db->close();
     
     // Return code if ran from command line
     if ($ret) exit($ret);
    -
    diff --git a/htdocs/install/step4.php b/htdocs/install/step4.php
    index 92bcb3dc1a7..7a7b4e464fa 100644
    --- a/htdocs/install/step4.php
    +++ b/htdocs/install/step4.php
    @@ -35,8 +35,7 @@ global $langs;
     $setuplang=GETPOST('selectlang','aZ09',3)?GETPOST('selectlang','aZ09',3):(empty($argv[1])?'auto':$argv[1]);
     $langs->setDefaultLang($setuplang);
     
    -$langs->load("admin");
    -$langs->load("install");
    +$langs->loadLangs(array("admin", "install"));
     
     // Now we load forced value from install.forced.php file.
     $useforcedwizard=false;
    @@ -47,7 +46,7 @@ if (@file_exists($forcedfile)) {
     	include_once $forcedfile;
     }
     
    -dolibarr_install_syslog("--- step4: entering step4.php page");
    +dolibarr_install_syslog("- step4: entering step4.php page");
     
     $error=0;
     $ok = 0;
    @@ -74,18 +73,18 @@ print '<h3><img class="valigntextbottom" src="../theme/common/octicons/build/svg
     print $langs->trans("LastStepDesc").'<br><br>';
     
     
    -print '<table cellspacing="0" cellpadding="2" width="100%">';
    +print '<table cellspacing="0" cellpadding="2">';
     
     $db=getDoliDBInstance($conf->db->type,$conf->db->host,$conf->db->user,$conf->db->pass,$conf->db->name,$conf->db->port);
     
     if ($db->ok)
     {
    -    print '<tr><td>'.$langs->trans("Login").' :</td><td>';
    -	print '<input name="login" type="text" value="' . (!empty($_GET["login"]) ? GETPOST("login") : (isset($force_install_dolibarrlogin) ? $force_install_dolibarrlogin : '')) . '"' . (@$force_install_noedit == 2 && $force_install_dolibarrlogin !== null ? ' disabled' : '') . '></td></tr>';
    -    print '<tr><td>'.$langs->trans("Password").' :</td><td>';
    -    print '<input type="password" name="pass"></td></tr>';
    -    print '<tr><td>'.$langs->trans("PasswordAgain").' :</td><td>';
    -    print '<input type="password" name="pass_verif"></td></tr>';
    +    print '<tr><td><label for="login">'.$langs->trans("Login").' :</label></td><td>';
    +	print '<input id="login" name="login" type="text" value="' . (!empty($_GET["login"]) ? GETPOST("login") : (isset($force_install_dolibarrlogin) ? $force_install_dolibarrlogin : '')) . '"' . (@$force_install_noedit == 2 && $force_install_dolibarrlogin !== null ? ' disabled' : '') . '></td></tr>';
    +    print '<tr><td><label for="pass">'.$langs->trans("Password").' :</label></td><td>';
    +    print '<input type="password" id="pass" name="pass"></td></tr>';
    +    print '<tr><td><label for="pass_verif">'.$langs->trans("PasswordAgain").' :</label></td><td>';
    +    print '<input type="password" id="pass_verif" name="pass_verif"></td></tr>';
         print '</table>';
     
         if (isset($_GET["error"]) && $_GET["error"] == 1)
    @@ -110,15 +109,13 @@ if ($db->ok)
             print '<div class="error">'.$langs->trans("PleaseTypeALogin").'</div>';
             $error=0;	// We show button
         }
    -
     }
     
    -
     $ret=0;
     if ($error && isset($argv[1])) $ret=1;
     dolibarr_install_syslog("Exit ".$ret);
     
    -dolibarr_install_syslog("--- step4: end");
    +dolibarr_install_syslog("- step4: end");
     
     pFooter($error,$setuplang);
     
    diff --git a/htdocs/install/step5.php b/htdocs/install/step5.php
    index 79fead3c51d..b2d3083a624 100644
    --- a/htdocs/install/step5.php
    +++ b/htdocs/install/step5.php
    @@ -23,7 +23,7 @@
     /**
      *       \file      htdocs/install/step5.php
      *       \ingroup   install
    - *       \brief     Last page of upgrade or install process
    + *       \brief     Last page of upgrade / install process
      */
     
     include_once 'inc.php';
    @@ -52,8 +52,7 @@ if (! empty($action) && preg_match('/upgrade/i', $action))	// If it's an old upg
         }
     }
     
    -$langs->load("admin");
    -$langs->load("install");
    +$langs->loadLangs(array("admin", "install"));
     
     $login = GETPOST('login', 'alpha')?GETPOST('login', 'alpha'):(empty($argv[5])?'':$argv[5]);
     $pass = GETPOST('pass', 'alpha')?GETPOST('pass', 'alpha'):(empty($argv[6])?'':$argv[6]);
    @@ -67,7 +66,7 @@ if ($conffile == "/etc/dolibarr/conf.php") $forcedfile="/etc/dolibarr/install.fo
     if (@file_exists($forcedfile)) {
     	$useforcedwizard = true;
     	include_once $forcedfile;
    -	// If forced install is enabled, let's replace post values. These are empty because form fields are disabled.
    +	// If forced install is enabled, replace post values. These are empty because form fields are disabled.
     	if ($force_install_noedit == 2) {
     		if (!empty($force_install_dolibarrlogin)) {
     			$login = $force_install_dolibarrlogin;
    @@ -75,16 +74,15 @@ if (@file_exists($forcedfile)) {
     	}
     }
     
    -dolibarr_install_syslog("--- step5: entering step5.php page");
    +dolibarr_install_syslog("- step5: entering step5.php page");
     
     $error=0;
     
    -
     /*
      *	Actions
      */
     
    -// If install, check pass and pass_verif used to create admin account
    +// If install, check password and password_verification used to create admin account
     if ($action == "set") {
     	if ($pass <> $pass_verif) {
     		header("Location: step4.php?error=1&selectlang=$setuplang" . (isset($login) ? '&login=' . $login : ''));
    @@ -394,8 +392,8 @@ if ($action == "set" && $success)
         else
         {
             // If here MAIN_VERSION_LAST_UPGRADE is not empty
    -        print $langs->trans("VersionLastUpgrade").': <b><font class="ok">'.$conf->global->MAIN_VERSION_LAST_UPGRADE.'</font></b><br>';
    -        print $langs->trans("VersionProgram").': <b><font class="ok">'.DOL_VERSION.'</font></b><br>';
    +        print $langs->trans("VersionLastUpgrade").': <b><span class="ok">'.$conf->global->MAIN_VERSION_LAST_UPGRADE.'</span></b><br>';
    +        print $langs->trans("VersionProgram").': <b><span class="ok">'.DOL_VERSION.'</span></b><br>';
             print $langs->trans("MigrationNotFinished").'<br>';
             print "<br>";
     
    @@ -442,8 +440,8 @@ elseif (empty($action) || preg_match('/upgrade/i',$action))
         else
         {
             // If here MAIN_VERSION_LAST_UPGRADE is not empty
    -        print $langs->trans("VersionLastUpgrade").': <b><font class="ok">'.$conf->global->MAIN_VERSION_LAST_UPGRADE.'</font></b><br>';
    -        print $langs->trans("VersionProgram").': <b><font class="ok">'.DOL_VERSION.'</font></b>';
    +        print $langs->trans("VersionLastUpgrade").': <b><span class="ok">'.$conf->global->MAIN_VERSION_LAST_UPGRADE.'</span></b><br>';
    +        print $langs->trans("VersionProgram").': <b><span class="ok">'.DOL_VERSION.'</span></b>';
     
             print "<br>";
     
    @@ -457,17 +455,14 @@ else
         dol_print_error('','step5.php: unknown choice of action');
     }
     
    -
    -
     // Clear cache files
     clearstatcache();
     
    -
     $ret=0;
     if ($error && isset($argv[1])) $ret=1;
     dolibarr_install_syslog("Exit ".$ret);
     
    -dolibarr_install_syslog("--- step5: Dolibarr setup finished");
    +dolibarr_install_syslog("- step5: Dolibarr setup finished");
     
     pFooter(1,$setuplang);
     
    diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php
    index f6e1b535706..5f372f521f8 100644
    --- a/htdocs/install/upgrade.php
    +++ b/htdocs/install/upgrade.php
    @@ -66,10 +66,7 @@ $versionto=GETPOST("versionto",'alpha',3)?GETPOST("versionto",'',3):(empty($argv
     $dirmodule=((GETPOST("dirmodule",'alpha',3) && GETPOST("dirmodule",'alpha',3) != 'ignoredbversion'))?GETPOST("dirmodule",'alpha',3):((empty($argv[3]) || $argv[3] == 'ignoredbversion')?'':$argv[3]);
     $ignoredbversion=(GETPOST('ignoredbversion','alpha',3)=='ignoredbversion')?GETPOST('ignoredbversion','alpha',3):((empty($argv[3]) || $argv[3] != 'ignoredbversion')?'':$argv[3]);
     
    -$langs->load("admin");
    -$langs->load("install");
    -$langs->load("other");
    -$langs->load("errors");
    +$langs->loadLangs(array("admin", "install", "other", "errors"));
     
     if ($dolibarr_main_db_type == "mysqli") $choix=1;
     if ($dolibarr_main_db_type == "pgsql") $choix=2;
    @@ -300,7 +297,7 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09
                 		{
                 			if ($db->lasterrno() != 'DB_ERROR_NOSUCHTABLE')
                 			{
    -            				print '<tr><td colspan="2"><font  class="error">'.$sql.' : '.$db->lasterror()."</font></td></tr>\n";
    +            				print '<tr><td colspan="2"><span class="error">'.$sql.' : '.$db->lasterror()."</font></td></tr>\n";
                 			}
                 		}
                 	}
    diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php
    index 1077e37f78e..603d521f5ec 100644
    --- a/htdocs/install/upgrade2.php
    +++ b/htdocs/install/upgrade2.php
    @@ -73,10 +73,7 @@ $versionfrom=GETPOST("versionfrom",'alpha',3)?GETPOST("versionfrom",'alpha',3):(
     $versionto=GETPOST("versionto",'alpha',3)?GETPOST("versionto",'alpha',3):(empty($argv[2])?'':$argv[2]);
     $enablemodules=GETPOST("enablemodules",'alpha',3)?GETPOST("enablemodules",'alpha',3):(empty($argv[3])?'':$argv[3]);
     
    -$langs->load('admin');
    -$langs->load('install');
    -$langs->load("bills");
    -$langs->load("suppliers");
    +$langs->loadLangs(array("admin", "install", "bills", "suppliers"));
     
     if ($dolibarr_main_db_type == 'mysqli') $choix=1;
     if ($dolibarr_main_db_type == 'pgsql')  $choix=2;
    @@ -204,6 +201,8 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09
             $db->query($sql, 1);
             $sql = 'ALTER TABLE '.MAIN_DB_PREFIX.'user ADD COLUMN dateemployment date';
             $db->query($sql, 1);
    +        $sql = 'ALTER TABLE '.MAIN_DB_PREFIX.'user ADD COLUMN dateemploymentend date';
    +        $db->query($sql, 1);
             $sql = 'ALTER TABLE '.MAIN_DB_PREFIX.'user ADD COLUMN default_range integer';
             $db->query($sql, 1);
             $sql = 'ALTER TABLE '.MAIN_DB_PREFIX.'user ADD COLUMN default_c_exp_tax_cat integer';
    @@ -216,6 +215,8 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09
             $db->query($sql, 1);
             $sql = 'ALTER TABLE '.MAIN_DB_PREFIX."extrafields ADD COLUMN enabled varchar(255) DEFAULT '1'";
             $db->query($sql, 1);
    +        $sql = 'ALTER TABLE '.MAIN_DB_PREFIX.'extrafields ADD COLUMN help text';
    +        $db->query($sql, 1);
             $sql = 'ALTER TABLE '.MAIN_DB_PREFIX.'user_rights ADD COLUMN entity integer DEFAULT 1 NOT NULL';
             $db->query($sql, 1);
     
    @@ -440,6 +441,13 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09
             	migrate_rename_directories($db,$langs,$conf,'/contracts','/contract');
             }
     
    +        // Scripts for 9.0
    +        $afterversionarray=explode('.','8.0.9');
    +        $beforeversionarray=explode('.','9.0.9');
    +        if (versioncompare($versiontoarray,$afterversionarray) >= 0 && versioncompare($versiontoarray,$beforeversionarray) <= 0)
    +        {
    +        	//migrate_rename_directories($db,$langs,$conf,'/contracts','/contract');
    +        }
         }
     
     	// Code executed only if migration is LAST ONE. Must always be done.
    @@ -2287,7 +2295,6 @@ function migrate_detail_livraison($db,$langs,$conf)
                         print ". ";
                         $i++;
                     }
    -
                 }
     
                 if ($error == 0)
    @@ -2375,7 +2382,6 @@ function migrate_stocks($db,$langs,$conf)
                     print ". ";
                     $i++;
                 }
    -
             }
     
             if ($error == 0)
    @@ -2630,7 +2636,6 @@ function migrate_restore_missing_links($db,$langs,$conf)
                     //print ". ";
                     $i++;
                 }
    -
             }
             else print $langs->trans('AlreadyDone')."<br>\n";
     
    @@ -2696,7 +2701,6 @@ function migrate_restore_missing_links($db,$langs,$conf)
                     //print ". ";
                     $i++;
                 }
    -
             }
             else
             {
    @@ -4433,6 +4437,7 @@ function migrate_delete_old_files($db,$langs,$conf)
         DOL_DOCUMENT_ROOT.'/core/modules/modComptabiliteExpert.class.php',
         DOL_DOCUMENT_ROOT.'/core/modules/modCommercial.class.php',
         DOL_DOCUMENT_ROOT.'/core/modules/modProduit.class.php',
    +    DOL_DOCUMENT_ROOT.'/core/modules/modSkype.class.php',
         DOL_DOCUMENT_ROOT.'/phenix/inc/triggers/interface_modPhenix_Phenixsynchro.class.php',
         DOL_DOCUMENT_ROOT.'/webcalendar/inc/triggers/interface_modWebcalendar_webcalsynchro.class.php',
         DOL_DOCUMENT_ROOT.'/core/triggers/interface_modWebcalendar_Webcalsynchro.class.php',
    diff --git a/htdocs/langs/ar_SA/languages.lang b/htdocs/langs/ar_SA/languages.lang
    index 7b27cc35010..4519ef6078d 100644
    --- a/htdocs/langs/ar_SA/languages.lang
    +++ b/htdocs/langs/ar_SA/languages.lang
    @@ -1,6 +1,6 @@
     # Dolibarr language file - Source file is en_US - languages
     Language_ar_AR=العربية
    -Language_ar_EG=Arabic (Egypt)
    +Language_ar_EG=العربيه مصر
     Language_ar_SA=العربية
     Language_bn_BD=بنغالي
     Language_bg_BG=البلغارية
    @@ -86,3 +86,4 @@ Language_uz_UZ=الأوزبكي
     Language_vi_VN=الفيتنامية
     Language_zh_CN=الصينية
     Language_zh_TW=الصينية (التقليدية)
    +Language_bh_MY=الماليزية
    diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
    index 5ff295e38db..e2f6083e6a6 100644
    --- a/htdocs/langs/en_US/accountancy.lang
    +++ b/htdocs/langs/en_US/accountancy.lang
    @@ -36,8 +36,12 @@ AlreadyInGeneralLedger=Already journalized in ledgers
     NotYetInGeneralLedger=Not yet journalized in ledgers
     GroupIsEmptyCheckSetup=Group is empty, check setup of the personalized accounting group
     DetailByAccount=Show detail by account
    -AccountWithNonZeroValues=Accounts with non zero values
    +AccountWithNonZeroValues=Accounts with non-zero values
     ListOfAccounts=List of accounts
    +CountriesInEEC=Countries in EEC
    +CountriesNotInEEC=Countries not in EEC
    +CountriesInEECExceptMe=Countries in EEC except %s
    +CountriesExceptMe=All countries except %s
     
     MainAccountForCustomersNotDefined=Main accounting account for customers not defined in setup
     MainAccountForSuppliersNotDefined=Main accounting account for vendors not defined in setup
    @@ -54,19 +58,19 @@ AccountancyAreaDescJournalSetup=STEP %s: Create or check content of your journal
     AccountancyAreaDescChartModel=STEP %s: Create a model of chart of account from menu %s
     AccountancyAreaDescChart=STEP %s: Create or check content of your chart of account from menu %s
     
    -AccountancyAreaDescVat=STEP %s: Define accounting accounts for each VAT Rates. For this, use the menu entry %s.    
    +AccountancyAreaDescVat=STEP %s: Define accounting accounts for each VAT Rates. For this, use the menu entry %s.
     AccountancyAreaDescDefault=STEP %s: Define default accounting accounts. For this, use the menu entry %s.
     AccountancyAreaDescExpenseReport=STEP %s: Define default accounting accounts for each type of expense report. For this, use the menu entry %s.
    -AccountancyAreaDescSal=STEP %s: Define default accounting accounts for payment of salaries. For this, use the menu entry %s.    
    -AccountancyAreaDescContrib=STEP %s: Define default accounting accounts for special expences (miscellaneous taxes). For this, use the menu entry %s.    
    +AccountancyAreaDescSal=STEP %s: Define default accounting accounts for payment of salaries. For this, use the menu entry %s.
    +AccountancyAreaDescContrib=STEP %s: Define default accounting accounts for special expenses (miscellaneous taxes). For this, use the menu entry %s.
     AccountancyAreaDescDonation=STEP %s: Define default accounting accounts for donation. For this, use the menu entry %s.
     AccountancyAreaDescMisc=STEP %s: Define mandatory default account and default accounting accounts for miscellaneous transactions. For this, use the menu entry %s.
    -AccountancyAreaDescLoan=STEP %s: Define default accounting accounts for loans. For this, use the menu entry %s. 
    +AccountancyAreaDescLoan=STEP %s: Define default accounting accounts for loans. For this, use the menu entry %s.
     AccountancyAreaDescBank=STEP %s: Define accounting accounts and journal code for each bank and financial accounts. For this, use the menu entry %s.
     AccountancyAreaDescProd=STEP %s: Define accounting accounts on your products/services. For this, use the menu entry %s.
     
     AccountancyAreaDescBind=STEP %s: Check the binding between existing %s lines and accounting account is done, so application will be able to journalize transactions in Ledger in one click. Complete missing bindings. For this, use the menu entry %s.
    -AccountancyAreaDescWriteRecords=STEP %s: Write transactions into the Ledger. For this, go into menu <strong>%s</strong>, and click into button <strong>%s</strong>. 
    +AccountancyAreaDescWriteRecords=STEP %s: Write transactions into the Ledger. For this, go into menu <strong>%s</strong>, and click into button <strong>%s</strong>.
     AccountancyAreaDescAnalyze=STEP %s: Add or edit existing transactions and generate reports and exports.
     
     AccountancyAreaDescClosePeriod=STEP %s: Close period so we can't make modification in a future.
    @@ -156,12 +160,13 @@ Docref=Reference
     LabelAccount=Label account
     LabelOperation=Label operation
     Sens=Sens
    +LetteringCode=Lettering code
     Codejournal=Journal
     NumPiece=Piece number
     TransactionNumShort=Num. transaction
     AccountingCategory=Personalized groups
     GroupByAccountAccounting=Group by accounting account
    -AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports.  
    +AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports.
     ByAccounts=By accounts
     ByPredefinedAccountGroups=By predefined groups
     ByPersonalizedAccountGroups=By personalized groups
    @@ -187,7 +192,7 @@ NewAccountingMvt=New transaction
     NumMvts=Numero of transaction
     ListeMvts=List of movements
     ErrorDebitCredit=Debit and Credit cannot have a value at the same time
    -AddCompteFromBK=Add accounting accounts to the group 
    +AddCompteFromBK=Add accounting accounts to the group
     ReportThirdParty=List third party account
     DescThirdPartyReport=Consult here the list of the third party customers and vendors and their accounting accounts
     ListAccounts=List of the accounting accounts
    @@ -198,13 +203,13 @@ PaymentsNotLinkedToProduct=Payment not linked to any product / service
     
     Pcgtype=Group of account
     Pcgsubtype=Subgroup of account
    -PcgtypeDesc=Group and subgroup of account are used as predefined 'filter' and 'grouping' criterias for some accounting reports. For example, 'INCOME' or 'EXPENSE' are used as groups for accounting accounts of products to build the expense/income report.
    +PcgtypeDesc=Group and subgroup of account are used as predefined 'filter' and 'grouping' criteria for some accounting reports. For example, 'INCOME' or 'EXPENSE' are used as groups for accounting accounts of products to build the expense/income report.
     
     TotalVente=Total turnover before tax
     TotalMarge=Total sales margin
     
     DescVentilCustomer=Consult here the list of customer invoice lines bound (or not) to a product accounting account
    -DescVentilMore=In most cases, if you use predefined products or services and you set the account number on the product/service card, the application will be able to make all the binding between your invoice lines and the accounting account of your chart of accounts, just in one click with the button <strong>"%s"</strong>. If account was not set on product/service cards or if you still has some lines not bound to an account, you will have to make a manual binding from the menu "<strong>%s</strong>".  
    +DescVentilMore=In most cases, if you use predefined products or services and you set the account number on the product/service card, the application will be able to make all the binding between your invoice lines and the accounting account of your chart of accounts, just in one click with the button <strong>"%s"</strong>. If account was not set on product/service cards or if you still have some lines not bound to an account, you will have to make a manual binding from the menu "<strong>%s</strong>".
     DescVentilDoneCustomer=Consult here the list of the lines of invoices customers and their product accounting account
     DescVentilTodoCustomer=Bind invoice lines not already bound with a product accounting account
     ChangeAccount=Change the product/service accounting account for selected lines with the following accounting account:
    @@ -213,7 +218,7 @@ DescVentilSupplier=Consult here the list of vendor invoice lines bound or not ye
     DescVentilDoneSupplier=Consult here the list of the lines of invoices vendors and their accounting account
     DescVentilTodoExpenseReport=Bind expense report lines not already bound with a fee accounting account
     DescVentilExpenseReport=Consult here the list of expense report lines bound (or not) to a fee accounting account
    -DescVentilExpenseReportMore=If you setup accounting account on type of expense report lines, the application will be able to make all the binding between your expense report lines and the accounting account of your chart of accounts, just in one click with the button <strong>"%s"</strong>. If account was not set on fees dictionary or if you still has some lines not bound to any account, you will have to make a manual binding from the menu "<strong>%s</strong>".  
    +DescVentilExpenseReportMore=If you setup accounting account on type of expense report lines, the application will be able to make all the binding between your expense report lines and the accounting account of your chart of accounts, just in one click with the button <strong>"%s"</strong>. If account was not set on fees dictionary or if you still have some lines not bound to any account, you will have to make a manual binding from the menu "<strong>%s</strong>".
     DescVentilDoneExpenseReport=Consult here the list of the lines of expenses reports and their fees accounting account
     
     ValidateHistory=Bind Automatically
    @@ -221,6 +226,7 @@ AutomaticBindingDone=Automatic binding done
     
     ErrorAccountancyCodeIsAlreadyUse=Error, you cannot delete this accounting account because it is used
     MvtNotCorrectlyBalanced=Movement not correctly balanced. Debit = %s | Credit = %s
    +Balancing=Balancing
     FicheVentilation=Binding card
     GeneralLedgerIsWritten=Transactions are written in the Ledger
     GeneralLedgerSomeRecordWasNotRecorded=Some of the transactions could not be journalized. If there is no other error message, this is probably because they were already journalized.
    @@ -232,7 +238,7 @@ NotYetAccounted=Not yet accounted in ledger
     
     ## Admin
     ApplyMassCategories=Apply mass categories
    -AddAccountFromBookKeepingWithNoCategories=Available acccount not yet in a personalized group
    +AddAccountFromBookKeepingWithNoCategories=Available account not yet in a personalized group
     CategoryDeleted=Category for the accounting account has been removed
     AccountingJournals=Accounting journals
     AccountingJournal=Accounting journal
    @@ -262,7 +268,8 @@ Modelcsv_quadratus=Export towards Quadratus QuadraCompta
     Modelcsv_ebp=Export towards EBP
     Modelcsv_cogilog=Export towards Cogilog
     Modelcsv_agiris=Export towards Agiris
    -Modelcsv_configurable=Export Configurable
    +Modelcsv_configurable=Export CSV Configurable
    +Modelcsv_FEC=Export FEC (Art. L47 A) (Test)
     ChartofaccountsId=Chart of accounts Id
     
     ## Tools - Init accounting account on product / service
    @@ -292,7 +299,7 @@ ErrorNoAccountingCategoryForThisCountry=No accounting account group available fo
     ErrorInvoiceContainsLinesNotYetBounded=You try to journalize some lines of the invoice <strong>%s</strong>, but some other lines are not yet bounded to accounting account. Journalization of all invoice lines for this invoice are refused.
     ErrorInvoiceContainsLinesNotYetBoundedShort=Some lines on invoice are not bound to accounting account.
     ExportNotSupported=The export format setuped is not supported into this page
    -BookeppingLineAlreayExists=Lines already existing into bookeeping
    +BookeppingLineAlreayExists=Lines already existing into bookkeeping
     NoJournalDefined=No journal defined
     Binded=Lines bound
     ToBind=Lines to bind
    @@ -301,6 +308,6 @@ UseMenuToSetBindindManualy=Lines not yet bound, use menu <a href="%s">%s</a> to
     ## Import
     ImportAccountingEntries=Accounting entries
     
    -WarningReportNotReliable=Warning, this report is not based on the Ledger, so does not contains transaction modified manualy in the Ledger. If your journalization is up to date, the bookkeeping view is more accurate.
    +WarningReportNotReliable=Warning, this report is not based on the Ledger, so does not contains transaction modified manually in the Ledger. If your journalization is up to date, the bookkeeping view is more accurate.
     ExpenseReportJournal=Expense Report Journal
     InventoryJournal=Inventory Journal
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index cbe085f3149..190b7cded97 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -10,9 +10,9 @@ VersionDevelopment=Development
     VersionUnknown=Unknown
     VersionRecommanded=Recommended
     FileCheck=Files integrity checker
    -FileCheckDesc=This tool allows you to check the integrity of files and setup of your application, comparing each files with the official ones. Value of some setup constants may also be checked. You can use this tool to detect if some files were modified by a hacker for example.
    +FileCheckDesc=This tool allows you to check the integrity of files and the setup of your application, comparing each file with the official one. The value of some setup constants may also be checked. You can use this tool to detect if some files were modified by a hacker, for example.
     FileIntegrityIsStrictlyConformedWithReference=Files integrity is strictly conformed with the reference.
    -FileIntegrityIsOkButFilesWereAdded=Files integrity check has passed, however some new files were added.
    +FileIntegrityIsOkButFilesWereAdded=Files integrity check has passed, however some new files have been added.
     FileIntegritySomeFilesWereRemovedOrModified=Files integrity check has failed. Some files were modified, removed or added.
     GlobalChecksum=Global checksum
     MakeIntegrityAnalysisFrom=Make integrity analysis of application files from
    @@ -23,21 +23,21 @@ FilesUpdated=Updated Files
     FilesModified=Modified Files
     FilesAdded=Added Files
     FileCheckDolibarr=Check integrity of application files
    -AvailableOnlyOnPackagedVersions=The local file for integrity checking is only available when application is installed from an official package 
    +AvailableOnlyOnPackagedVersions=The local file for integrity checking is only available when application is installed from an official package
     XmlNotFound=Xml Integrity File of application not found
     SessionId=Session ID
     SessionSaveHandler=Handler to save sessions
     SessionSavePath=Storage session localization
     PurgeSessions=Purge of sessions
     ConfirmPurgeSessions=Do you really want to purge all sessions? This will disconnect every user (except yourself).
    -NoSessionListWithThisHandler=Save session handler configured in your PHP does not allow to list all running sessions.
    +NoSessionListWithThisHandler=Save session handler configured in your PHP does not allow listing all running sessions.
     LockNewSessions=Lock new connections
    -ConfirmLockNewSessions=Are you sure you want to restrict any new Dolibarr connection to yourself. Only user <b>%s</b> will be able to connect after that. 
    +ConfirmLockNewSessions=Are you sure you want to restrict any new Dolibarr connection to yourself? Only user <b>%s</b> will be able to connect after that.
     UnlockNewSessions=Remove connection lock
     YourSession=Your session
    -Sessions=Users session
    +Sessions=Users sessions
     WebUserGroup=Web server user/group
    -NoSessionFound=Your PHP seems to not allow to list active sessions. Directory used to save sessions (<b>%s</b>) might be protected (For example, by OS permissions or by PHP directive open_basedir).
    +NoSessionFound=Your PHP seems to not allow listing of active sessions. The directory used to save sessions (<b>%s</b>) might be protected (For example, by OS permissions or by PHP directive open_basedir).
     DBStoringCharset=Database charset to store data
     DBSortingCharset=Database charset to sort data
     ClientCharset=Client charset
    @@ -50,7 +50,7 @@ ExternalUser=External user
     InternalUsers=Internal users
     ExternalUsers=External users
     GUISetup=Display
    -SetupArea=Setup area
    +SetupArea=Setup
     UploadNewTemplate=Upload new template(s)
     FormToTestFileUploadForm=Form to test file upload (according to setup)
     IfModuleEnabled=Note: yes is effective only if module <b>%s</b> is enabled
    @@ -80,7 +80,7 @@ PreviewNotAvailable=Preview not available
     ThemeCurrentlyActive=Theme currently active
     CurrentTimeZone=TimeZone PHP (server)
     MySQLTimeZone=TimeZone MySql (database)
    -TZHasNoEffect=Dates are stored and returned by database server as if they were kept as submited string. The timezone has effect only when using UNIX_TIMESTAMP function (that should not be used by Dolibarr, so database TZ should have no effect, even if changed after data was entered). 
    +TZHasNoEffect=Dates are stored and returned by database server as if they were kept as submitted string. The timezone has effect only when using the UNIX_TIMESTAMP function (that should not be used by Dolibarr, so database TZ should have no effect, even if changed after data was entered).
     Space=Space
     Table=Table
     Fields=Fields
    @@ -96,9 +96,9 @@ NoMaxSizeByPHPLimit=Note: No limit is set in your PHP configuration
     MaxSizeForUploadedFiles=Maximum size for uploaded files (0 to disallow any upload)
     UseCaptchaCode=Use graphical code (CAPTCHA) on login page
     AntiVirusCommand= Full path to antivirus command
    -AntiVirusCommandExample= Example for ClamWin: c:\Progra~1\ClamWin\bin\clamscan.exe<br>Example for ClamAv: /usr/bin/clamscan
    +AntiVirusCommandExample= Example for ClamWin: c:\\Progra~1\\ClamWin\\bin\\clamscan.exe<br>Example for ClamAv: /usr/bin/clamscan
     AntiVirusParam= More parameters on command line
    -AntiVirusParamExample= Example for ClamWin: --database="C:\Program Files (x86)\ClamWin\lib"
    +AntiVirusParamExample= Example for ClamWin: --database="C:\\Program Files (x86)\\ClamWin\\lib"
     ComptaSetup=Accounting module setup
     UserSetup=User management setup
     MultiCurrencySetup=Multi-currency setup
    @@ -111,14 +111,14 @@ NotConfigured=Module/Application not configured
     Active=Active
     SetupShort=Setup
     OtherOptions=Other options
    -OtherSetup=Other setup
    +OtherSetup=Other Setup
     CurrentValueSeparatorDecimal=Decimal separator
     CurrentValueSeparatorThousand=Thousand separator
     Destination=Destination
     IdModule=Module ID
     IdPermissions=Permissions ID
     LanguageBrowserParameter=Parameter %s
    -LocalisationDolibarrParameters=Localisation parameters
    +LocalisationDolibarrParameters=Localization parameters
     ClientTZ=Client Time Zone (user)
     ClientHour=Client time (user)
     OSTZ=Server OS Time Zone
    @@ -126,8 +126,8 @@ PHPTZ=PHP server Time Zone
     DaylingSavingTime=Daylight saving time
     CurrentHour=PHP Time (server)
     CurrentSessionTimeOut=Current session timeout
    -YouCanEditPHPTZ=To set a different PHP timezone (not required), you can try to add a file .htaccess with a line like this "SetEnv TZ Europe/Paris"
    -HoursOnThisPageAreOnServerTZ=Warning, in contrary of other screens, hours on this page are not in your local timezone, but for the timezone of the server.
    +YouCanEditPHPTZ=To set a different PHP timezone (not required), you can try to add a .htaccess file with a line like this "SetEnv TZ Europe/Paris"
    +HoursOnThisPageAreOnServerTZ=Warning, in contrary of other screens, hours on this page are not in your local timezone, but of the timezone of the server.
     Box=Widget
     Boxes=Widgets
     MaxNbOfLinesForBoxes=Max number of lines for widgets
    @@ -184,22 +184,22 @@ AddDropTable=Add DROP TABLE command
     ExportStructure=Structure
     NameColumn=Name columns
     ExtendedInsert=Extended INSERT
    -NoLockBeforeInsert=No lock commands around INSERT 
    +NoLockBeforeInsert=No lock commands around INSERT
     DelayedInsert=Delayed insert
     EncodeBinariesInHexa=Encode binary data in hexadecimal
     IgnoreDuplicateRecords=Ignore errors of duplicate record (INSERT IGNORE)
     AutoDetectLang=Autodetect (browser language)
     FeatureDisabledInDemo=Feature disabled in demo
     FeatureAvailableOnlyOnStable=Feature only available on official stable versions
    -BoxesDesc=Widgets are components showing some information that you can add to personalize some pages. You can choose between showing the widget or not by selecting target page and clicking 'Activate', or by clicking the dustbin to disable it.
    +BoxesDesc=Widgets are components showing some information that you can add to personalize some pages. You can choose between showing the widget or not by selecting target page and clicking 'Activate', or by clicking the trashcan to disable it.
     OnlyActiveElementsAreShown=Only elements from <a href="%s">enabled modules</a> are shown.
    -ModulesDesc=Dolibarr modules define which application/feature is enabled in software. Some application/modules require permissions you must grant to users, after activating it. Click on button on/off to enable a module/application.
    +ModulesDesc=The modules/applications determine which features are available in the software. Some modules require permissions to be granted to users after activating the module. Click the on/off button to enable/disable a module/application.
     ModulesMarketPlaceDesc=You can find more modules to download on external websites on the Internet...
    -ModulesDeployDesc=If permissions on your file system allows it, you can use this tool to deploy an external module. The module wil then be visible on the tab <strong>%s</strong>.
    +ModulesDeployDesc=If permissions on your file system allow it, you can use this tool to deploy an external module. The module will then be visible on the tab <strong>%s</strong>.
     ModulesMarketPlaces=Find external app/modules
     ModulesDevelopYourModule=Develop your own app/modules
    -ModulesDevelopDesc=You can develop or find a partner to develop for you, your personalised module
    -DOLISTOREdescriptionLong=Instead of switching on <a href="https://www.dolistore.com">www.dolistore.com</a> web site to find an external module, you can use this embedded tool that will make the seach on the external market place for you (may be slow, need an internet access)...
    +ModulesDevelopDesc=You may also develop your own module or find a partner to develop one for you.
    +DOLISTOREdescriptionLong=Instead of switching on <a href="https://www.dolistore.com">www.dolistore.com</a> web site to find an external module, you can use this embedded tool that will perform the search on the external market place for you (may be slow, need an internet access)...
     NewModule=New
     FreeModule=Free
     CompatibleUpTo=Compatible with version %s
    @@ -208,11 +208,11 @@ CompatibleAfterUpdate=This module requires an update to your Dolibarr %s (Min %s
     SeeInMarkerPlace=See in Market place
     Updated=Updated
     Nouveauté=Novelty
    -AchatTelechargement=Buy / Download 
    +AchatTelechargement=Buy / Download
     GoModuleSetupArea=To deploy/install a new module, go onto the Module setup area at <a href="%s">%s</a>.
     DoliStoreDesc=DoliStore, the official market place for Dolibarr ERP/CRM external modules
    -DoliPartnersDesc=List of companies providing custom developed modules or features (Note: anyone experienced in PHP programming can provide custom development for an open source project)
    -WebSiteDesc=Reference websites to find more modules...
    +DoliPartnersDesc=List of companies providing custom-developed modules or features.<br>Note: since Dolibarr is an open source application, <i>anyone</i> experienced in PHP programming may develop a module.
    +WebSiteDesc=External websites for more add-on (non-core) modules...
     DevelopYourModuleDesc=Some solutions to develop your own module...
     URL=Link
     BoxesAvailable=Widgets available
    @@ -229,7 +229,7 @@ DoNotStoreClearPassword=Do no store clear passwords in database but store only e
     MainDbPasswordFileConfEncrypted=Database password encrypted in conf.php (Activated recommended)
     InstrucToEncodePass=To have password encoded into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="...";</b><br>by<br><b>$dolibarr_main_db_pass="crypted:%s";</b>
     InstrucToClearPass=To have password decoded (clear) into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="crypted:...";</b><br>by<br><b>$dolibarr_main_db_pass="%s";</b>
    -ProtectAndEncryptPdfFiles=Protection of generated pdf files (Activated NOT recommended, breaks mass pdf generation)
    +ProtectAndEncryptPdfFiles=Protection of generated PDF files NOT recommended (breaks mass PDF generation)
     ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature makes building of a global merged PDFs not working.
     Feature=Feature
     DolibarrLicense=License
    @@ -246,8 +246,8 @@ ExternalResources=External resources
     SocialNetworks=Social Networks
     ForDocumentationSeeWiki=For user or developer documentation (Doc, FAQs...),<br>take a look at the Dolibarr Wiki:<br><b><a href="%s" target="_blank">%s</a></b>
     ForAnswersSeeForum=For any other questions/help, you can use the Dolibarr forum:<br><b><a href="%s" target="_blank">%s</a></b>
    -HelpCenterDesc1=This area can help you to get a Help support service on Dolibarr.
    -HelpCenterDesc2=Some part of this service are available in <b>english only</b>.
    +HelpCenterDesc1=Here are some resources for getting help and support with Dolibarr.
    +HelpCenterDesc2=Some of these resources are only available in <b>english</b>.
     CurrentMenuHandler=Current menu handler
     MeasuringUnit=Measuring unit
     LeftMargin=Left margin
    @@ -262,31 +262,31 @@ NoticePeriod=Notice period
     NewByMonth=New by month
     Emails=Emails
     EMailsSetup=Emails setup
    -EMailsDesc=This page allows you to overwrite your PHP parameters for emails sending. In most cases on Unix/Linux OS, your PHP setup is correct and these parameters are useless.
    +EMailsDesc=This page allows you to override your default PHP parameters for email sending. In most cases on Unix/Linux OS, the PHP setup is correct and these parameters are unnecessary.
     EmailSenderProfiles=Emails sender profiles
    -MAIN_MAIL_SMTP_PORT=SMTP/SMTPS Port (By default in php.ini: <b>%s</b>)
    -MAIN_MAIL_SMTP_SERVER=SMTP/SMTPS Host (By default in php.ini: <b>%s</b>)
    -MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike=SMTP/SMTPS Port (Not defined into PHP on Unix like systems)
    -MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike=SMTP/SMTPS Host (Not defined into PHP on Unix like systems)
    -MAIN_MAIL_EMAIL_FROM=Sender email for automatic emails (By default in php.ini: <b>%s</b>)
    -MAIN_MAIL_ERRORS_TO=Eemail used for error returns emails (fields 'Errors-To' in emails sent)
    -MAIN_MAIL_AUTOCOPY_TO= Send systematically a hidden carbon-copy of all sent emails to
    -MAIN_DISABLE_ALL_MAILS=Disable all emails sendings (for test purposes or demos)
    +MAIN_MAIL_SMTP_PORT=SMTP/SMTPS Port (default value in php.ini: <b>%s</b>)
    +MAIN_MAIL_SMTP_SERVER=SMTP/SMTPS Host (default value in php.ini: <b>%s</b>)
    +MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike=SMTP/SMTPS Port (Not defined into PHP on Unix-like systems)
    +MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike=SMTP/SMTPS Host (Not defined into PHP on Unix-like systems)
    +MAIN_MAIL_EMAIL_FROM=Sender email for automatic emails (default value in php.ini: <b>%s</b>)
    +MAIN_MAIL_ERRORS_TO=Email used for error returns emails (fields 'Errors-To' in emails sent)
    +MAIN_MAIL_AUTOCOPY_TO= Copy (Bcc) all sent emails to
    +MAIN_DISABLE_ALL_MAILS=Disable all email sending (for test purposes or demos)
     MAIN_MAIL_FORCE_SENDTO=Send all emails to (instead of real recipients, for test purposes)
    -MAIN_MAIL_ENABLED_USER_DEST_SELECT=Add employees users with email into allowed destinaries list
    -MAIN_MAIL_SENDMODE=Method to use to send EMails
    -MAIN_MAIL_SMTPS_ID=SMTP ID if authentication required
    -MAIN_MAIL_SMTPS_PW=SMTP Password if authentication required
    -MAIN_MAIL_EMAIL_TLS= Use TLS (SSL) encrypt
    -MAIN_MAIL_EMAIL_STARTTLS= Use TLS (STARTTLS) encrypt
    -MAIN_DISABLE_ALL_SMS=Disable all SMS sendings (for test purposes or demos)
    +MAIN_MAIL_ENABLED_USER_DEST_SELECT=Add employee users with email into allowed recipient list
    +MAIN_MAIL_SENDMODE=Email sending method
    +MAIN_MAIL_SMTPS_ID=SMTP ID (if sending server requires authentication)
    +MAIN_MAIL_SMTPS_PW=SMTP Password (if sending server requires authentication)
    +MAIN_MAIL_EMAIL_TLS= Use TLS (SSL) encryption
    +MAIN_MAIL_EMAIL_STARTTLS= Use TLS (STARTTLS) encryption
    +MAIN_DISABLE_ALL_SMS=Disable all SMS sending (for test purposes or demos)
     MAIN_SMS_SENDMODE=Method to use to send SMS
    -MAIN_MAIL_SMS_FROM=Default sender phone number for Sms sending
    -MAIN_MAIL_DEFAULT_FROMTYPE=Sender email by default for manual sendings (User email or Company email)
    +MAIN_MAIL_SMS_FROM=Default sender phone number for SMS sending
    +MAIN_MAIL_DEFAULT_FROMTYPE=Default sender email for manual sending (User email or Company email)
     UserEmail=User email
     CompanyEmail=Company email
     FeatureNotAvailableOnLinux=Feature not available on Unix like systems. Test your sendmail program locally.
    -SubmitTranslation=If translation for this language is not complete or you find errors, you can correct this by editing files into directory <b>langs/%s</b> and submit your change to www.transifex.com/dolibarr-association/dolibarr/
    +SubmitTranslation=If translation for this language is not complete or you find errors, you can correct this by editing files in directory <b>langs/%s</b> and submit your change to www.transifex.com/dolibarr-association/dolibarr/
     SubmitTranslationENUS=If translation for this language is not complete or you find errors, you can correct this by editing files into directory <b>langs/%s</b> and submit modified files on dolibarr.org/forum or for developers on github.com/Dolibarr/dolibarr.
     ModuleSetup=Module setup
     ModulesSetup=Modules/Application setup
    @@ -309,15 +309,15 @@ DoNotUseInProduction=Do not use in production
     ThisIsProcessToFollow=This is steps to process:
     ThisIsAlternativeProcessToFollow=This is an alternative setup to process manually:
     StepNb=Step %s
    -FindPackageFromWebSite=Find a package that provides feature you want (for example on official web site %s).
    +FindPackageFromWebSite=Find a package that provides features you want (for example on official web site %s).
     DownloadPackageFromWebSite=Download package (for example from official web site %s).
    -UnpackPackageInDolibarrRoot=Unpack the packaged files into server directory dedicated to Dolibarr: <b>%s</b>
    -UnpackPackageInModulesRoot=To deploy/install an external module, unpack the packaged files into the server directory dedicated to modules: <b>%s</b>
    -SetupIsReadyForUse=Module deployment is finished. You must however enable and setup the module in your application by going on the page to setup modules: <a href="%s">%s</a>.
    +UnpackPackageInDolibarrRoot=Unpack/unzip the packaged files into the server directory dedicated to Dolibarr: <b>%s</b>
    +UnpackPackageInModulesRoot=To deploy/install an external module, unpack/unzip the packaged files into the server directory dedicated to external modules:<br><b>%s</b>
    +SetupIsReadyForUse=Module deployment is finished. You must however enable and setup the module in your application by going to the page setup modules: <a href="%s">%s</a>.
     NotExistsDirect=The alternative root directory is not defined to an existing directory.<br>
     InfDirAlt=Since version 3, it is possible to define an alternative root directory. This allows you to store, into a dedicated directory, plug-ins and custom templates.<br>Just create a directory at the root of Dolibarr (eg: custom).<br>
     InfDirExample=<br>Then declare it in the file <strong>conf.php</strong><br> $dolibarr_main_url_root_alt='/custom'<br>$dolibarr_main_document_root_alt='/path/of/dolibarr/htdocs/custom'<br>If these lines are commented with "#", to enable them, just uncomment by removing the "#" character.
    -YouCanSubmitFile=For this step, you can submit the .zip file of module package here :
    +YouCanSubmitFile=Alternatively, you may upload the module .zip file package:
     CurrentVersion=Dolibarr current version
     CallUpdatePage=Go to the page that updates the database structure and data: %s.
     LastStableVersion=Latest stable version
    @@ -333,7 +333,7 @@ GenericMaskCodes4a=<u>Example on the 99th %s of the third party TheCompany, with
     GenericMaskCodes4b=<u>Example on third party created on 2007-03-01:</u><br>
     GenericMaskCodes4c=<u>Example on product created on 2007-03-01:</u><br>
     GenericMaskCodes5=<b>ABC{yy}{mm}-{000000}</b> will give <b>ABC0701-000099</b><br><b>{0000+100@1}-ZZZ/{dd}/XXX</b> will give <b>0199-ZZZ/31/XXX</b><br><b>IN{yy}{mm}-{0000}-{t}</b> will give <b>IN0701-0099-A</b> if the type of company is 'Responsable Inscripto' with code for type that is 'A_RI'
    -GenericNumRefModelDesc=Returns a customizable number according to a defined mask. 
    +GenericNumRefModelDesc=Returns a customizable number according to a defined mask.
     ServerAvailableOnIPOrPort=Server is available at address <b>%s</b> on port <b>%s</b>
     ServerNotAvailableOnIPOrPort=Server is not available at address <b>%s</b> on port <b>%s</b>
     DoTestServerAvailability=Test server connectivity
    @@ -347,37 +347,37 @@ SeeWikiForAllTeam=Take a look at the wiki page for full list of all actors and t
     UseACacheDelay= Delay for caching export response in seconds (0 or empty for no cache)
     DisableLinkToHelpCenter=Hide link "<b>Need help or support</b>" on login page
     DisableLinkToHelp=Hide link to online help "<b>%s</b>"
    -AddCRIfTooLong=There is no automatic wrapping, so if line is out of page on documents because too long, you must add yourself carriage returns in the textarea.
    -ConfirmPurge=Are you sure you want to execute this purge?<br>This will delete definitely all your data files with no way to restore them (ECM files, attached files...). 
    +AddCRIfTooLong=There is no automatic text wrapping, text that is too long will not display on documents. Please add carriage returns in the text area if needed.
    +ConfirmPurge=Are you sure you want to execute this purge?<br>This will permanently delete all your data files with no way to restore them (ECM files, attached files...).
     MinLength=Minimum length
     LanguageFilesCachedIntoShmopSharedMemory=Files .lang loaded in shared memory
     LanguageFile=Language file
    -ExamplesWithCurrentSetup=Examples with current running setup
    +ExamplesWithCurrentSetup=Examples with current configuration
     ListOfDirectories=List of OpenDocument templates directories
    -ListOfDirectoriesForModelGenODT=List of directories containing templates files with OpenDocument format.<br><br>Put here full path of directories.<br>Add a carriage return between eah directory.<br>To add a directory of the GED module, add here <b>DOL_DATA_ROOT/ecm/yourdirectoryname</b>.<br><br>Files in those directories must end with <b>.odt</b> or <b>.ods</b>. 
    +ListOfDirectoriesForModelGenODT=List of directories containing templates files with OpenDocument format.<br><br>Put here full path of directories.<br>Add a carriage return between eah directory.<br>To add a directory of the GED module, add here <b>DOL_DATA_ROOT/ecm/yourdirectoryname</b>.<br><br>Files in those directories must end with <b>.odt</b> or <b>.ods</b>.
     NumberOfModelFilesFound=Number of ODT/ODS template files found in these directories
    -ExampleOfDirectoriesForModelGen=Examples of syntax:<br>c:\mydir<br>/home/mydir<br>DOL_DATA_ROOT/ecm/ecmdir
    -FollowingSubstitutionKeysCanBeUsed=<br>To know how to create your odt document templates, before storing them in those directories, read wiki documentation: 
    +ExampleOfDirectoriesForModelGen=Examples of syntax:<br>c:\\mydir<br>/home/mydir<br>DOL_DATA_ROOT/ecm/ecmdir
    +FollowingSubstitutionKeysCanBeUsed=<br>To know how to create your odt document templates, before storing them in those directories, read wiki documentation:
     FullListOnOnlineDocumentation=http://wiki.dolibarr.org/index.php/Create_an_ODT_document_template
     FirstnameNamePosition=Position of Name/Lastname
     DescWeather=The following pictures will be shown on dashboard when number of late actions reach the following values:
     KeyForWebServicesAccess=Key to use Web Services (parameter "dolibarrkey" in webservices)
     TestSubmitForm=Input test form
    -ThisForceAlsoTheme=Using this menu manager will also use its own theme whatever is user choice. Also this menu manager specialized for smartphones does not works on all smartphone. Use another menu manager if you experience problems on yours. 
    +ThisForceAlsoTheme=Using this menu manager will also use its own theme whatever is user choice. Also this menu manager specialized for smartphones does not works on all smartphone. Use another menu manager if you experience problems on yours.
     ThemeDir=Skins directory
    -ConnectionTimeout=Connexion timeout
    +ConnectionTimeout=Connection timeout
     ResponseTimeout=Response timeout
     SmsTestMessage=Test message from __PHONEFROM__ to __PHONETO__
     ModuleMustBeEnabledFirst=Module <b>%s</b> must be enabled first if you need this feature.
     SecurityToken=Key to secure URLs
    -NoSmsEngine=No SMS sender manager available. SMS sender manager are not installed with default distribution (because they depends on an external supplier) but you can find some on %s
    +NoSmsEngine=No SMS sender manager available. A SMS sender manager is not installed with the default distribution because they depend on an external supplier, but you can find some on %s
     PDF=PDF
    -PDFDesc=You can set each global options related to the PDF generation
    +PDFDesc=You can set each global option related to the PDF generation
     PDFAddressForging=Rules to forge address boxes
     HideAnyVATInformationOnPDF=Hide all information related to Sales tax / VAT on generated PDF
     PDFRulesForSalesTax=Rules for Sales Tax / VAT
     PDFLocaltax=Rules for %s
    -HideLocalTaxOnPDF=Hide %s rate into pdf column tax sale
    +HideLocalTaxOnPDF=Hide %s rate in pdf column tax sale
     HideDescOnPDF=Hide products description on generated PDF
     HideRefOnPDF=Hide products ref. on generated PDF
     HideDetailsOnPDF=Hide product lines details on generated PDF
    @@ -387,7 +387,7 @@ UrlGenerationParameters=Parameters to secure URLs
     SecurityTokenIsUnique=Use a unique securekey parameter for each URL
     EnterRefToBuildUrl=Enter reference for object %s
     GetSecuredUrl=Get calculated URL
    -ButtonHideUnauthorized=Hide buttons to non admin users for unauthorized actions instead of showing greyed disabled buttons
    +ButtonHideUnauthorized=Hide buttons for non-admin users for unauthorized actions instead of showing greyed disabled buttons
     OldVATRates=Old VAT rate
     NewVATRates=New VAT rate
     PriceBaseTypeToChange=Modify on prices with base reference value defined on
    @@ -408,13 +408,13 @@ ExtrafieldSelect = Select list
     ExtrafieldSelectList = Select from table
     ExtrafieldSeparator=Separator (not a field)
     ExtrafieldPassword=Password
    -ExtrafieldRadio=Radio buttons (on choice only)
    +ExtrafieldRadio=Radio buttons (one choice only)
     ExtrafieldCheckBox=Checkboxes
     ExtrafieldCheckBoxFromList=Checkboxes from table
     ExtrafieldLink=Link to an object
     ComputedFormula=Computed field
     ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: <strong>$db, $conf, $langs, $mysoc, $user, $object</strong>.<br><strong>WARNING</strong>: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.<br>Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.<br><br>Example of formula:<br>$object->id < 10 ? round($object->id / 2, 2) : ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)<br><br>Example to reload object<br>(($reloadedobj = new Societe($db)) && ($reloadedobj->fetch($obj->id ? $obj->id : ($obj->rowid ? $obj->rowid : $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5 : '-1'<br><br>Other example of formula to force load of object and its parent object:<br>(($reloadedobj = new Task($db)) && ($reloadedobj->fetch($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetch($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : 'Parent project not found'
    -ExtrafieldParamHelpPassword=Keep this field empty means value will be stored without encryption (field must be only hidden with star on screen).<br>Set here value 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retreive original value)
    +ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).<br>Set  'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value)
     ExtrafieldParamHelpselect=List of values must be lines with format key,value (where key can't be '0')<br><br> for example : <br>1,value1<br>2,value2<br>code3,value3<br>...<br><br>In order to have the list depending on another complementary attribute list :<br>1,value1|options_<i>parent_list_code</i>:parent_key<br>2,value2|options_<i>parent_list_code</i>:parent_key <br><br>In order to have the list depending on another list :<br>1,value1|<i>parent_list_code</i>:parent_key<br>2,value2|<i>parent_list_code</i>:parent_key
     ExtrafieldParamHelpcheckbox=List of values must be lines with format key,value (where key can't be '0')<br><br> for example : <br>1,value1<br>2,value2<br>3,value3<br>...
     ExtrafieldParamHelpradio=List of values must be lines with format key,value (where key can't be '0')<br><br> for example : <br>1,value1<br>2,value2<br>3,value3<br>...
    @@ -432,14 +432,14 @@ DefaultLink=Default link
     SetAsDefault=Set as default
     ValueOverwrittenByUserSetup=Warning, this value may be overwritten by user specific setup (each user can set his own clicktodial url)
     ExternalModule=External module - Installed into directory %s
    -BarcodeInitForThirdparties=Mass barcode init for thirdparties
    +BarcodeInitForthird-parties=Mass barcode init for third-parties
     BarcodeInitForProductsOrServices=Mass barcode init or reset for products or services
     CurrentlyNWithoutBarCode=Currently, you have <strong>%s</strong> record on <strong>%s</strong> %s without barcode defined.
     InitEmptyBarCode=Init value for next %s empty records
     EraseAllCurrentBarCode=Erase all current barcode values
     ConfirmEraseAllCurrentBarCode=Are you sure you want to erase all current barcode values?
     AllBarcodeReset=All barcode values have been removed
    -NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled into barcode module setup.
    +NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled in the barcode module setup.
     EnableFileCache=Enable file cache
     ShowDetailsInPDFPageFoot=Add more details into footer of PDF files, like your company address, or manager names (to complete professional ids, company capital and VAT number).
     NoDetails=No more details in footer
    @@ -450,22 +450,22 @@ EnableAndSetupModuleCron=If you want to have this recurring invoice generated au
     ModuleCompanyCodeCustomerAquarium=%s followed by customer code for a customer accounting code
     ModuleCompanyCodeSupplierAquarium=%s followed by supplier code for a supplier accounting code
     ModuleCompanyCodePanicum=Return an empty accounting code.
    -ModuleCompanyCodeDigitaria=Accounting code depends on third party code. The code is composed of the character "C" in the first position followed by the first 5 characters of the third party code.  
    -Use3StepsApproval=By default, Purchase Orders need to be created and approved by 2 different users (one step/user to create and one step/user to approve. Note that if user has both permission to create and approve, one step/user will be enough). You can ask with this option to introduce a third step/user approval, if amount is higher than a dedicated value (so 3 steps will be necessary: 1=validation, 2=first approval and 3=second approval if amount is enough).<br>Set this to empty if one approval (2 steps) is enough, set it to a very low value (0.1) if a second approval (3 steps) is always required.  
    +ModuleCompanyCodeDigitaria=Accounting code depends on third party code. The code is composed of the character "C" in the first position followed by the first 5 characters of the third party code.
    +Use3StepsApproval=By default, Purchase Orders need to be created and approved by 2 different users (one step/user to create and one step/user to approve. Note that if user has both permission to create and approve, one step/user will be enough). You can ask with this option to introduce a third step/user approval, if amount is higher than a dedicated value (so 3 steps will be necessary: 1=validation, 2=first approval and 3=second approval if amount is enough).<br>Set this to empty if one approval (2 steps) is enough, set it to a very low value (0.1) if a second approval (3 steps) is always required.
     UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than...
    -WarningPHPMail=WARNING: It is often better to setup outgoing emails to use the email server of your provider instead of the default setup. Some email providers (like Yahoo) does not allow you to send an email from another server than their own server. Your current setup use the server of the application to send email and not the server of your email provider, so some recipients (the one compatible with the restrictive DMARC protocol), will ask your email provider if they can accept your email and some email providers (like Yahoo) may respond "no" because the server is not a server of them, so few of your sent Emails may not be accepted (be carefull also to your email provider sending quota).<br>If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider (ask your EMail provider to get SMTP credentials for your account).
    +WarningPHPMail=WARNING: It is often better to setup outgoing emails to use the email server of your provider instead of the default setup. Some email providers (like Yahoo) do not allow you to send an email from another server than their own server. Your current setup uses the server of the application to send email and not the server of your email provider, so some recipients (the one compatible with the restrictive DMARC protocol), will ask your email provider if they can accept your email and some email providers (like Yahoo) may respond "no" because the server is not their, so few of your sent Emails may not be accepted (be careful also of your email provider's sending quota).<br>If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider (ask your Email provider to get SMTP credentials for your account).
     WarningPHPMail2=If your email SMTP provider need to restrict email client to some IP addresses (very rare), this is the IP address of the mail user agent (MUA) for your ERP CRM application: <strong>%s</strong>.
     ClickToShowDescription=Click to show description
    -DependsOn=This module need the module(s)
    +DependsOn=This module needs the module(s)
     RequiredBy=This module is required by module(s)
    -TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. This need to have technical knowledges to read the content of the HTML page to get the key name of a field.
    -PageUrlForDefaultValues=You must enter here the relative url of the page. If you include parameters in URL, the default values will be effective if all parameters are set to same value. Examples:
    +TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. Technical knowledge is required to read the content of the HTML page to get the key name of a field.
    +PageUrlForDefaultValues=You must enter the relative url of the page. If you include parameters in URL, the default values will be effective if all parameters are set to same value. Examples:
     PageUrlForDefaultValuesCreate=<br>For form to create a new thirdparty, it is <strong>%s</strong>,<br>If you want default value only if url has some parameter, you can use <strong>%s</strong>
    -PageUrlForDefaultValuesList=<br>For page that list thirdparties, it is <strong>%s</strong>,<br>If you want default value only if url has some parameter, you can use <strong>%s</strong>
    +PageUrlForDefaultValuesList=<br>For page that list third-parties, it is <strong>%s</strong>,<br>If you want default value only if url has some parameter, you can use <strong>%s</strong>
     EnableDefaultValues=Enable usage of personalized default values
    -EnableOverwriteTranslation=Enable usage of overwrote translation
    -GoIntoTranslationMenuToChangeThis=A translation has been found for the key with this code, so to change this value, you must edit it fom Home-Setup-translation.
    -WarningSettingSortOrder=Warning, setting a default sort order may result in a technical error when going on the list page if field is an unknown field. If you experience such an error, come back to this page to remove the default sort order and restore default behavior. 
    +EnableOverwriteTranslation=Enable usage of overwritten translation
    +GoIntoTranslationMenuToChangeThis=A translation has been found for the key with this code. To change this value, you must edit it from Home-Setup-translation.
    +WarningSettingSortOrder=Warning, setting a default sort order may result in a technical error when going on the list page if field is an unknown field. If you experience such an error, come back to this page to remove the default sort order and restore default behavior.
     Field=Field
     ProductDocumentTemplates=Document templates to generate product document
     FreeLegalTextOnExpenseReports=Free legal text on expense reports
    @@ -476,18 +476,18 @@ SendEmailsReminders=Send agenda reminders by emails
     davDescription=Add a component to be a DAV server
     DAVSetup=Setup of module DAV
     DAV_ALLOW_PUBLIC_DIR=Enable the public directory (WebDav directory with no login required)
    -DAV_ALLOW_PUBLIC_DIRTooltip=The WebDav public directory is a WebDAV directory everybody can access to (in read and write mode), with no need to have/use an existing login/password account.
    +DAV_ALLOW_PUBLIC_DIRTooltip=The WebDav public directory is a WebDAV directory everybody can access  (in read and write mode), with no need to have/use an existing login/password account.
     DAV_ALLOW_ECM_DIR=Enable the root directy of DMS/ECM module (login required)
     DAV_ALLOW_ECM_DIRTooltip=The root directory where all files are manually uploaded when using the DMS/ECM module. Like for the feature from the web interface, you will need a valid login/password with granted permissions to access it.
     # Modules
     Module0Name=Users & Groups
     Module0Desc=Users / Employees and Groups management
    -Module1Name=Third parties
    +Module1Name=Third Parties
     Module1Desc=Companies and contact management (customers, prospects...)
     Module2Name=Commercial
     Module2Desc=Commercial management
     Module10Name=Accounting
    -Module10Desc=Simple accounting reports (journals, turnover) based onto database content. Does not use any ledger table.
    +Module10Desc=Simple accounting reports (journals, turnover) based on database content. Does not use any ledger table.
     Module20Name=Proposals
     Module20Desc=Commercial proposal management
     Module22Name=Mass E-mailings
    @@ -513,13 +513,13 @@ Module52Desc=Stock management (products)
     Module53Name=Services
     Module53Desc=Service management
     Module54Name=Contracts/Subscriptions
    -Module54Desc=Management of contracts (services or reccuring subscriptions)
    +Module54Desc=Management of contracts (services or recurring subscriptions)
     Module55Name=Barcodes
     Module55Desc=Barcode management
     Module56Name=Telephony
     Module56Desc=Telephony integration
     Module57Name=Direct bank payment orders
    -Module57Desc=Management of Direct Debit payment orders. It includes generation of SEPA file for european countries.
    +Module57Desc=Management of Direct Debit payment orders. It includes generation of SEPA file for European countries.
     Module58Name=ClickToDial
     Module58Desc=Integration of a ClickToDial system (Asterisk, ...)
     Module59Name=Bookmark4u
    @@ -532,43 +532,43 @@ Module80Name=Shipments
     Module80Desc=Shipments and delivery order management
     Module85Name=Banks and Cash
     Module85Desc=Management of bank or cash accounts
    -Module100Name=External site
    -Module100Desc=This module include an external web site or page into Dolibarr menus and view it into a Dolibarr frame
    +Module100Name=External Site
    +Module100Desc=Add external website link into Dolibarr menus to view it in a Dolibarr frame
     Module105Name=Mailman and SPIP
     Module105Desc=Mailman or SPIP interface for member module
     Module200Name=LDAP
    -Module200Desc=LDAP directory synchronisation
    +Module200Desc=LDAP directory synchronization
     Module210Name=PostNuke
     Module210Desc=PostNuke integration
     Module240Name=Data exports
    -Module240Desc=Tool to export Dolibarr data (with assistants)
    +Module240Desc=Tool to export Dolibarr data (with assistance)
     Module250Name=Data imports
    -Module250Desc=Tool to import data in Dolibarr  (with assistants)
    +Module250Desc=Tool to import data into Dolibarr (with assistance)
     Module310Name=Members
     Module310Desc=Foundation members management
     Module320Name=RSS Feed
     Module320Desc=Add RSS feed inside Dolibarr screen pages
    -Module330Name=Bookmarks
    -Module330Desc=Bookmarks management
    -Module400Name=Projects/Opportunities/Leads
    -Module400Desc=Management of projects, opportunities/leads and/or tasks. You can also assign any element (invoice, order, proposal, intervention, ...) to a project and get a transversal view from the project view.
    +Module330Name=Bookmarks and shortcuts
    +Module330Desc=Create shortcuts, always accessible, to the internal or external pages to which you frequently access
    +Module400Name=Projects or Leads
    +Module400Desc=Management of projects, leads/opportunities and/or tasks. You can also assign any element (invoice, order, proposal, intervention, ...) to a project and get a transversal view from the project view.
     Module410Name=Webcalendar
     Module410Desc=Webcalendar integration
     Module500Name=Taxes and Special expenses
     Module500Desc=Management of other expenses (sale taxes, social or fiscal taxes, dividends, ...)
     Module510Name=Payment of employee wages
    -Module510Desc=Record and follow payment of your employee wages
    +Module510Desc=Record and track employee payments
     Module520Name=Loan
     Module520Desc=Management of loans
     Module600Name=Notifications on business events
    -Module600Desc=Send EMail notifications (triggered by some business events) to users (setup defined on each user), to third-party contacts (setup defined on each third party) or to fixed emails
    -Module600Long=Note that this module is dedicated to send real time emails when a dedicated business event occurs. If you are looking for a feature to send reminders by email of your agenda events, go into setup of module Agenda.
    +Module600Desc=Send email notifications triggered by a business event, for users (setup defined on each user), third-party contacts (setup defined on each third party) or to defined emails
    +Module600Long=Note that this module sends emails in real-time when a specific business event occurs. If you are looking for a feature to send email reminders of agenda events, go into the setup of module Agenda.
     Module610Name=Product Variants
    -Module610Desc=Allows creation of products variant based on attributes (color, size, ...)
    +Module610Desc=Creation of product variants (color, size etc.)
     Module700Name=Donations
     Module700Desc=Donation management
     Module770Name=Expense reports
    -Module770Desc=Management and claim expense reports (transportation, meal, ...)
    +Module770Desc=Manage and claim expense reports (transportation, meal, ...)
     Module1120Name=Vendor commercial proposal
     Module1120Desc=Request vendor commercial proposal and prices
     Module1200Name=Mantis
    @@ -578,13 +578,13 @@ Module1520Desc=Mass mail document generation
     Module1780Name=Tags/Categories
     Module1780Desc=Create tags/category (products, customers, vendors, contacts or members)
     Module2000Name=WYSIWYG editor
    -Module2000Desc=Allow to edit some text area using an advanced editor (Based on CKEditor)
    +Module2000Desc=Allow text fields to be edited using CKEditor
     Module2200Name=Dynamic Prices
     Module2200Desc=Enable the usage of math expressions for prices
     Module2300Name=Scheduled jobs
     Module2300Desc=Scheduled jobs management (alias cron or chrono table)
     Module2400Name=Events/Agenda
    -Module2400Desc=Follow done and upcoming events. Let application logs automatic events for tracking purposes or record manual events or rendez-vous. This is the main important module for a good Customer or Supplier Relationship Management.
    +Module2400Desc=Track events. Let Dolibarr log automatic events for tracking purposes or record manual events or meetings. This is the main module for good Customer or Supplier Relationship Management.
     Module2500Name=DMS / ECM
     Module2500Desc=Document Management System / Electronic Content Management. Automatic organization of your generated or stored documents. Share them when you need.
     Module2600Name=API/Web services (SOAP server)
    @@ -592,16 +592,16 @@ Module2600Desc=Enable the Dolibarr SOAP server providing API services
     Module2610Name=API/Web services (REST server)
     Module2610Desc=Enable the Dolibarr REST server providing API services
     Module2660Name=Call WebServices (SOAP client)
    -Module2660Desc=Enable the Dolibarr web services client (Can be used to push data/requests to external servers. Supplier orders supported only for the moment) 
    +Module2660Desc=Enable the Dolibarr web services client (Can be used to push data/requests to external servers. Only Supplier orders currently supported.)
     Module2700Name=Gravatar
    -Module2700Desc=Use online Gravatar service (www.gravatar.com) to show photo of users/members (found with their emails). Need an internet access
    +Module2700Desc=Use online Gravatar service (www.gravatar.com) to show photo of users/members (found with their emails). Needs Internet access
     Module2800Desc=FTP Client
     Module2900Name=GeoIPMaxmind
     Module2900Desc=GeoIP Maxmind conversions capabilities
     Module3100Name=Skype
     Module3100Desc=Add a Skype button into users / third parties / contacts / members cards
     Module3200Name=Unalterable Archives
    -Module3200Desc=Activate log of some business events into an unalterable log. Events are archived in real-time. The log is a table of chained events that can be read only and exported. This module may be mandatory for some countries.
    +Module3200Desc=Enable an unalterable log of business events. Events are archived in real-time. The log is a read-only table of chained events that can be exported. This module may be mandatory for some countries.
     Module4000Name=HRM
     Module4000Desc=Human resources management (management of department, employee contracts and feelings)
     Module5000Name=Multi-company
    @@ -611,27 +611,31 @@ Module6000Desc=Workflow management (automatic creation of object and/or automati
     Module10000Name=Websites
     Module10000Desc=Create public websites with a WYSIWG editor. Just setup your web server (Apache, Nginx, ...) to point to the dedicated Dolibarr directory to have it online on the Internet with your own domain name.
     Module20000Name=Leave Requests management
    -Module20000Desc=Declare and follow employees leaves requests
    +Module20000Desc=Declare and track employees leave requests
     Module39000Name=Products lots
     Module39000Desc=Lot or serial number, eat-by and sell-by date management on products
    +Module40000Name=Multicurrency
    +Module40000Desc=Use alternative currencies in prices and documents
     Module50000Name=PayBox
    -Module50000Desc=Module to offer an online payment page accepting payments with Credit/Debit card via PayBox. This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
    +Module50000Desc=Offer customers a PayBox online payment page (credit/debit cards). This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
     Module50100Name=Point of sales
     Module50100Desc=Point of sales module (POS).
    +Module50150Name=Point of sales
    +Module50150Desc=Point of sales module (Touch screen POS).
     Module50200Name=Paypal
    -Module50200Desc=Module to offer an online payment page accepting payments using PayPal (credit card or PayPal credit). This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
    +Module50200Desc=Offer customers a PayPal online payment page (PayPal account or credit/debit cards). This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
     Module50400Name=Accounting (advanced)
    -Module50400Desc=Accounting management (double entries, support general and auxiliary ledgers). Export the ledger in several other accounting software format.
    +Module50400Desc=Accounting management (double entries, support general and auxiliary ledgers). Export the ledger in several other accounting software formats.
     Module54000Name=PrintIPP
    -Module54000Desc=Direct print (without opening the documents) using Cups IPP interface (Printer must be visible from server, and CUPS must be installe on server).
    +Module54000Desc=Direct print (without opening the documents) using Cups IPP interface (Printer must be visible from server, and CUPS must be installed on server).
     Module55000Name=Poll, Survey or Vote
    -Module55000Desc=Module to make online polls, surveys or votes (like Doodle, Studs, Rdvz, ...)
    +Module55000Desc=Module to create online polls, surveys or votes (like Doodle, Studs, Rdvz, ...)
     Module59000Name=Margins
     Module59000Desc=Module to manage margins
     Module60000Name=Commissions
     Module60000Desc=Module to manage commissions
    -Module62000Name=Incoterm
    -Module62000Desc=Add features to manage Incoterm
    +Module62000Name=Incoterms
    +Module62000Desc=Add features to manage Incoterms
     Module63000Name=Resources
     Module63000Desc=Manage resources (printers, cars, room, ...) you can then share into events
     Permission11=Read customer invoices
    @@ -653,9 +657,9 @@ Permission32=Create/modify products
     Permission34=Delete products
     Permission36=See/manage hidden products
     Permission38=Export products
    -Permission41=Read projects and tasks (shared project and projects i'm contact for). Can also enter time consumed, for me or my hierarchy, on assigned tasks (Timesheet)
    -Permission42=Create/modify projects (shared project and projects i'm contact for). Can also create tasks and assign users to project and tasks
    -Permission44=Delete projects (shared project and projects i'm contact for)
    +Permission41=Read projects and tasks (shared project and projects I'm contact for). Can also enter time consumed, for me or my hierarchy, on assigned tasks (Timesheet)
    +Permission42=Create/modify projects (shared project and projects I'm contact for). Can also create tasks and assign users to project and tasks
    +Permission44=Delete projects (shared project and projects I'm contact for)
     Permission45=Export projects
     Permission61=Read interventions
     Permission62=Create/modify interventions
    @@ -688,7 +692,7 @@ Permission109=Delete sendings
     Permission111=Read financial accounts
     Permission112=Create/modify/delete and compare transactions
     Permission113=Setup financial accounts (create, manage categories)
    -Permission114=Reconciliate transactions
    +Permission114=Reconcile transactions
     Permission115=Export transactions and account statements
     Permission116=Transfers between accounts
     Permission117=Manage cheques dispatching
    @@ -696,25 +700,25 @@ Permission121=Read third parties linked to user
     Permission122=Create/modify third parties linked to user
     Permission125=Delete third parties linked to user
     Permission126=Export third parties
    -Permission141=Read all projects and tasks (also private projects i am not contact for)
    -Permission142=Create/modify all projects and tasks (also private projects i am not contact for)
    +Permission141=Read all projects and tasks (also private projects I am not a contact for)
    +Permission142=Create/modify all projects and tasks (also private projects I am not a contact for)
     Permission144=Delete all projects and tasks (also private projects i am not contact for)
     Permission146=Read providers
     Permission147=Read stats
     Permission151=Read direct debit payment orders
     Permission152=Create/modify a direct debit payment orders
     Permission153=Send/Transmit direct debit payment orders
    -Permission154=Record Credits/Rejects of direct debit payment orders
    +Permission154=Record Credits/Rejections of direct debit payment orders
     Permission161=Read contracts/subscriptions
     Permission162=Create/modify contracts/subscriptions
     Permission163=Activate a service/subscription of a contract
     Permission164=Disable a service/subscription of a contract
     Permission165=Delete contracts/subscriptions
     Permission167=Export contracts
    -Permission171=Read trips and expenses (yours and your subordinates) 
    +Permission171=Read trips and expenses (yours and your subordinates)
     Permission172=Create/modify trips and expenses
     Permission173=Delete trips and expenses
    -Permission174=Read all trips and expenses 
    +Permission174=Read all trips and expenses
     Permission178=Export trips and expenses
     Permission180=Read suppliers
     Permission181=Read supplier orders
    @@ -727,7 +731,7 @@ Permission187=Close supplier orders
     Permission188=Cancel supplier orders
     Permission192=Create lines
     Permission193=Cancel lines
    -Permission194=Read the bandwith lines
    +Permission194=Read the bandwidth lines
     Permission202=Create ADSL connections
     Permission203=Order connections orders
     Permission204=Order connections
    @@ -752,12 +756,12 @@ Permission244=See the contents of the hidden categories
     Permission251=Read other users and groups
     PermissionAdvanced251=Read other users
     Permission252=Read permissions of other users
    -Permission253=Create/modify other users, groups and permisssions
    +Permission253=Create/modify other users, groups and permissions
     PermissionAdvanced253=Create/modify internal/external users and permissions
     Permission254=Create/modify external users only
     Permission255=Modify other users password
     Permission256=Delete or disable other users
    -Permission262=Extend access to all third parties (not only third parties that user is a sale representative).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc).<br>Not effective for projects (only rules on project permissions, visibility and assignement matters).
    +Permission262=Extend access to all third parties (not only third parties that user is a sale representative for).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).<br>Not effective for projects (only rules on project permissions, visibility and assignment matters).
     Permission271=Read CA
     Permission272=Read invoices
     Permission273=Issue invoices
    @@ -767,7 +771,7 @@ Permission283=Delete contacts
     Permission286=Export contacts
     Permission291=Read tariffs
     Permission292=Set permissions on the tariffs
    -Permission293=Modify costumers tariffs
    +Permission293=Modify customers tariffs
     Permission300=Read bar codes
     Permission301=Create/modify bar codes
     Permission302=Delete bar codes
    @@ -806,7 +810,7 @@ Permission538=Export services
     Permission701=Read donations
     Permission702=Create/modify donations
     Permission703=Delete donations
    -Permission771=Read expense reports (yours and your subordinates) 
    +Permission771=Read expense reports (yours and your subordinates)
     Permission772=Create/modify expense reports
     Permission773=Delete expense reports
     Permission774=Read all expense reports (even for user not subordinates)
    @@ -844,8 +848,8 @@ Permission1251=Run mass imports of external data into database (data load)
     Permission1321=Export customer invoices, attributes and payments
     Permission1322=Reopen a paid bill
     Permission1421=Export customer orders and attributes
    -Permission20001=Read leave requests (your leaves and the one of your subordinates)
    -Permission20002=Create/modify your leave requests (yours leaves and the one of your subordinates)
    +Permission20001=Read leave requests (your leave and that of your subordinates)
    +Permission20002=Create/modify your leave requests (your leave and that of your subordinates)
     Permission20003=Delete leave requests
     Permission20004=Read all leave requests (even of user not subordinates)
     Permission20005=Create/modify leave requests for everybody (even of user not subordinates)
    @@ -880,8 +884,8 @@ Permission63001=Read resources
     Permission63002=Create/modify resources
     Permission63003=Delete resources
     Permission63004=Link resources to agenda events
    -DictionaryCompanyType=Types of thirdparties
    -DictionaryCompanyJuridicalType=Legal forms of thirdparties
    +DictionaryCompanyType=Types of third-parties
    +DictionaryCompanyJuridicalType=Legal forms of third-parties
     DictionaryProspectLevel=Prospect potential level
     DictionaryCanton=State/Province
     DictionaryRegion=Regions
    @@ -894,7 +898,7 @@ DictionaryVAT=VAT Rates or Sales Tax Rates
     DictionaryRevenueStamp=Amount of tax stamps
     DictionaryPaymentConditions=Payment terms
     DictionaryPaymentModes=Payment modes
    -DictionaryTypeContact=Contact/Address types
    +DictionaryTypeContact=Contact address types
     DictionaryTypeOfContainer=Type of website pages/containers
     DictionaryEcotaxe=Ecotax (WEEE)
     DictionaryPaperFormat=Paper formats
    @@ -908,10 +912,11 @@ DictionarySource=Origin of proposals/orders
     DictionaryAccountancyCategory=Personalized groups for reports
     DictionaryAccountancysystem=Models for chart of accounts
     DictionaryAccountancyJournal=Accounting journals
    +DictionaryEMailTemplates=Email Templates
     DictionaryUnits=Units
     DictionaryProspectStatus=Prospection status
    -DictionaryHolidayTypes=Types of leaves
    -DictionaryOpportunityStatus=Opportunity status for project/lead
    +DictionaryHolidayTypes=Types of leave
    +DictionaryOpportunityStatus=Lead status for project/lead
     DictionaryExpenseTaxCat=Expense report - Transportation categories
     DictionaryExpenseTaxRange=Expense report - Range by transportation category
     SetupSaved=Setup saved
    @@ -919,35 +924,35 @@ SetupNotSaved=Setup not saved
     BackToModuleList=Back to modules list
     BackToDictionaryList=Back to list of Dictionaries
     TypeOfRevenueStamp=Type of tax stamp
    -VATManagement=VAT Management
    -VATIsUsedDesc=By default when creating prospects, invoices, orders etc the VAT rate follows the active standard rule:<br>If the seller is not subjected to VAT, then VAT defaults to 0. End of rule.<br>If the (selling country= buying country), then the VAT by default equals the VAT of the product in the selling country. End of rule. <br>If seller and buyer are both in the European Community and goods are transport products (car, ship, plane), the default VAT is 0 ( The VAT should be paid by the buyer to the customoffice of his country and not to the seller). End of rule.<br>If seller and buyer are both in the European Community and the buyer is not a company, then the VAT by defaults to the VAT of the product sold.  End of rule.<br>If seller and buyer are both in the European Community and the buyer is a company, then the VAT is 0 by default . End of rule.<br>In any othe case the proposed default is VAT=0. End of rule.
    -VATIsNotUsedDesc=By default the proposed VAT is 0 which can be used for cases like associations, individuals ou small companies.
    -VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real).  A system in which VAT is declared.
    -VATIsNotUsedExampleFR=In France, it means associations that are non VAT declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (VAT in franchise) and paid a franchise VAT without any VAT declaration.  This choice will display the reference "Non applicable VAT - art-293B of CGI" on invoices.
    +VATManagement=Sale Tax Management
    +VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the Sale Tax rate follows the active standard rule:<br>If the seller is not subject to Sale tax, then Sale tax defaults to 0. End of rule.<br>If the (seller's country = buyer's country), then the Sale tax by default equals the Sale tax of the product in the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default Sale tax is 0. This rule is dependant on the seller's country - please consult with your accountant. The Sale tax should be paid by the buyer to their customs office in their country and not to the seller. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community Sale tax number) then the Sale tax by defaults to the Sale tax of the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community Sale tax number), then the Sale tax is 0 by default. End of rule.<br>In any other case the proposed default is Sale tax=0. End of rule.
    +VATIsNotUsedDesc=By default the proposed Sale tax is 0 which can be used for cases like associations, individuals or small companies.
    +VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real).  A system in which Sale tax is declared.
    +VATIsNotUsedExampleFR=In France, it means associations that are non Sale tax declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (Sale tax in franchise) and paid a franchise Sale tax without any Sale tax declaration.  This choice will display the reference "Non applicable Sale tax - art-293B of CGI" on invoices.
     ##### Local Taxes #####
     LTRate=Rate
     LocalTax1IsNotUsed=Do not use second tax
    -LocalTax1IsUsedDesc=Use a second type of tax (other than VAT)
    -LocalTax1IsNotUsedDesc=Do not use other type of tax (other than VAT)
    +LocalTax1IsUsedDesc=Use a second type of tax (other than first one)
    +LocalTax1IsNotUsedDesc=Do not use other type of tax (other than first one)
     LocalTax1Management=Second type of tax
     LocalTax1IsUsedExample=
     LocalTax1IsNotUsedExample=
     LocalTax2IsNotUsed=Do not use third tax
    -LocalTax2IsUsedDesc=Use a third type of tax (other than VAT)
    -LocalTax2IsNotUsedDesc=Do not use other type of tax (other than VAT)
    +LocalTax2IsUsedDesc=Use a third type of tax (other than first one)
    +LocalTax2IsNotUsedDesc=Do not use other type of tax (other than first one)
     LocalTax2Management=Third type of tax
     LocalTax2IsUsedExample=
     LocalTax2IsNotUsedExample=
    -LocalTax1ManagementES= RE Management
    -LocalTax1IsUsedDescES= The RE rate by default when creating prospects, invoices, orders etc follow the active standard rule:<br>If te buyer is not subjected to RE, RE by default=0. End of rule.<br>If the buyer is subjected to RE then the RE by default. End of rule.<br>
    -LocalTax1IsNotUsedDescES= By default the proposed RE is 0. End of rule.
    -LocalTax1IsUsedExampleES= In Spain they are professionals subject to some specific sections of the Spanish IAE.
    -LocalTax1IsNotUsedExampleES= In Spain they are professional and societies and subject to certain sections of the Spanish IAE.
    -LocalTax2ManagementES= IRPF Management
    -LocalTax2IsUsedDescES= The RE rate by default when creating prospects, invoices, orders etc follow the active standard rule:<br>If the seller is not subjected to IRPF, then IRPF by default=0. End of rule.<br>If the seller is subjected to IRPF then the IRPF by default. End of rule.<br>
    -LocalTax2IsNotUsedDescES= By default the proposed IRPF is 0. End of rule.
    -LocalTax2IsUsedExampleES= In Spain, freelancers and independent professionals who provide services and companies who have chosen the tax system of modules.
    -LocalTax2IsNotUsedExampleES= In Spain they are bussines not subject to tax system of modules.
    +LocalTax1ManagementES=RE Management
    +LocalTax1IsUsedDescES=The RE rate by default when creating prospects, invoices, orders etc. follow the active standard rule:<br>If the buyer is not subjected to RE, RE by default=0. End of rule.<br>If the buyer is subjected to RE then the RE by default. End of rule.<br>
    +LocalTax1IsNotUsedDescES=By default the proposed RE is 0. End of rule.
    +LocalTax1IsUsedExampleES=In Spain they are professionals subject to some specific sections of the Spanish IAE.
    +LocalTax1IsNotUsedExampleES=In Spain they are professional and societies and subject to certain sections of the Spanish IAE.
    +LocalTax2ManagementES=IRPF Management
    +LocalTax2IsUsedDescES=The IRPF rate by default when creating prospects, invoices, orders etc. follow the active standard rule:<br>If the seller is not subjected to IRPF, then IRPF by default=0. End of rule.<br>If the seller is subjected to IRPF then the IRPF by default. End of rule.<br>
    +LocalTax2IsNotUsedDescES=By default the proposed IRPF is 0. End of rule.
    +LocalTax2IsUsedExampleES=In Spain, freelancers and independent professionals who provide services and companies who have chosen the tax system of modules.
    +LocalTax2IsNotUsedExampleES=In Spain they are businesses not subject to tax system of modules.
     CalcLocaltax=Reports on local taxes
     CalcLocaltax1=Sales - Purchases
     CalcLocaltax1Desc=Local Taxes reports are calculated with the difference between localtaxes sales and localtaxes purchases
    @@ -957,7 +962,7 @@ CalcLocaltax3=Sales
     CalcLocaltax3Desc=Local Taxes reports are the total of localtaxes sales
     LabelUsedByDefault=Label used by default if no translation can be found for code
     LabelOnDocuments=Label on documents
    -LabelOrTranslationKey=Label or translation key 
    +LabelOrTranslationKey=Label or translation key
     NbOfDays=No. of days
     AtEndOfMonth=At end of month
     CurrentNext=Current/Next
    @@ -996,7 +1001,7 @@ Skin=Skin theme
     DefaultSkin=Default skin theme
     MaxSizeList=Max length for list
     DefaultMaxSizeList=Default max length for lists
    -DefaultMaxSizeShortList=Default max length for short lists (ie in customer card)
    +DefaultMaxSizeShortList=Default max length for short lists (i.e. in customer card)
     MessageOfDay=Message of the day
     MessageLogin=Login page message
     LoginPage=Login page
    @@ -1005,8 +1010,8 @@ PermanentLeftSearchForm=Permanent search form on left menu
     DefaultLanguage=Default language to use (language code)
     EnableMultilangInterface=Enable multilingual interface
     EnableShowLogo=Show logo on left menu
    -CompanyInfo=Company/organization information
    -CompanyIds=Company/organization identities
    +CompanyInfo=Company/Organization
    +CompanyIds=Company/Organization identities
     CompanyName=Name
     CompanyAddress=Address
     CompanyZip=Zip
    @@ -1021,28 +1026,28 @@ OwnerOfBankAccount=Owner of bank account %s
     BankModuleNotActive=Bank accounts module not enabled
     ShowBugTrackLink=Show link "<strong>%s</strong>"
     Alerts=Alerts
    -DelaysOfToleranceBeforeWarning=Tolerance delays before warning
    -DelaysOfToleranceDesc=This screen allows you to define the tolerated delays before an alert is reported on screen with picto %s for each late element.
    -Delays_MAIN_DELAY_ACTIONS_TODO=Delay tolerance (in days) before alert on planned events (agenda events) not completed yet
    -Delays_MAIN_DELAY_PROJECT_TO_CLOSE=Delay tolerance (in days) before alert on project not closed in time
    -Delays_MAIN_DELAY_TASKS_TODO=Delay tolerance (in days) before alert on planned tasks (project tasks) not completed yet
    -Delays_MAIN_DELAY_ORDERS_TO_PROCESS=Delay tolerance (in days) before alert on orders not processed yet
    -Delays_MAIN_DELAY_SUPPLIER_ORDERS_TO_PROCESS=Delay tolerance (in days) before alert on purchase orders not processed yet
    -Delays_MAIN_DELAY_PROPALS_TO_CLOSE=Delay tolerance (in days) before alert on proposals to close
    -Delays_MAIN_DELAY_PROPALS_TO_BILL=Delay tolerance (in days) before alert on proposals not billed
    -Delays_MAIN_DELAY_NOT_ACTIVATED_SERVICES=Tolerance delay (in days) before alert on services to activate
    -Delays_MAIN_DELAY_RUNNING_SERVICES=Tolerance delay (in days) before alert on expired services
    -Delays_MAIN_DELAY_SUPPLIER_BILLS_TO_PAY=Tolerance delay (in days) before alert on unpaid supplier invoices
    -Delays_MAIN_DELAY_CUSTOMER_BILLS_UNPAYED=Tolerence delay (in days) before alert on unpaid client invoices
    -Delays_MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE=Tolerance delay (in days) before alert on pending bank reconciliation
    -Delays_MAIN_DELAY_MEMBERS=Tolerance delay (in days) before alert on delayed membership fee
    -Delays_MAIN_DELAY_CHEQUES_TO_DEPOSIT=Tolerance delay (in days) before alert for cheques deposit to do
    -Delays_MAIN_DELAY_EXPENSEREPORTS=Tolerance delay (in days) before alert for expense reports to approve
    -SetupDescription1=The setup area is for initial setup parameters before starting to use Dolibarr.
    +DelaysOfToleranceBeforeWarning=Delays before displaying an alert warning
    +DelaysOfToleranceDesc=This screen allows you to define the delay before an alert is reported onscreen with a %s icon for each late element.
    +Delays_MAIN_DELAY_ACTIONS_TODO=Delay (in days) before alert on planned events (agenda events) not completed yet
    +Delays_MAIN_DELAY_PROJECT_TO_CLOSE=Delay (in days) before alert on project not closed in time
    +Delays_MAIN_DELAY_TASKS_TODO=Delay (in days) before alert on planned tasks (project tasks) not completed yet
    +Delays_MAIN_DELAY_ORDERS_TO_PROCESS=Delay (in days) before alert on orders not processed yet
    +Delays_MAIN_DELAY_SUPPLIER_ORDERS_TO_PROCESS=Delay (in days) before alert on purchase orders not processed yet
    +Delays_MAIN_DELAY_PROPALS_TO_CLOSE=Delay (in days) before alert on proposals to close
    +Delays_MAIN_DELAY_PROPALS_TO_BILL=Delay (in days) before alert on proposals not billed
    +Delays_MAIN_DELAY_NOT_ACTIVATED_SERVICES=Delay (in days) before alert on services to activate
    +Delays_MAIN_DELAY_RUNNING_SERVICES=Delay (in days) before alert on expired services
    +Delays_MAIN_DELAY_SUPPLIER_BILLS_TO_PAY=Delay (in days) before alert on unpaid supplier invoices
    +Delays_MAIN_DELAY_CUSTOMER_BILLS_UNPAYED=Delay (in days) before alert on unpaid client invoices
    +Delays_MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE=Delay (in days) before alert on pending bank reconciliation
    +Delays_MAIN_DELAY_MEMBERS=Delay (in days) before alert on delayed membership fee
    +Delays_MAIN_DELAY_CHEQUES_TO_DEPOSIT=Delay (in days) before alert for cheque deposit to do
    +Delays_MAIN_DELAY_EXPENSEREPORTS=Delay (in days) before alert for expense reports to approve
    +SetupDescription1=Before starting to use Dolibarr some initial parameters must be defined and modules enabled/configured.
     SetupDescription2=The mandatory setup steps are the 2 first steps in the Setup menu, namely :
    -SetupDescription3=Settings in menu <a href="%s">%s -> %s</a>. This step is required because it defines data used on Dolibarr screens to customize the default behavior of the software (for country-related features for example).
    -SetupDescription4=Settings in menu <a href="%s">%s -> %s</a>. This step is required because Dolibarr ERP/CRM is a collection of several modules/applications, all more or less independent. New features are added to menus for every module you activate.
    -SetupDescription5=Other menu entries manage optional parameters.
    +SetupDescription3=<a href="%s">%s -> %s</a><br>Basic parameters used to customize the default behavior of Dolibarr (e.g for country-related features).
    +SetupDescription4=<a href="%s">%s -> %s</a><br>Dolibarr ERP/CRM is a collection of many modules/applications, all more or less independent. The modules relevant to your needs must be enabled and configured. New items/options are added to menus with the activation of a module.
    +SetupDescription5=Other Setup menu entries provides optional parameters.
     LogEvents=Security audit events
     Audit=Audit
     InfoDolibarr=About Dolibarr
    @@ -1060,16 +1065,16 @@ LogEventDesc=You can enable here the logging for Dolibarr security events. Admin
     AreaForAdminOnly=Setup parameters can be set by <b>administrator users</b> only.
     SystemInfoDesc=System information is miscellaneous technical information you get in read only mode and visible for administrators only.
     SystemAreaForAdminOnly=This area is available for administrator users only. None of the Dolibarr permissions can reduce this limit.
    -CompanyFundationDesc=Edit on this page all known information of the company or foundation you need to manage (For this, click on "%s" or "%s" button at bottom of page)
    -AccountantDesc=Edit on this page all known information about your accountant/bookkeeper
    +CompanyFundationDesc=Edit the information of the company/entity. Click on "%s" or "%s" button at the bottom of the page.
    +AccountantDesc=Edit the details of your accountant/bookkeeper
     AccountantFileNumber=File number
     DisplayDesc=You can choose each parameter related to the Dolibarr look and feel here
     AvailableModules=Available app/modules
     ToActivateModule=To activate modules, go on setup Area (Home->Setup->Modules).
     SessionTimeOut=Time out for session
    -SessionExplanation=This number guarantee that session will never expire before this delay, if the session cleaner is done by Internal PHP session cleaner (and nothing else). Internal PHP session cleaner does not guaranty that session will expire just after this delay. It will expire, after this delay, and when the session cleaner is ran, so every <b>%s/%s</b> access, but only during access made by other sessions.<br>Note: on some servers with an external session cleaning mechanism (cron under debian, ubuntu ...), the sessions can be destroyed after a period defined by the default <strong>session.gc_maxlifetime</strong>, no matter what the value entered here. 
    +SessionExplanation=This number guarantees that the session will never expire before this delay, if the session cleaner is done by Internal PHP session cleaner (and nothing else). Internal PHP session cleaner does not guarantee that the session will expire after this delay. It will expire, after this delay, and when the session cleaner is run, so every <b>%s/%s</b> access, but only during access made by other sessions.<br>Note: on some servers with an external session cleaning mechanism (cron under debian, ubuntu ...), the sessions can be destroyed after a period defined by the default <strong>session.gc_maxlifetime</strong>, no matter what the value entered here is.
     TriggersAvailable=Available triggers
    -TriggersDesc=Triggers are files that will modify the behaviour of Dolibarr workflow once copied into the directory <b>htdocs/core/triggers</b>. They realised new actions, activated on Dolibarr events (new company creation, invoice validation, ...).
    +TriggersDesc=Triggers are files that will modify the behavior of Dolibarr workflow once copied into the directory <b>htdocs/core/triggers</b>. They realize new actions, activated on Dolibarr events (new company creation, invoice validation, ...).
     TriggerDisabledByName=Triggers in this file are disabled by the <b>-NORUN</b> suffix in their name.
     TriggerDisabledAsModuleDisabled=Triggers in this file are disabled as module <b>%s</b> is disabled.
     TriggerAlwaysActive=Triggers in this file are always active, whatever are the activated Dolibarr modules.
    @@ -1079,7 +1084,7 @@ DictionaryDesc=Insert all reference data. You can add your values to the default
     ConstDesc=This page allows you to edit all other parameters not available in previous pages. These are mostly reserved parameters for developers or advanced troubleshooting. For a list of options <a href="https://wiki.dolibarr.org/index.php/Setup_Other#List_of_known_hidden_options" title="External Site - opens in a new window" target="_blank">check here</a>.
     MiscellaneousDesc=All other security related parameters are defined here.
     LimitsSetup=Limits/Precision setup
    -LimitsDesc=You can define limits, precisions and optimisations used by Dolibarr here
    +LimitsDesc=You can define limits, precisions and optimizations used by Dolibarr here
     MAIN_MAX_DECIMALS_UNIT=Max decimals for unit prices
     MAIN_MAX_DECIMALS_TOT=Max decimals for total prices
     MAIN_MAX_DECIMALS_SHOWN=Max decimals for prices shown on screen (Add <b>...</b> after this number if you want to see <b>...</b> when number is truncated when shown on screen)
    @@ -1088,51 +1093,51 @@ UnitPriceOfProduct=Net unit price of a product
     TotalPriceAfterRounding=Total price (net/vat/incl tax) after rounding
     ParameterActiveForNextInputOnly=Parameter effective for next input only
     NoEventOrNoAuditSetup=No security event has been recorded yet. This can be normal if audit has not been enabled on "setup - security - audit" page.
    -NoEventFoundWithCriteria=No security event has been found for such search criterias.
    +NoEventFoundWithCriteria=No security event has been found for this search criteria.
     SeeLocalSendMailSetup=See your local sendmail setup
     BackupDesc=To make a complete backup of Dolibarr, you must:
     BackupDesc2=Save content of documents directory (<b>%s</b>) that contains all uploaded and generated files (So it includes all dump files generated at step 1).
    -BackupDesc3=Save content of your database (<b>%s</b>) into a dump file. For this, you can use following assistant.
    +BackupDesc3=Save content of your database (<b>%s</b>) into a dump file. For this, you can use the following assistant.
     BackupDescX=Archived directory should be stored in a secure place.
     BackupDescY=The generated dump file should be stored in a secure place.
    -BackupPHPWarning=Backup can't be guaranted with this method. Prefer previous one
    +BackupPHPWarning=Backup cannot be guaranteed with this method. Previous one recommended.
     RestoreDesc=To restore a Dolibarr backup, you must:
    -RestoreDesc2=Restore archive file (zip file for example) of documents directory to extract tree of files in documents directory of a new Dolibarr installation or into this current documents directoy (<b>%s</b>).
    +RestoreDesc2=Restore archive file (zip file for example) of documents directory to extract tree of files in documents directory of a new Dolibarr installation or into this current documents directory (<b>%s</b>).
     RestoreDesc3=Restore the data, from a backup dump file, into the database of the new Dolibarr installation or into the database of this current installation (<b>%s</b>). Warning, once restore is finished, you must use a login/password, that existed when backup was made, to connect again. To restore a backup database into this current installation, you can follow this assistant.
     RestoreMySQL=MySQL import
     ForcedToByAModule= This rule is forced to <b>%s</b> by an activated module
     PreviousDumpFiles=Generated database backup files
    -WeekStartOnDay=First day of week 
    +WeekStartOnDay=First day of week
     RunningUpdateProcessMayBeRequired=Running the upgrade process seems to be required (Programs version %s differs from database version %s)
     YouMustRunCommandFromCommandLineAfterLoginToUser=You must run this command from command line after login to a shell with user <b>%s</b> or you must add -W option at end of command line to provide <b>%s</b> password.
     YourPHPDoesNotHaveSSLSupport=SSL functions not available in your PHP
     DownloadMoreSkins=More skins to download
     SimpleNumRefModelDesc=Returns the reference number with format %syymm-nnnn where yy is year, mm is month and nnnn is a sequence without hole and with no reset
    -ShowProfIdInAddress=Show professionnal id with addresses on documents
    -ShowVATIntaInAddress=Hide VAT Intra num with addresses on documents
    +ShowProfIdInAddress=Show professional id with addresses on documents
    +ShowVATIntaInAddress=Hide intra-Community VAT number with addresses on documents
     TranslationUncomplete=Partial translation
    -MAIN_DISABLE_METEO=Disable meteo view
    +MAIN_DISABLE_METEO=Disable meteorological view
     MeteoStdMod=Standard mode
     MeteoStdModEnabled=Standard mode enabled
     MeteoPercentageMod=Percentage mode
     MeteoPercentageModEnabled=Percentage mode enabled
     MeteoUseMod=Click to use %s
     TestLoginToAPI=Test login to API
    -ProxyDesc=Some features of Dolibarr need to have an Internet access to work. Define here parameters for this. If the Dolibarr server is behind a Proxy server, those parameters tells Dolibarr how to access Internet through it. 
    +ProxyDesc=Some features of Dolibarr need to have internet access to work. Define here the parameters for this. If the Dolibarr server is behind a Proxy server, these parameters tell Dolibarr how to access the internet through it.
     ExternalAccess=External access
     MAIN_PROXY_USE=Use a proxy server (otherwise direct access to internet)
     MAIN_PROXY_HOST=Name/Address of proxy server
     MAIN_PROXY_PORT=Port of proxy server
     MAIN_PROXY_USER=Login to use the proxy server
     MAIN_PROXY_PASS=Password to use the proxy server
    -DefineHereComplementaryAttributes=Define here all attributes, not already available by default, and that you want to be supported for %s.
    +DefineHereComplementaryAttributes=Define any attributes not already available by default, that you want to be supported for %s here.
     ExtraFields=Complementary attributes
     ExtraFieldsLines=Complementary attributes (lines)
     ExtraFieldsLinesRec=Complementary attributes (templates invoices lines)
     ExtraFieldsSupplierOrdersLines=Complementary attributes (order lines)
     ExtraFieldsSupplierInvoicesLines=Complementary attributes (invoice lines)
     ExtraFieldsThirdParties=Complementary attributes (thirdparty)
    -ExtraFieldsContacts=Complementary attributes (contact/address)
    +ExtraFieldsContacts=Complementary attributes (contact address)
     ExtraFieldsMember=Complementary attributes (member)
     ExtraFieldsMemberType=Complementary attributes (member type)
     ExtraFieldsCustomerInvoices=Complementary attributes (invoices)
    @@ -1146,43 +1151,44 @@ AlphaNumOnlyLowerCharsAndNoSpace=only alphanumericals and lower case characters
     SendmailOptionNotComplete=Warning, on some Linux systems, to send email from your email, sendmail execution setup must contains option -ba (parameter mail.force_extra_parameters into your php.ini file). If some recipients never receive emails, try to edit this PHP parameter with mail.force_extra_parameters = -ba).
     PathToDocuments=Path to documents
     PathDirectory=Directory
    -SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might be not correctly parsed by some receiving mail servers. Result is that some mails can't be read by people hosted by those bugged platforms. It's case for some Internet providers (Ex: Orange in France). This is not a problem into Dolibarr nor into PHP but onto receiving mail server. You can however add option MAIN_FIX_FOR_BUGGED_MTA to 1 into setup - other to modify Dolibarr to avoid this. However, you may experience problem with other servers that respect strictly the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" that has no disadvantages.
    +SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might not be parsed correctly by some receiving mail servers. The result is that some mails can't be read by people hosted by those bugged platforms. This is the case for some Internet providers (Ex: Orange in France). This is not a problem with Dolibarr or PHP but with the receiving mail server. You can however add an option MAIN_FIX_FOR_BUGGED_MTA to 1 in Setup - Other to modify Dolibarr to avoid this. However, you may experience problems with other servers that strictly use the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" which has no disadvantages.
     TranslationSetup=Setup of translation
     TranslationKeySearch=Search a translation key or string
     TranslationOverwriteKey=Overwrite a translation string
     TranslationDesc=How to set displayed application language :<br>* Systemwide: menu <strong>Home - Setup - Display</strong><br>* Per user: Use the <strong>User display setup</strong> tab on user card (click on username at the top of the screen).
     TranslationOverwriteDesc=You can also override strings filling the following table. Choose your language from "%s" dropdown, insert the translation key string into "%s" and your new translation into "%s"
    -TranslationOverwriteDesc2=You can use the other tab to help you know translation key to use
    +TranslationOverwriteDesc2=You can use the other tab to help you know which translation key to use
     TranslationString=Translation string
     CurrentTranslationString=Current translation string
     WarningAtLeastKeyOrTranslationRequired=A search criteria is required at least for key or translation string
     NewTranslationStringToShow=New translation string to show
     OriginalValueWas=The original translation is overwritten. Original value was:<br><br>%s
    -TransKeyWithoutOriginalValue=You forced a new translation for the translation key '<strong>%s</strong>' that does not exists in any language files
    +TransKeyWithoutOriginalValue=You forced a new translation for the translation key '<strong>%s</strong>' that does not exist in any language files
     TotalNumberOfActivatedModules=Activated application/modules: <b>%s</b> / <b>%s</b>
     YouMustEnableOneModule=You must at least enable 1 module
    -ClassNotFoundIntoPathWarning=Class %s not found into PHP path
    +ClassNotFoundIntoPathWarning=Class %s not found in PHP path
     YesInSummer=Yes in summer
    -OnlyFollowingModulesAreOpenedToExternalUsers=Note, only following modules are opened to external users (whatever are permission of such users) and only if permissions were granted:
    +OnlyFollowingModulesAreOpenedToExternalUsers=Note, only the following modules are opened to external users (whatever the permissions of such users) and only if permissions are granted:
     SuhosinSessionEncrypt=Session storage encrypted by Suhosin
     ConditionIsCurrently=Condition is currently %s
    -YouUseBestDriver=You use driver %s that is best driver available currently.
    -YouDoNotUseBestDriver=You use drive %s but driver %s is recommended.
    -NbOfProductIsLowerThanNoPb=You have only %s products/services into database. This does not required any particular optimization.
    +YouUseBestDriver=You use driver %s which is the best driver available currently.
    +YouDoNotUseBestDriver=You use driver %s but driver %s is recommended.
    +NbOfProductIsLowerThanNoPb=You have only %s products/services in the database. This does not require any particular optimization.
     SearchOptim=Search optimization
    -YouHaveXProductUseSearchOptim=You have %s product into database. You should add the constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 into Home-Setup-Other, you limit the search to the beginning of strings making possible for database to use index and you should get an immediate response.
    -BrowserIsOK=You are using the web browser %s. This browser is ok for security and performance.
    -BrowserIsKO=You are using the web browser %s. This browser is known to be a bad choice for security, performance and reliability. We recommand you to use Firefox, Chrome, Opera or Safari.
    +YouHaveXProductUseSearchOptim=You have %s products in the database. You should add the constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Home-Setup-Other. Limit the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response.
    +BrowserIsOK=You are using the %s web browser. This browser is ok for security and performance.
    +BrowserIsKO=You are using the %s web browser. This browser is known to be a bad choice for security, performance and reliability. We recommend using Firefox, Chrome, Opera or Safari.
     XDebugInstalled=XDebug is loaded.
     XCacheInstalled=XCache is loaded.
     AddRefInList=Display Customer/Supplier ref. info list (select list or combobox) and most of hyperlink.<br>Third Parties will appear with a name format of "CC12345 - SC45678 - The Big Company corp." instead of "The Big Company corp".
    -AskForPreferredShippingMethod=Ask for preferred sending method for Third Parties.
    +AddAdressInList=Display Customer/Supplier adress info list (select list or combobox)<br>Third Parties will appear with a name format of "The Big Company corp. - 21 jump street 123456 Big town - USA" instead of "The Big Company corp".
    +AskForPreferredShippingMethod=Ask for preferred shipping method for Third Parties.
     FieldEdition=Edition of field %s
     FillThisOnlyIfRequired=Example: +2 (fill only if timezone offset problems are experienced)
     GetBarCode=Get barcode
     ##### Module password generation
     PasswordGenerationStandard=Return a password generated according to internal Dolibarr algorithm: 8 characters containing shared numbers and characters in lowercase.
    -PasswordGenerationNone=Do not suggest any generated password. Password must be typed in manually.
    +PasswordGenerationNone=Do not suggest a generated password. Password must be typed in manually.
     PasswordGenerationPerso=Return a password according to your personally defined configuration.
     SetupPerso=According to your configuration
     PasswordPatternDesc=Password pattern description
    @@ -1195,8 +1201,8 @@ UserMailRequired=EMail required to create a new user
     HRMSetup=HRM module setup
     ##### Company setup #####
     CompanySetup=Companies module setup
    -CompanyCodeChecker=Options for automatic generation of customer/supplier codes
    -AccountCodeManager=Options for automatic generation of customer/supplier accounting codes
    +CompanyCodeChecker=Options for automatic generation of customer / vendor codes
    +AccountCodeManager=Options for automatic generation of customer / vendor accounting codes
     NotificationsDesc=EMails notifications feature allows you to silently send automatic mail, for some Dolibarr events. Targets of notifications can be defined:
     NotificationsDescUser=* per users, one user at time.
     NotificationsDescContact=* per third parties contacts (customers or vendors), one contact at time.
    @@ -1211,7 +1217,7 @@ MustBeMandatory=Mandatory to create third parties (if vat number or type of comp
     MustBeInvoiceMandatory=Mandatory to validate invoices?
     TechnicalServicesProvided=Technical services provided
     #####DAV #####
    -WebDAVSetupDesc=This is the links to access the WebDAV directory. It contains a "public" dir open to any user knowing the URL (if public directory access allowed) and a "private" directory that need an existing login account/password to access to.
    +WebDAVSetupDesc=This is the links to access the WebDAV directory. It contains a "public" dir open to any user knowing the URL (if public directory access allowed) and a "private" directory that need an existing login account/password to access.
     WebDavServer=Root URL of %s server : %s
     ##### Webcal setup #####
     WebCalUrlForVCalExport=An export link to <b>%s</b> format is available at following link: %s
    @@ -1219,6 +1225,7 @@ WebCalUrlForVCalExport=An export link to <b>%s</b> format is available at follow
     BillsSetup=Invoices module setup
     BillsNumberingModule=Invoices and credit notes numbering model
     BillsPDFModules=Invoice documents models
    +BillsPDFModulesAccordindToInvoiceType=Invoice documents models according to invoice type
     PaymentsPDFModules=Payment documents models
     CreditNote=Credit note
     CreditNotes=Credit notes
    @@ -1343,11 +1350,11 @@ LDAPTestSynchroMemberType=Test member type synchronization
     LDAPTestSearch= Test a LDAP search
     LDAPSynchroOK=Synchronization test successful
     LDAPSynchroKO=Failed synchronization test
    -LDAPSynchroKOMayBePermissions=Failed synchronization test. Check that connexion to server is correctly configured and allows LDAP udpates
    +LDAPSynchroKOMayBePermissions=Failed synchronization test. Check that the connection to the server is correctly configured and allows LDAP updates
     LDAPTCPConnectOK=TCP connect to LDAP server successful (Server=%s, Port=%s)
     LDAPTCPConnectKO=TCP connect to LDAP server failed (Server=%s, Port=%s)
    -LDAPBindOK=Connect/Authentificate to LDAP server successful (Server=%s, Port=%s, Admin=%s, Password=%s)
    -LDAPBindKO=Connect/Authentificate to LDAP server failed (Server=%s, Port=%s, Admin=%s, Password=%s)
    +LDAPBindOK=Connect/Authenticate to LDAP server successful (Server=%s, Port=%s, Admin=%s, Password=%s)
    +LDAPBindKO=Connect/Authenticate to LDAP server failed (Server=%s, Port=%s, Admin=%s, Password=%s)
     LDAPSetupForVersion3=LDAP server configured for version 3
     LDAPSetupForVersion2=LDAP server configured for version 2
     LDAPDolibarrMapping=Dolibarr Mapping
    @@ -1360,8 +1367,8 @@ LDAPFieldLoginSamba=Login (samba, activedirectory)
     LDAPFieldLoginSambaExample=Example : samaccountname
     LDAPFieldFullname=Full name
     LDAPFieldFullnameExample=Example : cn
    -LDAPFieldPasswordNotCrypted=Password not crypted
    -LDAPFieldPasswordCrypted=Password crypted
    +LDAPFieldPasswordNotCrypted=Password not encrypted
    +LDAPFieldPasswordCrypted=Password encrypted
     LDAPFieldPasswordExample=Example : userPassword
     LDAPFieldCommonNameExample=Example : cn
     LDAPFieldName=Name
    @@ -1409,40 +1416,41 @@ LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP
     LDAPDescValues=Example values are designed for <b>OpenLDAP</b> with following loaded schemas: <b>core.schema, cosine.schema, inetorgperson.schema</b>). If you use thoose values and OpenLDAP, modify your LDAP config file <b>slapd.conf</b> to have all thoose schemas loaded.
     ForANonAnonymousAccess=For an authenticated access (for a write access for example)
     PerfDolibarr=Performance setup/optimizing report
    -YouMayFindPerfAdviceHere=You will find on this page some checks or advices related to performance.
    -NotInstalled=Not installed, so your server is not slow down by this.
    +YouMayFindPerfAdviceHere=This page provides some checks or advice related to performance.
    +NotInstalled=Not installed, so your server is not slowed down by this.
     ApplicativeCache=Applicative cache
    -MemcachedNotAvailable=No applicative cache found. You can enhance performance by installing a cache server Memcached and a module able to use this cache server.<br>More information here <a href="http://wiki.dolibarr.org/index.php/Module_MemCached_EN">http://wiki.dolibarr.org/index.php/Module_MemCached_EN</a>.<br>Note that a lot of web hosting provider does not provide such cache server. 
    +MemcachedNotAvailable=No applicative cache found. You can enhance performance by installing a cache server Memcached and a module able to use this cache server.<br>More information here <a href="http://wiki.dolibarr.org/index.php/Module_MemCached_EN">http://wiki.dolibarr.org/index.php/Module_MemCached_EN</a>.<br>Note that a lot of web hosting provider does not provide such cache server.
     MemcachedModuleAvailableButNotSetup=Module memcached for applicative cache found but setup of module is not complete.
     MemcachedAvailableAndSetup=Module memcached dedicated to use memcached server is enabled.
     OPCodeCache=OPCode cache
    -NoOPCodeCacheFound=No OPCode cache found. May be you use another OPCode cache than XCache or eAccelerator (good), may be you don't have OPCode cache (very bad). 
    +NoOPCodeCacheFound=No OPCode cache found. Maybe you are using an OPCode cache other than XCache or eAccelerator (good), or maybe you don't have OPCode cache (very bad).
     HTTPCacheStaticResources=HTTP cache for static resources (css, img, javascript)
     FilesOfTypeCached=Files of type %s are cached by HTTP server
     FilesOfTypeNotCached=Files of type %s are not cached by HTTP server
     FilesOfTypeCompressed=Files of type %s are compressed by HTTP server
     FilesOfTypeNotCompressed=Files of type %s are not compressed by HTTP server
     CacheByServer=Cache by server
    -CacheByServerDesc=For exemple using the Apache directive "ExpiresByType image/gif A2592000"
    +CacheByServerDesc=For example using the Apache directive "ExpiresByType image/gif A2592000"
     CacheByClient=Cache by browser
     CompressionOfResources=Compression of HTTP responses
    -CompressionOfResourcesDesc=For exemple using the Apache directive "AddOutputFilterByType DEFLATE"
    -TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers 
    -DefaultValuesDesc=You can define/force here the default value you want to get when your create a new record, and/or defaut filters or sort order when your list record. 
    -DefaultCreateForm=Default values (on forms to create)
    +CompressionOfResourcesDesc=For example using the Apache directive "AddOutputFilterByType DEFLATE"
    +TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers
    +DefaultValuesDesc=Here you can define/force the default value you want to have when you create a new record, and/or default filters or sort order when your list records.
    +DefaultCreateForm=Default values (to create on forms)
     DefaultSearchFilters=Default search filters
     DefaultSortOrder=Default sort orders
     DefaultFocus=Default focus fields
    +DefaultMandatory=Mandatory form fields
     ##### Products #####
     ProductSetup=Products module setup
     ServiceSetup=Services module setup
     ProductServiceSetup=Products and Services modules setup
     NumberOfProductShowInSelect=Max number of products in combos select lists (0=no limit)
    -ViewProductDescInFormAbility=Visualization of product descriptions in the forms (otherwise as popup tooltip)
    +ViewProductDescInFormAbility=Display product descriptions in forms (otherwise as popup tooltip)
     MergePropalProductCard=Activate in product/service Attached Files tab an option to merge product PDF document to proposal PDF azur if product/service is in the proposal
    -ViewProductDescInThirdpartyLanguageAbility=Visualization of products descriptions in the language of the third party
    -UseSearchToSelectProductTooltip=Also if you have a large number of product (> 100 000), you can increase speed by setting constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string.
    -UseSearchToSelectProduct=Wait you press a key before loading content of product combo list (This may increase performance if you have a large number of products, but it is less convenient)
    +ViewProductDescInThirdpartyLanguageAbility=Display products descriptions in the language of the third party
    +UseSearchToSelectProductTooltip=Also if you have a large number of products (> 100 000), you can increase speed by setting constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string.
    +UseSearchToSelectProduct=Wait until you press a key before loading content of product combo list (This may increase performance if you have a large number of products, but it is less convenient)
     SetDefaultBarcodeTypeProducts=Default barcode type to use for products
     SetDefaultBarcodeTypeThirdParties=Default barcode type to use for third parties
     UseUnits=Define a unit of measure for Quantity during order, proposal or invoice lines edition
    @@ -1458,7 +1466,7 @@ SyslogFilename=File name and path
     YouCanUseDOL_DATA_ROOT=You can use DOL_DATA_ROOT/dolibarr.log for a log file in Dolibarr "documents" directory. You can set a different path to store this file.
     ErrorUnknownSyslogConstant=Constant %s is not a known Syslog constant
     OnlyWindowsLOG_USER=Windows only supports LOG_USER
    -CompressSyslogs=Compression and backup of debug log files (generated by module Log for debug) 
    +CompressSyslogs=Compression and backup of debug log files (generated by module Log for debug)
     SyslogFileNumberOfSaves=Log backups
     ConfigureCleaningCronjobToSetFrequencyOfSaves=Configure cleaning scheduled job to set log backup frequency
     ##### Donations #####
    @@ -1479,7 +1487,7 @@ BarcodeDescC39=Barcode of type C39
     BarcodeDescC128=Barcode of type C128
     BarcodeDescDATAMATRIX=Barcode of type Datamatrix
     BarcodeDescQRCODE=Barcode of type QR code
    -GenbarcodeLocation=Bar code generation command line tool (used by internal engine for some bar code types). Must be compatible with "genbarcode".<br>For example: /usr/local/bin/genbarcode 
    +GenbarcodeLocation=Bar code generation command line tool (used by internal engine for some bar code types). Must be compatible with "genbarcode".<br>For example: /usr/local/bin/genbarcode
     BarcodeInternalEngine=Internal engine
     BarCodeNumberManager=Manager to auto define barcode numbers
     ##### Prelevements #####
    @@ -1503,7 +1511,7 @@ SendingsSetup=Sending module setup
     SendingsReceiptModel=Sending receipt model
     SendingsNumberingModules=Sendings numbering modules
     SendingsAbility=Support shipping sheets for customer deliveries
    -NoNeedForDeliveryReceipts=In most cases, shipping sheets are used both as sheets for customer deliveries (list of products to send) and sheets that is received and signed by customer. So product deliveries receipts is a duplicated feature and is rarely activated.
    +NoNeedForDeliveryReceipts=In most cases, shipping sheets are used both as sheets for customer deliveries (list of products to send) and sheets that are received and signed by customer. Hence the product deliveries receipt is a duplicated feature and is rarely activated.
     FreeLegalTextOnShippings=Free text on shipments
     ##### Deliveries #####
     DeliveryOrderNumberingModules=Products deliveries receipt numbering module
    @@ -1515,18 +1523,18 @@ AdvancedEditor=Advanced editor
     ActivateFCKeditor=Activate advanced editor for:
     FCKeditorForCompany=WYSIWIG creation/edition of elements description and note (except products/services)
     FCKeditorForProduct=WYSIWIG creation/edition of products/services description and note
    -FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). <font class="warning">Warning: Using this option for this case is seriously not recommended as it can create problems with special characters and page formating when building PDF files.</font>
    +FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). <font class="warning">Warning: Using this option for this case is seriously not recommended as it can create problems with special characters and page formatting when building PDF files.</font>
     FCKeditorForMailing= WYSIWIG creation/edition for mass eMailings (Tools->eMailing)
     FCKeditorForUserSignature=WYSIWIG creation/edition of user signature
     FCKeditorForMail=WYSIWIG creation/edition for all mail (except Tools->eMailing)
     ##### OSCommerce 1 #####
    -OSCommerceErrorConnectOkButWrongDatabase=Connection succeeded but database doesn't look to be an OSCommerce database (Key %s not found in table %s).
    -OSCommerceTestOk=Connection to server '%s' on database '%s' with user '%s' successfull.
    -OSCommerceTestKo1=Connection to server '%s' succeed but database '%s' could not be reached.
    +OSCommerceErrorConnectOkButWrongDatabase=Connection succeeded but database does not appear to be an OSCommerce database (Key %s not found in table %s).
    +OSCommerceTestOk=Connection to server '%s' on database '%s' with user '%s' successful.
    +OSCommerceTestKo1=Connection to server '%s' succeeded but database '%s' could not be reached.
     OSCommerceTestKo2=Connection to server '%s' with user '%s' failed.
     ##### Stock #####
     StockSetup=Stock module setup
    -IfYouUsePointOfSaleCheckModule=If you use a Point of Sale module (POS module provided by default or another external module), this setup may be ignored by your Point Of Sale module. Most point of sales modules are designed to create immediatly an invoice and decrease stock by default whatever are options here. So, if you need or not to have a stock decrease when registering a sell from your Point Of Sale, check also your POS module set up.
    +IfYouUsePointOfSaleCheckModule=If you use the Point of Sale module (POS) provided by default or an external module, this setup may be ignored by your POS module. Most POS modules are designed by default to create an invoice immediately and decrease stock irrespective of the options here. So if you need or not to have a stock decrease when registering a sale from your POS, check also your POS module setup.
     ##### Menu #####
     MenuDeleted=Menu deleted
     Menus=Menus
    @@ -1548,7 +1556,7 @@ DetailRight=Condition to display unauthorized grey menus
     DetailLangs=Lang file name for label code translation
     DetailUser=Intern / Extern / All
     Target=Target
    -DetailTarget=Target for links (_blank top open a new window)
    +DetailTarget=Target for links (_blank top opens a new window)
     DetailLevel=Level (-1:top menu, 0:header menu, >0 menu and sub menu)
     ModifMenu=Menu change
     DeleteMenu=Delete menu entry
    @@ -1556,14 +1564,14 @@ ConfirmDeleteMenu=Are you sure you want to delete menu entry <b>%s</b>?
     FailedToInitializeMenu=Failed to initialize menu
     ##### Tax #####
     TaxSetup=Taxes, social or fiscal taxes and dividends module setup
    -OptionVatMode=VAT due 
    +OptionVatMode=VAT due
     OptionVATDefault=Standard basis
     OptionVATDebitOption=Accrual basis
     OptionVatDefaultDesc=VAT is due:<br>- on delivery for goods (we use invoice date)<br>- on payments for services
     OptionVatDebitOptionDesc=VAT is due:<br>- on delivery for goods (we use invoice date)<br>- on invoice (debit) for services
     OptionPaymentForProductAndServices=Cash basis for products and services
     OptionPaymentForProductAndServicesDesc=VAT is due:<br>- on payment for goods<br>- on payments for services
    -SummaryOfVatExigibilityUsedByDefault=Time of VAT exigibility by default according to chosen option: 
    +SummaryOfVatExigibilityUsedByDefault=Time of VAT eligibility by default according to chosen option:
     OnDelivery=On delivery
     OnPayment=On payment
     OnInvoice=On invoice
    @@ -1575,41 +1583,41 @@ InvoiceDateUsed=Invoice date used
     YourCompanyDoesNotUseVAT=Your company has been defined to not use VAT (Home - Setup - Company/Organization), so there is no VAT options to setup.
     AccountancyCode=Accounting Code
     AccountancyCodeSell=Sale account. code
    -AccountancyCodeBuy=Purchase account. code 
    +AccountancyCodeBuy=Purchase account. code
     ##### Agenda #####
     AgendaSetup=Events and agenda module setup
     PasswordTogetVCalExport=Key to authorize export link
     PastDelayVCalExport=Do not export event older than
    -AGENDA_USE_EVENT_TYPE=Use events types (managed into menu Setup -> Dictionaries -> Type of agenda events)
    -AGENDA_USE_EVENT_TYPE_DEFAULT=Set automatically this default value for type of event into event create form
    -AGENDA_DEFAULT_FILTER_TYPE=Set automatically this type of event into search filter of agenda view
    -AGENDA_DEFAULT_FILTER_STATUS=Set automatically this status for events into search filter of agenda view
    +AGENDA_USE_EVENT_TYPE=Use events types (managed in menu Setup -> Dictionaries -> Type of agenda events)
    +AGENDA_USE_EVENT_TYPE_DEFAULT=Automatically set this default value for type of event in event create form
    +AGENDA_DEFAULT_FILTER_TYPE=Automatically set this type of event in search filter of agenda view
    +AGENDA_DEFAULT_FILTER_STATUS=Automatically set this status for events in search filter of agenda view
     AGENDA_DEFAULT_VIEW=Which tab do you want to open by default when selecting menu Agenda
     AGENDA_REMINDER_EMAIL=Enable event reminder <b>by emails</b> (remind option/delay can be defined on each event). Note: Module <strong>%s</strong> must be enabled and correctly setup to have reminder sent at the correct frequency.
    -AGENDA_REMINDER_BROWSER=Enable event reminder <b>on users browser</b> (when event date is reached, each user is able to refuse this from the browser confirmation question)
    +AGENDA_REMINDER_BROWSER=Enable event reminder <b>on user's browser</b> (when event date is reached, each user is able to refuse this from the browser confirmation question)
     AGENDA_REMINDER_BROWSER_SOUND=Enable sound notification
     AGENDA_SHOW_LINKED_OBJECT=Show linked object into agenda view
     ##### Clicktodial #####
     ClickToDialSetup=Click To Dial module setup
     ClickToDialUrlDesc=Url called when a click on phone picto is done.  In URL, you can use tags<br><b>__PHONETO__</b> that will be replaced with the phone number of person to call<br><b>__PHONEFROM__</b> that will be replaced with phone number of calling person (yours)<br><b>__LOGIN__</b> that will be replaced with clicktodial login (defined on user card)<br><b>__PASS__</b> that will be replaced with clicktodial password (defined on user card).
    -ClickToDialDesc=This module allows to make phone numbers clickable. A click on this icon will call make your phone to call the phone number. This can be used to call a call center system from Dolibarr that can call the phone number on a SIP system for example.
    +ClickToDialDesc=This module allows to make phone numbers clickable. A click on this icon will call make your phone call the phone number. This can be used to call a call center system from Dolibarr that can call the phone number on a SIP system for example.
     ClickToDialUseTelLink=Use just a link "tel:" on phone numbers
    -ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface installed on same computer than the browser, and called when you click on a link in your browser that start with "tel:". If you need a full server solution (no need of local software installation), you must set this to "No" and fill next field.
    +ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface installed on the same computer as the browser, and called when you click on a link in your browser that starts with "tel:". If you need a full server solution (no need of local software installation), you must set this to "No" and fill next field.
     ##### Point Of Sales (CashDesk) #####
     CashDesk=Point of sales
     CashDeskSetup=Point of sales module setup
    -CashDeskThirdPartyForSell=Default generic third party to use for sells
    +CashDeskThirdPartyForSell=Default generic third party to use for sales
     CashDeskBankAccountForSell=Default account to use to receive cash payments
     CashDeskBankAccountForCheque= Default account to use to receive payments by cheque
     CashDeskBankAccountForCB= Default account to use to receive payments by credit cards
    -CashDeskDoNotDecreaseStock=Disable stock decrease when a sell is done from Point of Sale (if "no", stock decrease is done for each sell done from POS, whatever is option set into module Stock).
    +CashDeskDoNotDecreaseStock=Disable stock decrease when a sale is done from Point of Sale (if "no", stock decrease is done for each sale done from POS, irrespective of the option set in module Stock).
     CashDeskIdWareHouse=Force and restrict warehouse to use for stock decrease
    -StockDecreaseForPointOfSaleDisabled=Stock decrease from Point Of Sale disabled
    +StockDecreaseForPointOfSaleDisabled=Stock decrease from Point of Sale disabled
     StockDecreaseForPointOfSaleDisabledbyBatch=Stock decrease in POS is not compatible with lot management
    -CashDeskYouDidNotDisableStockDecease=You did not disable stock decrease when making a sell from Point Of Sale. So a warehouse is required.
    +CashDeskYouDidNotDisableStockDecease=You did not disable stock decrease when making a sale from Point of Sale. Hence a warehouse is required.
     ##### Bookmark #####
     BookmarkSetup=Bookmark module setup
    -BookmarkDesc=This module allows you to manage bookmarks. You can also add shortcuts to any Dolibarr pages or externale web sites on your left menu.
    +BookmarkDesc=This module allows you to manage bookmarks. You can also add shortcuts to any Dolibarr pages or external web sites on your left menu.
     NbOfBoomarkToShow=Maximum number of bookmarks to show in left menu
     ##### WebServices #####
     WebServicesSetup=Webservices module setup
    @@ -1623,7 +1631,7 @@ ApiProductionMode=Enable production mode (this will activate use of a cache for
     ApiExporerIs=You can explore and test the APIs at URL
     OnlyActiveElementsAreExposed=Only elements from enabled modules are exposed
     ApiKey=Key for API
    -WarningAPIExplorerDisabled=The API explorer has been disabled. API explorer is not required to provide API services. It is a tool for developer to find/test REST APIs. If you need this tool, go into setup of module API REST to activate it. 
    +WarningAPIExplorerDisabled=The API explorer has been disabled. API explorer is not required to provide API services. It is a tool for developer to find/test REST APIs. If you need this tool, go into setup of module API REST to activate it.
     ##### Bank #####
     BankSetupModule=Bank module setup
     FreeLegalTextOnChequeReceipts=Free text on cheque receipts
    @@ -1675,7 +1683,7 @@ NoAmbiCaracAutoGeneration=Do not use ambiguous characters ("1","l","i","|","0","
     SalariesSetup=Setup of module salaries
     SortOrder=Sort order
     Format=Format
    -TypePaymentDesc=0:Customer payment type, 1:Vendor payment type, 2:Both customers and vendors payment type 
    +TypePaymentDesc=0:Customer payment type, 1:Vendor payment type, 2:Both customers and vendors payment type
     IncludePath=Include path (defined into variable %s)
     ExpenseReportsSetup=Setup of module Expense Reports
     TemplatePDFExpenseReports=Document templates to generate expense report document
    @@ -1687,16 +1695,17 @@ YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for E
     ListOfNotificationsPerUser=List of notifications per user*
     ListOfNotificationsPerUserOrContact=List of notifications per user* or per contact**
     ListOfFixedNotifications=List of fixed notifications
    -GoOntoUserCardToAddMore=Go on the tab "Notifications" of a user to add or remove notifications for users
    -GoOntoContactCardToAddMore=Go on the tab "Notifications" of a third party to add or remove notifications for contacts/addresses
    +GoOntoUserCardToAddMore=Go to the tab "Notifications" of a user to add or remove notifications for users
    +GoOntoContactCardToAddMore=Go on the tab "Notifications" of a third party to add or remove notifications for contact addresses
     Threshold=Threshold
     BackupDumpWizard=Wizard to build database backup dump file
     SomethingMakeInstallFromWebNotPossible=Installation of external module is not possible from the web interface for the following reason:
    -SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is only manual steps a privileged user can do. 
    +SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is only manual steps a privileged user can do.
     InstallModuleFromWebHasBeenDisabledByFile=Install of external module from application has been disabled by your administrator. You must ask him to remove the file <strong>%s</strong> to allow this feature.
    -ConfFileMustContainCustom=Installing or building an external module from application need to save the module files into directory <strong>%s</strong>. To have this directory processed by Dolibarr, you must setup your <strong>conf/conf.php</strong> to add the 2 directive lines:<br><strong>$dolibarr_main_url_root_alt='/custom';</strong><br><strong>$dolibarr_main_document_root_alt='%s/custom';</strong> 
    +ConfFileMustContainCustom=Installing or building an external module from application need to save the module files into directory <strong>%s</strong>. To have this directory processed by Dolibarr, you must setup your <strong>conf/conf.php</strong> to add the 2 directive lines:<br><strong>$dolibarr_main_url_root_alt='/custom';</strong><br><strong>$dolibarr_main_document_root_alt='%s/custom';</strong>
     HighlightLinesOnMouseHover=Highlight table lines when mouse move passes over
     HighlightLinesColor=Highlight color of the line when the mouse passes over (keep empty for no highlight)
    +HighlightLinesChecked=Highlight color of the line when it is checked (keep empty for no highlight)
     TextTitleColor=Text color of Page title
     LinkColor=Color of links
     PressF5AfterChangingThis=Press CTRL+F5 on keyboard or clear your browser cache after changing this value to have it effective
    @@ -1712,16 +1721,16 @@ BackgroundTableLineEvenColor=Background color for even table lines
     MinimumNoticePeriod=Minimum notice period (Your leave request must be done before this delay)
     NbAddedAutomatically=Number of days added to counters of users (automatically) each month
     EnterAnyCode=This field contains a reference to identify line. Enter any value of your choice, but without special characters.
    -UnicodeCurrency=Enter here between braces, list of byte number that represent the currency symbol. For exemple: for $, enter [36] - for brazil real R$ [82,36] - for €, enter [8364]
    +UnicodeCurrency=Enter here between braces, list of byte number that represent the currency symbol. For example: for $, enter [36] - for brazil real R$ [82,36] - for €, enter [8364]
     ColorFormat=The RGB color is in HEX format, eg: FF0000
     PositionIntoComboList=Position of line into combo lists
     SellTaxRate=Sale tax rate
     RecuperableOnly=Yes for VAT "Not Perceived but Recoverable" dedicated for some state in France. Keep value to "No" in all other cases.
     UrlTrackingDesc=If the provider or transport service offer a page or web site to check status of your shipping, you can enter it here. You can use the key {TRACKID} into URL parameters so the system will replace it with value of tracking number user entered into shipment card.
    -OpportunityPercent=When you create an opportunity, you will defined an estimated amount of project/lead. According to status of opportunity, this amount may be multiplicated by this rate to evaluate global amount all your opportunities may generate. Value is percent (between 0 and 100).
    +OpportunityPercent=When you create a lead, you will define an estimated amount of project/lead. According to status of lead, this amount may be multiplied by this rate to evaluate global amount all your opportunities may generate. Value is percent (between 0 and 100).
     TemplateForElement=This template record is dedicated to which element
     TypeOfTemplate=Type of template
    -TemplateIsVisibleByOwnerOnly=Template is visible by owner only
    +TemplateIsVisibleByOwnerOnly=Template is visible to owner only
     VisibleEverywhere=Visible everywhere
     VisibleNowhere=Visible nowhere
     FixTZ=TimeZone fix
    @@ -1747,10 +1756,10 @@ YouUseLastStableVersion=You use the latest stable version
     TitleExampleForMajorRelease=Example of message you can use to announce this major release (feel free to use it on your web sites)
     TitleExampleForMaintenanceRelease=Example of message you can use to announce this maintenance release (feel free to use it on your web sites)
     ExampleOfNewsMessageForMajorRelease=Dolibarr ERP & CRM %s is available. Version %s is a major release with a lot of new features for both users and developers. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read <a href="https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog">ChangeLog</a> for complete list of changes.
    -ExampleOfNewsMessageForMaintenanceRelease=Dolibarr ERP & CRM %s is available. Version %s is a maintenance version, so it contains only fixes of bugs. We recommend everybody using an older version to upgrade to this one. As any maintenance release, no new features, nor data structure change is present into this version. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read <a href="https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog">ChangeLog</a> for complete list of changes.
    -MultiPriceRuleDesc=When option "Several level of prices per product/service" is on, you can define different prices (one per price level) for each product. To save you time, you can enter here rule to have price for each level autocalculated according to price of first level, so you will have to enter only price for first level on each product. This page is here to save you time and can be usefull only if your prices for each leve are relative to first level. You can ignore this page in most cases.
    +ExampleOfNewsMessageForMaintenanceRelease=Dolibarr ERP & CRM %s is available. Version %s is a maintenance version, so it contains only fixes of bugs. We recommend everybody using an older version to upgrade to this one. As any maintenance release, no new features or data structure change is present in this version. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read <a href="https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog">ChangeLog</a> for complete list of changes.
    +MultiPriceRuleDesc=When option "Several level of prices per product/service" is on, you can define different prices (one per price level) for each product. To save you time, here you can enter a rule to have a price for each level autocalculated according to the price of first level, so you will have to only enter a price for the first level on each product. This page is here to save you time and can be useful only if your prices for each level are relative to first level. You can ignore this page in most cases.
     ModelModulesProduct=Templates for product documents
    -ToGenerateCodeDefineAutomaticRuleFirst=To be able to generate automatically codes, you must first define a manager to auto define barcode number.
    +ToGenerateCodeDefineAutomaticRuleFirst=To be able to generate codes automatically, you must first define a manager to auto define barcode number.
     SeeSubstitutionVars=See * note for list of possible substitution variables
     SeeChangeLog=See ChangeLog file (english only)
     AllPublishers=All publishers
    @@ -1771,35 +1780,45 @@ AddOtherPagesOrServices=Add other pages or services
     AddModels=Add document or numbering templates
     AddSubstitutions=Add keys substitutions
     DetectionNotPossible=Detection not possible
    -UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved on database user table and must be provided on each API call) 
    +UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved in database user table and must be provided on each API call)
     ListOfAvailableAPIs=List of available APIs
    -activateModuleDependNotSatisfied=Module "%s" depends on module "%s" that is missing, so module "%1$s" may not work correclty. Please install module "%2$s" or disable module "%1$s" if you want to be safe from any surprise
    -CommandIsNotInsideAllowedCommands=The command you try to run is not inside list of allowed commands defined into parameter <strong>$dolibarr_main_restrict_os_commands</strong> into <strong>conf.php</strong> file.
    +activateModuleDependNotSatisfied=Module "%s" depends on module "%s", that is missing, so module "%1$s" may not work correctly. Please install module "%2$s" or disable module "%1$s" if you want to be safe from any surprise
    +CommandIsNotInsideAllowedCommands=The command you are trying to run is not in the list of allowed commands defined in parameter <strong>$dolibarr_main_restrict_os_commands</strong> in the <strong>conf.php</strong> file.
     LandingPage=Landing page
    -SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", price will be also the same for all companies if products are shared between environments
    +SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", the price will also be the same for all companies if products are shared between environments
     ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for activated module(s) were given to admin users only. You may need to grant permissions to other users or groups manually if necessary.
    -UserHasNoPermissions=This user has no permission defined
    -TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "Nb of days")<br>Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "Offset" in days)<br>Use "Current/Next" to have payment term date being the first Nth of the month (N is stored into field "Nb of days")
    +UserHasNoPermissions=This user has no permissions defined
    +TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "%s")<br>Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "%s" in days)<br>Use "Current/Next" to have payment term date being the first Nth of the month after delta (delta is field "%s", N is stored into field "%s")
     BaseCurrency=Reference currency of the company (go into setup of company to change this)
    -WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016). 
    -WarningNoteModulePOSForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated. 
    -WarningInstallationMayBecomeNotCompliantWithLaw=You try to install the module %s that is an external module. Activating an external module means you trust the publisher of the module and you are sure that this module does not alterate negatively the behavior of your application and is compliant with laws of your country (%s). If the module bring a non legal feature, you become responsible for the use of a non legal software.
    +WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with French laws (Loi Finance 2016).
    +WarningNoteModulePOSForFrenchLaw=This module %s is compliant with French laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated.
    +WarningInstallationMayBecomeNotCompliantWithLaw=You are trying to install module %s that is an external module. Activating an external module means you trust the publisher of that module and that you are sure that this module does not adversely impact the behavior of your application, and is compliant with laws of your country (%s). If the module introduces an illegal feature, you become responsible for the use of illegal software.
     MAIN_PDF_MARGIN_LEFT=Left margin on PDF
     MAIN_PDF_MARGIN_RIGHT=Right margin on PDF
     MAIN_PDF_MARGIN_TOP=Top margin on PDF
     MAIN_PDF_MARGIN_BOTTOM=Bottom margin on PDF
     NothingToSetup=There is no specific setup to do for this module.
     SetToYesIfGroupIsComputationOfOtherGroups=Set this to yes if this group is a computation of other groups
    -EnterCalculationRuleIfPreviousFieldIsYes=Enter calculcation rule if previous field was set to Yes (For example 'CODEGRP1+CODEGRP2')
    +EnterCalculationRuleIfPreviousFieldIsYes=Enter calculation rule if previous field was set to Yes (For example 'CODEGRP1+CODEGRP2')
     SeveralLangugeVariatFound=Several language variants found
     COMPANY_AQUARIUM_REMOVE_SPECIAL=Remove special characters
     COMPANY_AQUARIUM_CLEAN_REGEX=Regex filter to clean value (COMPANY_AQUARIUM_CLEAN_REGEX)
    -GDPRContact=Privacy Policies or GDPR contact
    -GDPRContactDesc=If you store data about European companies/citizen, you can store here the contact who is responsible for the General Data Protection Regulation
    +GDPRContact=Data Protection Officer (DPO, Data Privacy or GDPR contact)
    +GDPRContactDesc=If you store data about European companies/citizen, you can store the contact who is responsible for the General Data Protection Regulation here
    +HelpOnTooltip=Help text to show on tooltip
    +HelpOnTooltipDesc=Put text or a translation key here for the text to show on a tooltip when this field appears in a form
     YouCanDeleteFileOnServerWith=You can delete this file on server with Command Line:<br>%s
    +ChartLoaded=Chart of account loaded
    +SocialNetworkSetup=Setup of module Social Networks
    +EnableFeatureFor=Enable features for <strong>%s</strong>
    +VATIsUsedIsOff=Note: The option to use sales Tax or VAT has been set to <strong>Off</strong> in the menu %s - %s, so Sale tax or Vat used will always be 0 for sales.
    +SwapSenderAndRecipientOnPDF=Swap sender and recipient address on PDF
    +FeatureSupportedOnTextFieldsOnly=Warning, feature supported on text fields only
     ##### Resource ####
    -ResourceSetup=Configuration du module Resource 
    +ResourceSetup=Configuration du module Resource
     UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list).
     DisabledResourceLinkUser=Disable feature to link a resource to users
     DisabledResourceLinkContact=Disable feature to link a resource to contacts
     ConfirmUnactivation=Confirm module reset
    +OnMobileOnly=On small screen (smartphone) only
    +DisableProspectCustomerType=Disable the "Prospect + Customer" third party type (so third party must be Prospect or Customer but can't be both)
    diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang
    index 4a7ab99ca77..cd39a43abe8 100644
    --- a/htdocs/langs/en_US/agenda.lang
    +++ b/htdocs/langs/en_US/agenda.lang
    @@ -1,12 +1,12 @@
    -# Dolibarr language file - Source file is en_US - agenda 
    +# Dolibarr language file - Source file is en_US - agenda
     IdAgenda=ID event
     Actions=Events
     Agenda=Agenda
     TMenuAgenda=Agenda
     Agendas=Agendas
     LocalAgenda=Internal calendar
    -ActionsOwnedBy=Event owned by 
    -ActionsOwnedByShort=Owner 
    +ActionsOwnedBy=Event owned by
    +ActionsOwnedByShort=Owner
     AffectedTo=Assigned to
     Event=Event
     Events=Events
    @@ -31,14 +31,15 @@ ViewWeek=Week view
     ViewPerUser=Per user view
     ViewPerType=Per type view
     AutoActions= Automatic filling
    -AgendaAutoActionDesc= Define here events for which you want Dolibarr to create automatically an event in agenda. If nothing is checked, only manual actions will be included in logged and visible into agenda. Automatic tracking of business actions done on objects (validation, status change) will not be saved. 
    -AgendaSetupOtherDesc= This page provides options to allow export of your Dolibarr events into an external calendar (thunderbird, google calendar, ...)
    +AgendaAutoActionDesc= Here you can define events which you want Dolibarr to create automatically  in Agenda. If nothing is checked, only manual actions will be included in logs and displayed in Agenda. Automatic tracking of business actions done on objects (validation, status change) will not be saved.
    +AgendaSetupOtherDesc= This page provides options to allow exports of your Dolibarr events into an external calendar (thunderbird, google calendar, ...)
     AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda.
     ActionsEvents=Events for which Dolibarr will create an action in agenda automatically
     EventRemindersByEmailNotEnabled=Event reminders by email was not enabled into %s module setup.
     ##### Agenda event labels #####
     NewCompanyToDolibarr=Third party %s created
     ContractValidatedInDolibarr=Contract %s validated
    +CONTRACT_DELETEInDolibarr=Contract %s deleted
     PropalClosedSignedInDolibarr=Proposal %s signed
     PropalClosedRefusedInDolibarr=Proposal %s refused
     PropalValidatedInDolibarr=Proposal %s validated
    @@ -110,7 +111,7 @@ DefaultWorkingHours=Default working hours in day (Example: 9-18)
     # External Sites ical
     ExportCal=Export calendar
     ExtSites=Import external calendars
    -ExtSitesEnableThisTool=Show external calendars (defined into global setup) into agenda. Does not affect external calendars defined by users.
    +ExtSitesEnableThisTool=Show external calendars (defined in global setup) in Agenda. Does not affect external calendars defined by users.
     ExtSitesNbOfAgenda=Number of calendars
     AgendaExtNb=Calendar no. %s
     ExtSiteUrlAgenda=URL to access .ical file
    diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang
    index c62dc0498e0..7650613341e 100644
    --- a/htdocs/langs/en_US/banks.lang
    +++ b/htdocs/langs/en_US/banks.lang
    @@ -7,7 +7,7 @@ BankName=Bank name
     FinancialAccount=Account
     BankAccount=Bank account
     BankAccounts=Bank accounts
    -BankAccountsAndGateways=Bank accounts | Gateways
    +BankAccountsAndGateways=Bank | Gateways
     ShowAccount=Show Account
     AccountRef=Financial account ref
     AccountLabel=Financial account label
    @@ -46,7 +46,7 @@ BankAccountDomiciliation=Account address
     BankAccountCountry=Account country
     BankAccountOwner=Account owner name
     BankAccountOwnerAddress=Account owner address
    -RIBControlError=Integrity check of values fails. This means information for this account number are not complete or wrong (check country, numbers and IBAN).
    +RIBControlError=Integrity check of values fails. This means the information for this account number is incomplete or incorrect (check country, numbers and IBAN).
     CreateAccount=Create account
     NewBankAccount=New account
     NewFinancialAccount=New financial account
    @@ -76,6 +76,7 @@ TransactionsToConciliate=Entries to reconcile
     Conciliable=Can be reconciled
     Conciliate=Reconcile
     Conciliation=Reconciliation
    +SaveStatementOnly=Save statement only
     ReconciliationLate=Reconciliation late
     IncludeClosedAccount=Include closed accounts
     OnlyOpenedAccount=Only open accounts
    @@ -104,7 +105,7 @@ SocialContributionPayment=Social/fiscal tax payment
     BankTransfer=Bank transfer
     BankTransfers=Bank transfers
     MenuBankInternalTransfer=Internal transfer
    -TransferDesc=Transfer from one account to another one, Dolibarr will write two record (a debit in source account and a credit in target account. The same amount (except sign), label and date will be used for this transaction)
    +TransferDesc=Transfer from one account to another one, Dolibarr will write two records (a debit in source account and a credit in target account). The same amount (except sign), label and date will be used for this transaction)
     TransferFrom=From
     TransferTo=To
     TransferFromToDone=A transfer from <b>%s</b> to <b>%s</b> of <b>%s</b> %s has been recorded.
    @@ -135,8 +136,8 @@ BankTransactionLine=Bank entry
     AllAccounts=All bank and cash accounts
     BackToAccount=Back to account
     ShowAllAccounts=Show for all accounts
    -FutureTransaction=Transaction in futur. No way to conciliate.
    -SelectChequeTransactionAndGenerate=Select/filter checks to include into the check deposit receipt and click on "Create".
    +FutureTransaction=Transaction in future. No way to reconcile.
    +SelectChequeTransactionAndGenerate=Select/filter checks to include in the check deposit receipt and click on "Create".
     InputReceiptNumber=Choose the bank statement related with the conciliation. Use a sortable numeric value: YYYYMM or YYYYMMDD
     EventualyAddCategory=Eventually, specify a category in which to classify the records
     ToConciliate=To reconcile?
    @@ -153,7 +154,7 @@ RejectCheckDate=Date the check was returned
     CheckRejected=Check returned
     CheckRejectedAndInvoicesReopened=Check returned and invoices reopened
     BankAccountModelModule=Document templates for bank accounts
    -DocumentModelSepaMandate=Template of SEPA mandate. Usefull for european countries in EEC only.
    +DocumentModelSepaMandate=Template of SEPA mandate. Useful for European countries in EEC only.
     DocumentModelBan=Template to print a page with BAN information.
     NewVariousPayment=New miscellaneous payments
     VariousPayment=Miscellaneous payments
    @@ -162,4 +163,4 @@ ShowVariousPayment=Show miscellaneous payments
     AddVariousPayment=Add miscellaneous payments
     SEPAMandate=SEPA mandate
     YourSEPAMandate=Your SEPA mandate
    -FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Thanks to return it signed (scan of the signed document) or sent it by mail to 
    +FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Return it signed (scan of the signed document) or send it by mail to
    diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
    index fae0f88fcc5..9e3d2a4af98 100644
    --- a/htdocs/langs/en_US/bills.lang
    +++ b/htdocs/langs/en_US/bills.lang
    @@ -25,12 +25,12 @@ InvoiceProFormaAsk=Proforma invoice
     InvoiceProFormaDesc=<b>Proforma invoice</b> is an image of a true invoice but has no accountancy value.
     InvoiceReplacement=Replacement invoice
     InvoiceReplacementAsk=Replacement invoice for invoice
    -InvoiceReplacementDesc=<b>Replacement invoice</b> is used to cancel and replace completely an invoice with no payment already received.<br><br>Note: Only invoices with no payment on it can be replaced. If the invoice you replace is not yet closed, it will be automatically closed to 'abandoned'.
    +InvoiceReplacementDesc=<b>Replacement invoice</b> is used to cancel and completely replace an invoice with no payment already received.<br><br>Note: Only invoices with no payment on it can be replaced. If the invoice you replace is not yet closed, it will be automatically closed to 'abandoned'.
     InvoiceAvoir=Credit note
     InvoiceAvoirAsk=Credit note to correct invoice
    -InvoiceAvoirDesc=The <b>credit note</b> is a negative invoice used to solve fact that an invoice has an amount that differs than amount really paid (because customer paid too much by error, or will not paid completely since he returned some products for example).
    +InvoiceAvoirDesc=The <b>credit note</b> is a negative invoice used to correct the fact that an invoice has an amount that differs from the amount really paid (eg customer paid too much by mistake, or will not pay completely since he returned some products).
     invoiceAvoirWithLines=Create Credit Note with lines from the origin invoice
    -invoiceAvoirWithPaymentRestAmount=Create Credit Note with remaining unpaid of origin invoice 
    +invoiceAvoirWithPaymentRestAmount=Create Credit Note with remaining unpaid of origin invoice
     invoiceAvoirLineWithPaymentRestAmount=Credit Note for remaining unpaid amount
     ReplaceInvoice=Replace invoice %s
     ReplacementInvoice=Replacement invoice
    @@ -66,12 +66,12 @@ paymentInInvoiceCurrency=in invoices currency
     PaidBack=Paid back
     DeletePayment=Delete payment
     ConfirmDeletePayment=Are you sure you want to delete this payment?
    -ConfirmConvertToReduc=Do you want to convert this %s into an absolute discount ?<br>The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this customer.
    -ConfirmConvertToReducSupplier=Do you want to convert this %s into an absolute discount ?<br>The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this supplier.
    +ConfirmConvertToReduc=Do you want to convert this %s into an absolute discount?<br>The amount will be saved among all discounts and could be used as a discount for a current or a future invoice for this customer.
    +ConfirmConvertToReducSupplier=Do you want to convert this %s into an absolute discount?<br>The amount will be saved among all discounts and could be used as a discount for a current or a future invoice for this supplier.
     SupplierPayments=Suppliers payments
     ReceivedPayments=Received payments
     ReceivedCustomersPayments=Payments received from customers
    -PayedSuppliersPayments=Payments payed to suppliers
    +PayedSuppliersPayments=Payments paid to suppliers
     ReceivedCustomersPaymentsToValid=Received customers payments to validate
     PaymentsReportsForYear=Payments reports for %s
     PaymentsReports=Payments reports
    @@ -91,8 +91,8 @@ PaymentConditionsShort=Payment terms
     PaymentAmount=Payment amount
     ValidatePayment=Validate payment
     PaymentHigherThanReminderToPay=Payment higher than reminder to pay
    -HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess received for each overpaid invoices.
    -HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess paid for each overpaid invoice.
    +HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess received for each overpaid invoice.
    +HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess paid for each overpaid invoice.
     ClassifyPaid=Classify 'Paid'
     ClassifyPaidPartially=Classify 'Paid partially'
     ClassifyCanceled=Classify 'Abandoned'
    @@ -131,7 +131,8 @@ BillStatusClosedUnpaid=Closed (unpaid)
     BillStatusClosedPaidPartially=Paid (partially)
     BillShortStatusDraft=Draft
     BillShortStatusPaid=Paid
    -BillShortStatusPaidBackOrConverted=Refund or converted
    +BillShortStatusPaidBackOrConverted=Refunded or converted
    +Refunded=Refunded
     BillShortStatusConverted=Paid
     BillShortStatusCanceled=Abandoned
     BillShortStatusValidated=Validated
    @@ -141,16 +142,16 @@ BillShortStatusNotRefunded=Not refunded
     BillShortStatusClosedUnpaid=Closed
     BillShortStatusClosedPaidPartially=Paid (partially)
     PaymentStatusToValidShort=To validate
    -ErrorVATIntraNotConfigured=Intracommunautary VAT number not yet defined
    +ErrorVATIntraNotConfigured=Intra-Community VAT number not yet defined
     ErrorNoPaiementModeConfigured=No default payment mode defined. Go to Invoice module setup to fix this.
     ErrorCreateBankAccount=Create a bank account, then go to Setup panel of Invoice module to define payment modes
     ErrorBillNotFound=Invoice %s does not exist
    -ErrorInvoiceAlreadyReplaced=Error, you try to validate an invoice to replace invoice %s. But this one has already been replaced by invoice %s.
    +ErrorInvoiceAlreadyReplaced=Error, you tried to validate an invoice to replace invoice %s. But this one has already been replaced by invoice %s.
     ErrorDiscountAlreadyUsed=Error, discount already used
     ErrorInvoiceAvoirMustBeNegative=Error, correct invoice must have a negative amount
     ErrorInvoiceOfThisTypeMustBePositive=Error, this type of invoice must have a positive amount
     ErrorCantCancelIfReplacementInvoiceNotValidated=Error, can't cancel an invoice that has been replaced by another invoice that is still in draft status
    -ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved=This part or another is already used so discount serie cant be removed.
    +ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved=This part or another is already used so discount series cannot be removed.
     BillFrom=From
     BillTo=To
     ActionsOnBill=Actions on invoice
    @@ -179,20 +180,20 @@ ConfirmClassifyPaidBill=Are you sure you want to change invoice <b>%s</b> to sta
     ConfirmCancelBill=Are you sure you want to cancel invoice <b>%s</b>?
     ConfirmCancelBillQuestion=Why do you want to classify this invoice 'abandoned'?
     ConfirmClassifyPaidPartially=Are you sure you want to change invoice <b>%s</b> to status paid?
    -ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What are reasons for you to close this invoice?
    -ConfirmClassifyPaidPartiallyReasonAvoir=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I regularise the VAT with a credit note.
    +ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What is the reason/s for you closing this invoice?
    +ConfirmClassifyPaidPartiallyReasonAvoir=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I regularize the VAT with a credit note.
     ConfirmClassifyPaidPartiallyReasonDiscount=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term.
     ConfirmClassifyPaidPartiallyReasonDiscountNoVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I accept to lose the VAT on this discount.
    -ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note. 
    +ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note.
     ConfirmClassifyPaidPartiallyReasonBadCustomer=Bad customer
     ConfirmClassifyPaidPartiallyReasonProductReturned=Products partially returned
     ConfirmClassifyPaidPartiallyReasonOther=Amount abandoned for other reason
    -ConfirmClassifyPaidPartiallyReasonDiscountNoVatDesc=This choice is possible if your invoice have been provided with suitable comment. (Example «Only the tax corresponding to the price that have been actually paid gives rights to deduction»)
    -ConfirmClassifyPaidPartiallyReasonDiscountVatDesc=In some countries, this choice might be possible only if your invoice contains correct note.
    +ConfirmClassifyPaidPartiallyReasonDiscountNoVatDesc=This choice is possible if your invoice has been provided with suitable comments. (Example «Only the tax corresponding to the price that has been actually paid gives rights to deduction»)
    +ConfirmClassifyPaidPartiallyReasonDiscountVatDesc=In some countries, this choice might be possible only if your invoice contains correct notes.
     ConfirmClassifyPaidPartiallyReasonAvoirDesc=Use this choice if all other does not suit
    -ConfirmClassifyPaidPartiallyReasonBadCustomerDesc=A <b>bad customer</b> is a customer that refuse to pay his debt.
    +ConfirmClassifyPaidPartiallyReasonBadCustomerDesc=A <b>bad customer</b> is a customer that refuses to pay his debt.
     ConfirmClassifyPaidPartiallyReasonProductReturnedDesc=This choice is used when payment is not complete because some of products were returned
    -ConfirmClassifyPaidPartiallyReasonOtherDesc=Use this choice if all other does not suit, for example in following situation:<br>- payment not complete because some products were shipped back<br>- amount claimed too important because a discount was forgotten<br>In all cases, amount over-claimed must be corrected in accountancy system by creating a credit note.
    +ConfirmClassifyPaidPartiallyReasonOtherDesc=Use this choice if all others are not suitable, for example in following situation:<br>- payment not complete because some products were shipped back<br>- amount claimed too important because a discount was forgotten<br>In all cases, amount over-claimed must be corrected in accountancy system by creating a credit note.
     ConfirmClassifyAbandonReasonOther=Other
     ConfirmClassifyAbandonReasonOtherDesc=This choice will be used in all other cases. For example because you plan to create a replacing invoice.
     ConfirmCustomerPayment=Do you confirm this payment input for <b>%s</b> %s?
    @@ -203,6 +204,7 @@ UnvalidateBill=Unvalidate invoice
     NumberOfBills=No. of invoices
     NumberOfBillsByMonth=No. of invoices per month
     AmountOfBills=Amount of invoices
    +AmountOfBillsHT=Amount of invoices (net of tax)
     AmountOfBillsByMonthHT=Amount of invoices by month (net of tax)
     ShowSocialContribution=Show social/fiscal tax
     ShowBill=Show invoice
    @@ -302,9 +304,9 @@ DiscountAlreadyCounted=Discounts or credits already consumed
     CustomerDiscounts=Customer discounts
     SupplierDiscounts=Vendors discounts
     BillAddress=Bill address
    -HelpEscompte=This discount is a discount granted to customer because its payment was made before term.
    -HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loose.
    -HelpAbandonOther=This amount has been abandoned since it was an error (wrong customer or invoice replaced by an other for example)
    +HelpEscompte=This discount is a discount granted to customer because payment was made before term.
    +HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loss.
    +HelpAbandonOther=This amount has been abandoned since it was an error (wrong customer or invoice replaced by another for example)
     IdSocialContribution=Social/fiscal tax payment id
     PaymentId=Payment id
     PaymentRef=Payment ref.
    @@ -321,22 +323,22 @@ InvoiceNotChecked=No invoice selected
     CloneInvoice=Clone invoice
     ConfirmCloneInvoice=Are you sure you want to clone this invoice <b>%s</b>?
     DisabledBecauseReplacedInvoice=Action disabled because invoice has been replaced
    -DescTaxAndDividendsArea=This area presents a summary of all payments made for special expenses. Only record with payment during the fixed year are included here.
    +DescTaxAndDividendsArea=This area presents a summary of all payments made for special expenses. Only records with payment during the fixed year are included here.
     NbOfPayments=No. of payments
     SplitDiscount=Split discount in two
    -ConfirmSplitDiscount=Are you sure you want to split this discount of <b>%s</b> %s into 2 lower discounts?
    -TypeAmountOfEachNewDiscount=Input amount for each of two parts :
    -TotalOfTwoDiscountMustEqualsOriginal=Total of two new discount must be equal to original discount amount. 
    +ConfirmSplitDiscount=Are you sure you want to split this discount of <b>%s</b> %s into 2 smaller discounts?
    +TypeAmountOfEachNewDiscount=Input amount for each of two parts:
    +TotalOfTwoDiscountMustEqualsOriginal=Total of two new discounts must be equal to original discount amount.
     ConfirmRemoveDiscount=Are you sure you want to remove this discount?
     RelatedBill=Related invoice
     RelatedBills=Related invoices
     RelatedCustomerInvoices=Related customer invoices
     RelatedSupplierInvoices=Related supplier invoices
     LatestRelatedBill=Latest related invoice
    -WarningBillExist=Warning, one or more invoice already exist
    +WarningBillExist=Warning, one or more invoices already exist
     MergingPDFTool=Merging PDF tool
     AmountPaymentDistributedOnInvoice=Payment amount distributed on invoice
    -PaymentOnDifferentThirdBills=Allow payments on different thirdparties bills but same parent company
    +PaymentOnDifferentThirdBills=Allow payments on different third parties bills but same parent company
     PaymentNote=Payment note
     ListOfPreviousSituationInvoices=List of previous situation invoices
     ListOfNextSituationInvoices=List of next situation invoices
    @@ -344,7 +346,7 @@ ListOfSituationInvoices=List of situation invoices
     CurrentSituationTotal=Total current situation
     DisabledBecauseNotEnouthCreditNote=To remove a situation invoice from cycle, this invoice's credit note total must cover this invoice total
     RemoveSituationFromCycle=Remove this invoice from cycle
    -ConfirmRemoveSituationFromCycle=Remove this invoice %s from cycle ? 
    +ConfirmRemoveSituationFromCycle=Remove this invoice %s from cycle ?
     ConfirmOuting=Confirm outing
     FrequencyPer_d=Every %s days
     FrequencyPer_m=Every %s months
    @@ -408,19 +410,19 @@ PaymentTypeCHQ=Check
     PaymentTypeShortCHQ=Check
     PaymentTypeTIP=TIP (Documents against Payment)
     PaymentTypeShortTIP=TIP Payment
    -PaymentTypeVAD=On line payment
    -PaymentTypeShortVAD=On line payment
    +PaymentTypeVAD=Online payment
    +PaymentTypeShortVAD=Online payment
     PaymentTypeTRA=Bank draft
     PaymentTypeShortTRA=Draft
     PaymentTypeFAC=Factor
     PaymentTypeShortFAC=Factor
     BankDetails=Bank details
     BankCode=Bank code
    -DeskCode=Desk code
    +DeskCode=Office code
     BankAccountNumber=Account number
    -BankAccountNumberKey=Key
    +BankAccountNumberKey=Check digits
     Residence=Direct debit
    -IBANNumber=IBAN number
    +IBANNumber=IBAN complete account number
     IBAN=IBAN
     BIC=BIC/SWIFT
     BICNumber=BIC/SWIFT number
    @@ -436,7 +438,7 @@ NetToBePaid=Net to be paid
     PhoneNumber=Tel
     FullPhoneNumber=Telephone
     TeleFax=Fax
    -PrettyLittleSentence=Accept the amount of payments due by checks issued in my name as a Member of an accounting association approved by the Fiscal Administration.  
    +PrettyLittleSentence=Accept the amount of payments due by checks issued in my name as a Member of an accounting association approved by the Fiscal Administration.
     IntracommunityVATNumber=Intracommunity number of VAT
     PaymentByChequeOrderedTo=Check payment (including tax) are payable to %s send to
     PaymentByChequeOrderedToShort=Check payment (including tax) are payable to
    @@ -445,7 +447,7 @@ PaymentByTransferOnThisBankAccount=Payment by transfer on the following bank acc
     VATIsNotUsedForInvoice=* Non applicable VAT art-293B of CGI
     LawApplicationPart1=By application of the law 80.335 of 12/05/80
     LawApplicationPart2=the goods remain the property of
    -LawApplicationPart3=the seller until the complete cashing of
    +LawApplicationPart3=the seller until full payment of
     LawApplicationPart4=their price.
     LimitedLiabilityCompanyCapital=SARL with Capital of
     UseLine=Apply
    @@ -474,21 +476,22 @@ Reported=Delayed
     DisabledBecausePayments=Not possible since there are some payments
     CantRemovePaymentWithOneInvoicePaid=Can't remove payment since there is at least one invoice classified paid
     ExpectedToPay=Expected payment
    -CantRemoveConciliatedPayment=Can't remove conciliated payment
    +CantRemoveConciliatedPayment=Can't remove reconciled payment
     PayedByThisPayment=Paid by this payment
    -ClosePaidInvoicesAutomatically=Classify "Paid" all standard, down payment or replacement invoices entirely paid.
    +ClosePaidInvoicesAutomatically=Classify "Paid" all standard, down payment or replacement invoices paid entirely.
     ClosePaidCreditNotesAutomatically=Classify "Paid" all credit notes entirely paid back.
    -ClosePaidContributionsAutomatically=Classify "Paid" all social or fiscal contributions entirely paid.
    -AllCompletelyPayedInvoiceWillBeClosed=All invoice with no remain to pay will be automatically closed to status "Paid".
    +ClosePaidContributionsAutomatically=Classify "Paid" all social or fiscal contributions paid entirely.
    +AllCompletelyPayedInvoiceWillBeClosed=All invoice with no remainder to pay will be automatically closed with status "Paid".
     ToMakePayment=Pay
     ToMakePaymentBack=Pay back
     ListOfYourUnpaidInvoices=List of unpaid invoices
     NoteListOfYourUnpaidInvoices=Note: This list contains only invoices for third parties you are linked to as a sale representative.
     RevenueStamp=Revenue stamp
    -YouMustCreateInvoiceFromThird=This option is only available when creating invoice from tab "customer" of third party
    -YouMustCreateInvoiceFromSupplierThird=This option is only available when creating invoice from tab "supplier" of third party
    +YouMustCreateInvoiceFromThird=This option is only available when creating invoices from tab "customer" of third party
    +YouMustCreateInvoiceFromSupplierThird=This option is only available when creating invoices from tab "supplier" of third party
     YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice first and convert it to "template" to create a new template invoice
     PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (recommended Template)
    +PDFSpongeDescription=Invoice PDF template Sponge. A complete invoice template
     PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for situation invoices
     TerreNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0
     MarsNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for down payment invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0
    @@ -533,7 +536,7 @@ invoiceLineProgressError=Invoice line progress can't be greater than or equal to
     updatePriceNextInvoiceErrorUpdateline=Error : update price on invoice line : %s
     ToCreateARecurringInvoice=To create a recurring invoice for this contract, first create this draft invoice, then convert it into an invoice template and define the frequency for generation of future invoices.
     ToCreateARecurringInvoiceGene=To generate future invoices regularly and manually, just go on menu <strong>%s - %s - %s</strong>.
    -ToCreateARecurringInvoiceGeneAuto=If you need to have such invoices generated automatically, ask you administrator to enable and setup module <strong>%s</strong>. Note that both method (manual and automatic) can be used together with no risk of duplication.
    +ToCreateARecurringInvoiceGeneAuto=If you need to have such invoices generated automatically, ask your administrator to enable and setup module <strong>%s</strong>. Note that both method (manual and automatic) can be used together with no risk of duplication.
     DeleteRepeatableInvoice=Delete template invoice
     ConfirmDeleteRepeatableInvoice=Are your sure you want to delete the template invoice?
     CreateOneBillByThird=Create one invoice per third party (otherwise, one invoice per order)
    @@ -546,3 +549,4 @@ AutoFillDateFromShort=Set start date
     AutoFillDateTo=Set end date for service line with next invoice date
     AutoFillDateToShort=Set end date
     MaxNumberOfGenerationReached=Max number of gen. reached
    +BILL_DELETEInDolibarr=Invoice deleted
    diff --git a/htdocs/langs/en_US/blockedlog.lang b/htdocs/langs/en_US/blockedlog.lang
    index fa56db7eed6..88d3662be9c 100644
    --- a/htdocs/langs/en_US/blockedlog.lang
    +++ b/htdocs/langs/en_US/blockedlog.lang
    @@ -2,13 +2,13 @@ BlockedLog=Unalterable Logs
     Field=Field
     BlockedLogDesc=This module tracks some events into an unalterable log (that you can't modify once recorded) into a block chain, in real time. This module provides compatibility with requirements of laws of some countries (like France with the law Finance 2016 - Norme NF535).
     Fingerprints=Archived events and fingerprints
    -FingerprintsDesc=This is the tool to browse or extract the unalterable logs. Unalterable logs are generated and archived locally into a dedicated table, in real time when you record a business event. You can use this tool to export this archive and save it into an external support (some countries, like France, ask you do it every year). Note that, there is no feature to purge this log and every change tried to be done directly into this log (by a hacker for example) will be reported with a non valid fingerprint. If you really need to purge this table because you used your application for a demo/test purpose and want to clean your data to start your production, you can ask your reseller or integrator to reset your database (all your data will be removed).  
    +FingerprintsDesc=This is the tool to browse or extract the unalterable logs. Unalterable logs are generated and archived locally into a dedicated table, in real time when you record a business event. You can use this tool to export this archive and save it into an external support (some countries, like France, ask that you do it every year). Note that, there is no feature to purge this log and every change tried to be done directly into this log (by a hacker for example) will be reported with a non-valid fingerprint. If you really need to purge this table because you used your application for a demo/test purpose and want to clean your data to start your production, you can ask your reseller or integrator to reset your database (all your data will be removed).
     CompanyInitialKey=Company initial key (hash of genesis block)
     BrowseBlockedLog=Unalterable logs
     ShowAllFingerPrintsMightBeTooLong=Show all archived logs (might be long)
    -ShowAllFingerPrintsErrorsMightBeTooLong=Show all non valid archive logs (might be long)
    +ShowAllFingerPrintsErrorsMightBeTooLong=Show all non-valid archive logs (might be long)
     DownloadBlockChain=Download fingerprints
    -KoCheckFingerprintValidity=Archived log is not valid. It means someone (a hacker ?) has modified some datas of this archived log after it was recorded, or has erased the previous archived record (check that line with previous # exists).
    +KoCheckFingerprintValidity=Archived log is not valid. It means someone (a hacker?) has modified some data of this archived log after it was recorded, or has erased the previous archived record (check that line with previous # exists).
     OkCheckFingerprintValidity=Archived log is valid. It means all data on this line were not modified and record follow the previous one.
     OkCheckFingerprintValidityButChainIsKo=Archived log seems valid compared to previous one but the chain was corrupted previously.
     AddedByAuthority=Stored into remote authority
    @@ -22,8 +22,8 @@ logPAYMENT_CUSTOMER_CREATE=Customer payment created
     logPAYMENT_CUSTOMER_DELETE=Customer payment logical deletion
     logDONATION_PAYMENT_CREATE=Donation payment created
     logDONATION_PAYMENT_DELETE=Donation payment logical deletion
    -logBILL_PAYED=Customer invoice payed
    -logBILL_UNPAYED=Customer invoice set unpayed
    +logBILL_PAYED=Customer invoice paid
    +logBILL_UNPAYED=Customer invoice set unpaid
     logBILL_VALIDATE=Customer invoice validated
     logBILL_SENTBYMAIL=Customer invoice send by mail
     logBILL_DELETE=Customer invoice logically deleted
    @@ -32,9 +32,9 @@ logMODULE_SET=Module BlockedLog was enabled
     logDON_VALIDATE=Donation validated
     logDON_MODIFY=Donation modified
     logDON_DELETE=Donation logical deletion
    -logMEMBER_SUBSCRIPTION_CREATE=Member subcription created
    -logMEMBER_SUBSCRIPTION_MODIFY=Member subcription modified
    -logMEMBER_SUBSCRIPTION_DELETE=Member subcription logical deletion
    +logMEMBER_SUBSCRIPTION_CREATE=Member subscription created
    +logMEMBER_SUBSCRIPTION_MODIFY=Member subscription modified
    +logMEMBER_SUBSCRIPTION_DELETE=Member subscription logical deletion
     BlockedLogBillDownload=Customer invoice download
     BlockedLogBillPreview=Customer invoice preview
     BlockedlogInfoDialog=Log Details
    @@ -46,8 +46,8 @@ logDOC_DOWNLOAD=Download of a validated document in order to print or send
     DataOfArchivedEvent=Full datas of archived event
     ImpossibleToReloadObject=Original object (type %s, id %s) not linked (see 'Full datas' column to get unalterable saved data)
     BlockedLogAreRequiredByYourCountryLegislation=Unalterable Logs module may be required by the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they can not be validated by a tax audit.
    -BlockedLogActivatedBecauseRequiredByYourCountryLegislation=Unalterable Logs module was activated because of the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they can not be validated by a tax audit.
    +BlockedLogActivatedBecauseRequiredByYourCountryLegislation=Unalterable Logs module was activated because of the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they cannot be validated by a tax audit.
     BlockedLogDisableNotAllowedForCountry=List of countries where usage of this module is mandatory (just to prevent to disable the module by error, if your country is in this list, disable of module is not possible without editing this list first. Note also that enabling/disabling this module will keep a track into the unalterable log).
    -OnlyNonValid=Non valid
    -TooManyRecordToScanRestrictFilters=Too many record to scan/analyze. Please restrict list with more restrictive filters.
    +OnlyNonValid=Non-valid
    +TooManyRecordToScanRestrictFilters=Too many records to scan/analyze. Please restrict list with more restrictive filters.
     RestrictYearToExport=Restrict month / year to export
    diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang
    index 152a6eccce5..8a519879ac3 100644
    --- a/htdocs/langs/en_US/boxes.lang
    +++ b/htdocs/langs/en_US/boxes.lang
    @@ -23,11 +23,11 @@ BoxTitleLastRssInfos=Latest %s news from %s
     BoxTitleLastProducts=Products/Services: latest %s modified
     BoxTitleProductsAlertStock=Products: stock alert
     BoxTitleLastSuppliers=Latest %s recorded suppliers
    -BoxTitleLastModifiedSuppliers=Suppliers: latest %s modified
    -BoxTitleLastModifiedCustomers=Customers: latest %s modified
    +BoxTitleLastModifiedSuppliers=Latest %s modified vendors
    +BoxTitleLastModifiedCustomers=Latest %s modified customers
     BoxTitleLastCustomersOrProspects=Latest %s customers or prospects
     BoxTitleLastCustomerBills=Latest %s modified customer invoices
    -BoxTitleLastSupplierBills=Latest %s modified supplier invoices
    +BoxTitleLastSupplierBills=Latest %s modified vendor invoices
     BoxTitleLastModifiedProspects=Latest %s modified prospects
     BoxTitleLastModifiedMembers=Latest %s modified members
     BoxTitleLastFicheInter=Latest %s modified interventions
    @@ -35,7 +35,7 @@ BoxTitleOldestUnpaidCustomerBills=Customer Invoices: oldest %s unpaid
     BoxTitleOldestUnpaidSupplierBills=Supplier Invoices: oldest %s unpaid
     BoxTitleCurrentAccounts=Open Accounts: balances
     BoxTitleLastModifiedContacts=Contacts/Addresses: latest %s modified
    -BoxMyLastBookmarks=Bookmarks: latest %s
    +BoxMyLastBookmarks=Bookmarks: latest %s modified
     BoxOldestExpiredServices=Oldest active expired services
     BoxLastExpiredServices=Latest %s oldest contacts with active expired services
     BoxTitleLastActionsToDo=Latest %s actions to do
    @@ -45,7 +45,7 @@ BoxTitleLastModifiedExpenses=Latest %s modified expense reports
     BoxGlobalActivity=Global activity (invoices, proposals, orders)
     BoxGoodCustomers=Good customers
     BoxTitleGoodCustomers=%s Good customers
    -FailedToRefreshDataInfoNotUpToDate=Failed to refresh RSS flux. Latest successfull refresh date: %s
    +FailedToRefreshDataInfoNotUpToDate=Failed to refresh RSS flux. Latest successful refresh date: %s
     LastRefreshDate=Latest refresh date
     NoRecordedBookmarks=No bookmarks defined.
     ClickToAdd=Click here to add.
    @@ -83,4 +83,4 @@ ForCustomersOrders=Customers orders
     ForProposals=Proposals
     LastXMonthRolling=The latest %s month rolling
     ChooseBoxToAdd=Add widget to your dashboard
    -BoxAdded=Widget was added in your dashboard
    \ No newline at end of file
    +BoxAdded=Widget was added in your dashboard
    diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang
    index 1f51f375e89..7fb03ea235c 100644
    --- a/htdocs/langs/en_US/cashdesk.lang
    +++ b/htdocs/langs/en_US/cashdesk.lang
    @@ -30,5 +30,14 @@ ShowCompany=Show company
     ShowStock=Show warehouse
     DeleteArticle=Click to remove this article
     FilterRefOrLabelOrBC=Search (Ref/Label)
    -UserNeedPermissionToEditStockToUsePos=You ask to decrease stock on invoice creation, so user that use POS need to have permission to edit stock.
    +UserNeedPermissionToEditStockToUsePos=You ask to decrease stock on invoice creation, so user that uses POS needs to have permission to edit stock.
     DolibarrReceiptPrinter=Dolibarr Receipt Printer
    +PointOfSale=Point of sales
    +CloseBill=Close Bill
    +Floors=Floors
    +Floor=Floor
    +AddTable=Add table
    +Place=Place
    +TakeboxNecesary='TakeBOX' application required
    +OrderPrinters=Order printers
    +SearchProduct=Search product
    diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang
    index ee019d0ebbb..cef3eaa2815 100644
    --- a/htdocs/langs/en_US/categories.lang
    +++ b/htdocs/langs/en_US/categories.lang
    @@ -55,7 +55,7 @@ MembersCategoryShort=Members tag/category
     SuppliersCategoriesShort=Suppliers tags/categories
     CustomersCategoriesShort=Customers tags/categories
     ProspectsCategoriesShort=Prospects tags/categories
    -CustomersProspectsCategoriesShort=Cust./Prosp. categories
    +CustomersProspectsCategoriesShort=Cust./Prosp. tags/categories
     ProductsCategoriesShort=Products tags/categories
     MembersCategoriesShort=Members tags/categories
     ContactCategoriesShort=Contacts tags/categories
    diff --git a/htdocs/langs/en_US/commercial.lang b/htdocs/langs/en_US/commercial.lang
    index 47c5d8646ba..0a0deb99a1f 100644
    --- a/htdocs/langs/en_US/commercial.lang
    +++ b/htdocs/langs/en_US/commercial.lang
    @@ -72,8 +72,8 @@ StatusProsp=Prospect status
     DraftPropals=Draft commercial proposals
     NoLimit=No limit
     ToOfferALinkForOnlineSignature=Link for online signature
    -WelcomeOnOnlineSignaturePage=Welcome to the page to accept commerical proposals from %s
    +WelcomeOnOnlineSignaturePage=Welcome to the page to accept commercial proposals from %s
     ThisScreenAllowsYouToSignDocFrom=This screen allow you to accept and sign, or refuse, a quote/commercial proposal
     ThisIsInformationOnDocumentToSign=This is information on document to accept or refuse
    -SignatureProposalRef=Signature of quote/commerical proposal %s
    -FeatureOnlineSignDisabled=Feature for online signing disabled or document generated before the feature was enabled  
    \ No newline at end of file
    +SignatureProposalRef=Signature of quote/commercial proposal %s
    +FeatureOnlineSignDisabled=Feature for online signing disabled or document generated before the feature was enabled
    diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang
    index 78762e542e2..e026ac5673d 100644
    --- a/htdocs/langs/en_US/companies.lang
    +++ b/htdocs/langs/en_US/companies.lang
    @@ -7,7 +7,7 @@ DeleteContact=Delete a contact/address
     ConfirmDeleteContact=Are you sure you want to delete this contact and all inherited information?
     MenuNewThirdParty=New Third Party
     MenuNewCustomer=New Customer
    -MenuNewProspect=Nnew Prospect
    +MenuNewProspect=New Prospect
     MenuNewSupplier=New Vendor
     MenuNewPrivateIndividual=New private individual
     NewCompany=New company (prospect, customer, vendor)
    @@ -40,7 +40,7 @@ ThirdPartyCustomersWithIdProf12=Customers with %s or %s
     ThirdPartySuppliers=Vendors
     ThirdPartyType=Type of company
     Individual=Private individual
    -ToCreateContactWithSameName=Will create automatically a contact/address with same information than third party under the third party. In most cases, even if your third party is a physical people, creating a third party alone is enough.
    +ToCreateContactWithSameName=Will create a Third Party and a linked Contact/Address with same information as the Third Party. In most cases, even if your Third Party is a physical person, creating a Third Party alone is enough.
     ParentCompany=Parent company
     Subsidiaries=Subsidiaries
     ReportByMonth=Report by month
    @@ -80,7 +80,7 @@ VATIsUsed=Sales tax used
     VATIsUsedWhenSelling=This defines if this third party includes a sale tax or not when it makes an invoice to its own customers
     VATIsNotUsed=Sales tax is not used
     CopyAddressFromSoc=Fill address with third party address
    -ThirdpartyNotCustomerNotSupplierSoNoRef=Third party neither customer nor vendor, no available refering objects
    +ThirdpartyNotCustomerNotSupplierSoNoRef=Third party neither customer nor vendor, no available referring objects
     ThirdpartyIsNeitherCustomerNorClientSoCannotHaveDiscounts=Third party neither customer nor supplier, discounts are not available
     PaymentBankAccount=Payment bank account
     OverAllProposals=Proposals
    @@ -258,7 +258,7 @@ ProfId1DZ=RC
     ProfId2DZ=Art.
     ProfId3DZ=NIF
     ProfId4DZ=NIS
    -VATIntra=Sales tax ID
    +VATIntra=Sales Tax/VAT ID
     VATIntraShort=Tax ID
     VATIntraSyntaxIsValid=Syntax is valid
     VATReturn=VAT return
    @@ -274,8 +274,8 @@ CompanyHasRelativeDiscount=This customer has a default discount of <b>%s%%</b>
     CompanyHasNoRelativeDiscount=This customer has no relative discount by default
     HasRelativeDiscountFromSupplier=You have a default discount of <b>%s%%</b> from this supplier
     HasNoRelativeDiscountFromSupplier=You have no default relative discount from this supplier
    -CompanyHasAbsoluteDiscount=This customer has discount available (credits notes or down payments) for <b>%s</b> %s
    -CompanyHasDownPaymentOrCommercialDiscount=This customer has discount available (commercial, down payments) for <b>%s</b> %s
    +CompanyHasAbsoluteDiscount=This customer has discounts available (credits notes or down payments) for <b>%s</b> %s
    +CompanyHasDownPaymentOrCommercialDiscount=This customer has discounts available (commercial, down payments) for <b>%s</b> %s
     CompanyHasCreditNote=This customer still has credit notes for <b>%s</b> %s
     HasNoAbsoluteDiscountFromSupplier=You have no discount credit available from this supplier
     HasAbsoluteDiscountFromSupplier=You have discounts available (credits notes or down payments) for <b>%s</b> %s from this supplier
    @@ -311,8 +311,8 @@ CustomerCodeDesc=Customer Code, unique for all customers
     SupplierCodeDesc=Vendor Code, unique for all vendors
     RequiredIfCustomer=Required if third party is a customer or prospect
     RequiredIfSupplier=Required if third party is a vendor
    -ValidityControledByModule=Validity controled by module
    -ThisIsModuleRules=This is rules for this module
    +ValidityControledByModule=Validity controlled by module
    +ThisIsModuleRules=Rules for this module
     ProspectToContact=Prospect to contact
     CompanyDeleted=Company "%s" deleted from database.
     ListOfContacts=List of contacts/addresses
    @@ -338,15 +338,15 @@ MyContacts=My contacts
     Capital=Capital
     CapitalOf=Capital of %s
     EditCompany=Edit company
    -ThisUserIsNot=This user is not a prospect, customer nor vendor
    +ThisUserIsNot=This user is not a prospect, customer or vendor
     VATIntraCheck=Check
    -VATIntraCheckDesc=The link <b>%s</b> allows to ask the european VAT checker service. An external internet access from server is required for this service to work.
    +VATIntraCheckDesc=The link <b>%s</b> uses the European VAT checker service (VIES). An external internet access from server is required for this service to work.
     VATIntraCheckURL=http://ec.europa.eu/taxation_customs/vies/vieshome.do
    -VATIntraCheckableOnEUSite=Check Intracomunnautary VAT on European commision site
    -VATIntraManualCheck=You can also check manually from european web site <a href="%s" target="_blank">%s</a>
    +VATIntraCheckableOnEUSite=Check intra-Community VAT on the European Commission website
    +VATIntraManualCheck=You can also check manually on the European Commission website <a href="%s" target="_blank">%s</a>
     ErrorVATCheckMS_UNAVAILABLE=Check not possible. Check service is not provided by the member state (%s).
    -NorProspectNorCustomer=Nor prospect, nor customer
    -JuridicalStatus=Legal form
    +NorProspectNorCustomer=Not prospect, or customer
    +JuridicalStatus=Legal Entity Type
     Staff=Staff
     ProspectLevelShort=Potential
     ProspectLevel=Prospect potential
    @@ -402,9 +402,9 @@ DeleteFile=Delete file
     ConfirmDeleteFile=Are you sure you want to delete this file?
     AllocateCommercial=Assigned to sales representative
     Organization=Organization
    -FiscalYearInformation=Information on the fiscal year
    +FiscalYearInformation=Fiscal Year
     FiscalMonthStart=Starting month of the fiscal year
    -YouMustAssignUserMailFirst=You must create email for this user first to be able to add emails notifications for him.
    +YouMustAssignUserMailFirst=You must create an email for this user prior to being able to add an email notification.
     YouMustCreateContactFirst=To be able to add email notifications, you must first define contacts with valid emails for the third party
     ListSuppliersShort=List of Vendors
     ListProspectsShort=List of Prospects
    @@ -420,12 +420,12 @@ CurrentOutstandingBill=Current outstanding bill
     OutstandingBill=Max. for outstanding bill
     OutstandingBillReached=Max. for outstanding bill reached
     OrderMinAmount=Minimum amount for order
    -MonkeyNumRefModelDesc=Return numero with format %syymm-nnnn for customer code and %syymm-nnnn for vendor code where yy is year, mm is month and nnnn is a sequence with no break and no return to 0.
    +MonkeyNumRefModelDesc=Return a number with the format %syymm-nnnn for the customer code and %syymm-nnnn for the vendor code where yy is year, mm is month and nnnn is a sequence with no break and no return to 0.
     LeopardNumRefModelDesc=The code is free. This code can be modified at any time.
     ManagingDirectors=Manager(s) name (CEO, director, president...)
     MergeOriginThirdparty=Duplicate third party (third party you want to delete)
     MergeThirdparties=Merge third parties
    -ConfirmMergeThirdparties=Are you sure you want to merge this third party into the current one? All linked objects (invoices, orders, ...) will be moved to current third party, then the thirdparty will be deleted.
    +ConfirmMergeThirdparties=Are you sure you want to merge this third party into the current one? All linked objects (invoices, orders, ...) will be moved to current third party, then the third party will be deleted.
     ThirdpartiesMergeSuccess=Third parties have been merged
     SaleRepresentativeLogin=Login of sales representative
     SaleRepresentativeFirstname=First name of sales representative
    diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang
    index ba36f59ba4a..6ad5e357b35 100644
    --- a/htdocs/langs/en_US/compta.lang
    +++ b/htdocs/langs/en_US/compta.lang
    @@ -6,7 +6,7 @@ OptionMode=Option for accountancy
     OptionModeTrue=Option Incomes-Expenses
     OptionModeVirtual=Option Claims-Debts
     OptionModeTrueDesc=In this context, the turnover is calculated over payments (date of payments). The validity of the figures is assured only if the book-keeping is scrutinized through the input/output on the accounts via invoices.
    -OptionModeVirtualDesc=In this context, the turnover is calculated over invoices (date of validation). When these invoices are due, whether they have been paid or not, they are listed in the turnover output. 
    +OptionModeVirtualDesc=In this context, the turnover is calculated over invoices (date of validation). When these invoices are due, whether they have been paid or not, they are listed in the turnover output.
     FeatureIsSupportedInInOutModeOnly=Feature only available in CREDITS-DEBTS accountancy mode (See Accountancy module configuration)
     VATReportBuildWithOptionDefinedInModule=Amounts shown here are calculated using rules defined by Tax module setup.
     LTReportBuildWithOptionDefinedInModule=Amounts shown here are calculated using rules defined by Company setup.
    @@ -29,7 +29,7 @@ BalanceBefore=Balance (before)
     Balance=Balance
     Debit=Debit
     Credit=Credit
    -Piece=Accounting Doc. 
    +Piece=Accounting Doc.
     AmountHTVATRealReceived=Net collected
     AmountHTVATRealPaid=Net paid
     VATToPay=Tax sales
    @@ -154,8 +154,8 @@ AnnualSummaryInputOutputMode=Balance of income and expenses, annual summary
     AnnualByCompanies=Balance of income and expenses, by predefined groups of account
     AnnualByCompaniesDueDebtMode=Balance of income and expenses, detail by predefined groups, mode <b>%sClaims-Debts%s</b> said <b>Commitment accounting</b>.
     AnnualByCompaniesInputOutputMode=Balance of income and expenses, detail by predefined groups, mode <b>%sIncomes-Expenses%s</b> said <b>cash accounting</b>.
    -SeeReportInInputOutputMode=See %sanalysis of payments%s for a calculation on actual payments made, if they are not yet accounted in Ledger.
    -SeeReportInDueDebtMode=See %sanalysis of invoices%s for a calculation based on known recorded invoices even, if they are not yet accounted in Ledger.
    +SeeReportInInputOutputMode=See %sanalysis of payments%s for a calculation on actual payments made even if they are not yet accounted in Ledger.
    +SeeReportInDueDebtMode=See %sanalysis of invoices%s for a calculation based on known recorded invoices even if they are not yet accounted in Ledger.
     SeeReportInBookkeepingMode=See <b>%sBookeeping report%s</b> for a calculation on <b>Bookkeeping Ledger table</b>
     RulesAmountWithTaxIncluded=- Amounts shown are with all taxes included
     RulesResultDue=- It includes outstanding invoices, expenses, VAT, donations whether they are paid or not. Is also includes paid salaries.<br>- It is based on the validation date of invoices and VAT and on the due date for expenses. For salaries defined with Salary module, the value date of payment is used.
    @@ -167,7 +167,7 @@ RulesAmountOnInOutBookkeepingRecord=It includes record in your Ledger with accou
     RulesResultBookkeepingPredefined=It includes record in your Ledger with accounting accounts that has the group "EXPENSE" or "INCOME"
     RulesResultBookkeepingPersonalized=It show record in your Ledger with accounting accounts <b>grouped by personalized groups</b>
     SeePageForSetup=See menu <a href="%s">%s</a> for setup
    -DepositsAreNotIncluded=- Down payment invoices are nor included
    +DepositsAreNotIncluded=- Down payment invoices are not included
     DepositsAreIncluded=- Down payment invoices are included
     LT1ReportByCustomers=Report tax 2 by third party
     LT2ReportByCustomers=Report tax 3 by third party
    @@ -191,7 +191,7 @@ RulesVATInProducts=- For material assets, the report includes the VAT received o
     RulesVATDueServices=- For services, the report includes VAT invoices due, paid or not, based on the invoice date.
     RulesVATDueProducts=- For material assets, the report includes the VAT invoices, based on the invoice date.
     OptionVatInfoModuleComptabilite=Note: For material assets, it should use the date of delivery to be more fair.
    -ThisIsAnEstimatedValue=This is a preview, based on business events and not from the final ledger table, so final results may differ from this preview values 
    +ThisIsAnEstimatedValue=This is a preview, based on business events and not from the final ledger table, so final results may differ from this preview values
     PercentOfInvoice=%%/invoice
     NotUsedForGoods=Not used on goods
     ProposalStats=Statistics on proposals
    @@ -203,7 +203,7 @@ ToDispatch=To dispatch
     ThirdPartyMustBeEditAsCustomer=Third party must be defined as a customer
     SellsJournal=Sales Journal
     PurchasesJournal=Purchases Journal
    -DescSellsJournal=Sales Journal 
    +DescSellsJournal=Sales Journal
     DescPurchasesJournal=Purchases Journal
     InvoiceRef=Invoice ref.
     CodeNotDef=Not defined
    @@ -229,9 +229,9 @@ ACCOUNTING_VAT_SOLD_ACCOUNT=Accounting account by default for VAT on sales (used
     ACCOUNTING_VAT_BUY_ACCOUNT=Accounting account by default for VAT on purchases (used if not defined on VAT dictionary setup)
     ACCOUNTING_VAT_PAY_ACCOUNT=Accounting account by default for paying VAT
     ACCOUNTING_ACCOUNT_CUSTOMER=Accounting account used for customer third parties
    -ACCOUNTING_ACCOUNT_CUSTOMER_Desc=The dedicated accounting account defined on third party card will be used for Subledger accouting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated customer accouting account on third party is not defined.
    +ACCOUNTING_ACCOUNT_CUSTOMER_Desc=The dedicated accounting account defined on third party card will be used for Subledger accounting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated customer accounting account on third party is not defined.
     ACCOUNTING_ACCOUNT_SUPPLIER=Accounting account used for vendor third parties
    -ACCOUNTING_ACCOUNT_SUPPLIER_Desc=The dedicated accounting account defined on third party card will be used for Subledger accouting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated supplier accouting account on third party is not defined.
    +ACCOUNTING_ACCOUNT_SUPPLIER_Desc=The dedicated accounting account defined on third party card will be used for Subledger accounting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated supplier accounting account on third party is not defined.
     CloneTax=Clone a social/fiscal tax
     ConfirmCloneTax=Confirm the clone of a social/fiscal tax
     CloneTaxForNextMonth=Clone it for next month
    @@ -248,7 +248,7 @@ ErrorBankAccountNotFound=Error: Bank account not found
     FiscalPeriod=Accounting period
     ListSocialContributionAssociatedProject=List of social contributions associated with the project
     DeleteFromCat=Remove from accounting group
    -AccountingAffectation=Accounting assignement
    +AccountingAffectation=Accounting assignment
     LastDayTaxIsRelatedTo=Last day of period the tax is related to
     VATDue=Sale tax claimed
     ClaimedForThisPeriod=Claimed for the period
    @@ -256,4 +256,4 @@ PaidDuringThisPeriod=Paid during this period
     ByVatRate=By sale tax rate
     TurnoverbyVatrate=Turnover invoiced by sale tax rate
     TurnoverCollectedbyVatrate=Turnover collected by sale tax rate
    -PurchasebyVatrate=Purchase by sale tax rate
    \ No newline at end of file
    +PurchasebyVatrate=Purchase by sale tax rate
    diff --git a/htdocs/langs/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang
    index d2a03f64935..b4e8d7c96d9 100644
    --- a/htdocs/langs/en_US/contracts.lang
    +++ b/htdocs/langs/en_US/contracts.lang
    @@ -67,7 +67,7 @@ CloseService=Close service
     BoardRunningServices=Expired running services
     ServiceStatus=Status of service
     DraftContracts=Drafts contracts
    -CloseRefusedBecauseOneServiceActive=Contract can't be closed as ther is at least one open service on it
    +CloseRefusedBecauseOneServiceActive=Contract can't be closed as there is at least one open service on it
     ActivateAllContracts=Activate all contract lines
     CloseAllContracts=Close all contract lines
     DeleteContractLine=Delete a contract line
    diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang
    index 704b852e138..63d56feca61 100644
    --- a/htdocs/langs/en_US/cron.lang
    +++ b/htdocs/langs/en_US/cron.lang
    @@ -11,11 +11,11 @@ URLToLaunchCronJobs=URL to check and launch qualified cron jobs
     OrToLaunchASpecificJob=Or to check and launch a specific job
     KeyForCronAccess=Security key for URL to launch cron jobs
     FileToLaunchCronJobs=Command line to check and launch qualified cron jobs
    -CronExplainHowToRunUnix=On Unix environment you should use the following crontab entry to run the command line each 5 minutes 
    -CronExplainHowToRunWin=On Microsoft(tm) Windows environement you can use Scheduled task tools to run the command line each 5 minutes
    +CronExplainHowToRunUnix=On Unix environment you should use the following crontab entry to run the command line each 5 minutes
    +CronExplainHowToRunWin=On Microsoft(tm) Windows environment you can use Scheduled Task tools to run the command line each 5 minutes
     CronMethodDoesNotExists=Class %s does not contains any method %s
     CronJobDefDesc=Cron job profiles are defined into the module descriptor file. When module is activated, they are loaded and available so you can administer the jobs from the admin tools menu %s.
    -CronJobProfiles=List of predefined cron job profiles 
    +CronJobProfiles=List of predefined cron job profiles
     # Menu
     EnabledAndDisabled=Enabled and disabled
     # Page list
    @@ -61,11 +61,11 @@ CronStatusInactiveBtn=Disable
     CronTaskInactive=This job is disabled
     CronId=Id
     CronClassFile=Filename with class
    -CronModuleHelp=Name of Dolibarr module directory (also work with external Dolibarr module). <BR> For exemple to call the fetch method of Dolibarr Product object /htdocs/<u>product</u>/class/product.class.php, the value for module is<br><i>product</i>
    -CronClassFileHelp=The relative path and file name to load (path is relative to web server root directory). <BR> For exemple to call the fetch method of Dolibarr Product object htdocs/product/class/<u>product.class.php</u>, the value for class file name is<br><i>product/class/product.class.php</i>
    -CronObjectHelp=The object name to load. <BR> For exemple to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for class file name is<br><i>Product</i>
    -CronMethodHelp=The object method to launch. <BR> For exemple to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for method is<br><i>fetch</i>
    -CronArgsHelp=The method arguments. <BR> For exemple to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for paramters can be<br><i>0, ProductRef</i>
    +CronModuleHelp=Name of Dolibarr module directory (also work with external Dolibarr module). <BR> For example to call the fetch method of Dolibarr Product object /htdocs/<u>product</u>/class/product.class.php, the value for module is<br><i>product</i>
    +CronClassFileHelp=The relative path and file name to load (path is relative to web server root directory). <BR> For example to call the fetch method of Dolibarr Product object htdocs/product/class/<u>product.class.php</u>, the value for class file name is<br><i>product/class/product.class.php</i>
    +CronObjectHelp=The object name to load. <BR> For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for class file name is<br><i>Product</i>
    +CronMethodHelp=The object method to launch. <BR> For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for method is<br><i>fetch</i>
    +CronArgsHelp=The method arguments. <BR> For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for paramters can be<br><i>0, ProductRef</i>
     CronCommandHelp=The system command line to execute.
     CronCreateJob=Create new Scheduled Job
     CronFrom=From
    diff --git a/htdocs/langs/en_US/deliveries.lang b/htdocs/langs/en_US/deliveries.lang
    index 7e39f48ea55..0d432c3f426 100644
    --- a/htdocs/langs/en_US/deliveries.lang
    +++ b/htdocs/langs/en_US/deliveries.lang
    @@ -17,14 +17,15 @@ DeliveryNotValidated=Delivery not validated
     StatusDeliveryCanceled=Canceled
     StatusDeliveryDraft=Draft
     StatusDeliveryValidated=Received
    -# merou PDF model						   
    -NameAndSignature=Name and Signature : 
    +# merou PDF model
    +NameAndSignature=Name and Signature :
     ToAndDate=To___________________________________ on ____/_____/__________
     GoodStatusDeclaration=Have received the goods above in good condition,
    -Deliverer=Deliverer : 
    +Deliverer=Deliverer :
     Sender=Sender
     Recipient=Recipient
     ErrorStockIsNotEnough=There's not enough stock
     Shippable=Shippable
     NonShippable=Not Shippable
     ShowReceiving=Show delivery receipt
    +NonExistentOrder=Non-existent order
    diff --git a/htdocs/langs/en_US/dict.lang b/htdocs/langs/en_US/dict.lang
    index bb79cd59d7d..59e7cc058f4 100644
    --- a/htdocs/langs/en_US/dict.lang
    +++ b/htdocs/langs/en_US/dict.lang
    @@ -116,7 +116,7 @@ CountryHM=Heard Island and McDonald
     CountryVA=Holy See (Vatican City State)
     CountryHN=Honduras
     CountryHK=Hong Kong
    -CountryIS=Icelande
    +CountryIS=Iceland
     CountryIN=India
     CountryID=Indonesia
     CountryIR=Iran
    @@ -131,7 +131,7 @@ CountryKI=Kiribati
     CountryKP=North Korea
     CountryKR=South Korea
     CountryKW=Kuwait
    -CountryKG=Kyrghyztan
    +CountryKG=Kyrgyzstan
     CountryLA=Lao
     CountryLV=Latvia
     CountryLB=Lebanon
    @@ -160,7 +160,7 @@ CountryMD=Moldova
     CountryMN=Mongolia
     CountryMS=Monserrat
     CountryMZ=Mozambique
    -CountryMM=Birmania (Myanmar)
    +CountryMM=Myanmar (Burma)
     CountryNA=Namibia
     CountryNR=Nauru
     CountryNP=Nepal
    @@ -223,7 +223,7 @@ CountryTO=Tonga
     CountryTT=Trinidad and Tobago
     CountryTR=Turkey
     CountryTM=Turkmenistan
    -CountryTC=Turks and Cailos Islands
    +CountryTC=Turks and Caicos Islands
     CountryTV=Tuvalu
     CountryUG=Uganda
     CountryUA=Ukraine
    @@ -277,7 +277,7 @@ CurrencySingMGA=Ariary
     CurrencyMUR=Mauritius rupees
     CurrencySingMUR=Mauritius rupee
     CurrencyNOK=Norwegian krones
    -CurrencySingNOK=Norwegian krone
    +CurrencySingNOK=Norwegian kronas
     CurrencyTND=Tunisian dinars
     CurrencySingTND=Tunisian dinar
     CurrencyUSD=US Dollars
    @@ -354,4 +354,4 @@ ExpAuto13PCV=13 CV and more
     ExpCyclo=Capacity lower to 50cm3
     ExpMoto12CV=Motorbike 1 or 2 CV
     ExpMoto345CV=Motorbike 3, 4 or 5 CV
    -ExpMoto5PCV=Motorbike 5 CV and more
    \ No newline at end of file
    +ExpMoto5PCV=Motorbike 5 CV and more
    diff --git a/htdocs/langs/en_US/donations.lang b/htdocs/langs/en_US/donations.lang
    index 748057cc9cc..5edc8d62033 100644
    --- a/htdocs/langs/en_US/donations.lang
    +++ b/htdocs/langs/en_US/donations.lang
    @@ -27,7 +27,7 @@ IConfirmDonationReception=The recipient declare reception, as a donation, of the
     MinimumAmount=Minimum amount is  %s
     FreeTextOnDonations=Free text to show in footer
     FrenchOptions=Options for France
    -DONATION_ART200=Show article 200 from CGI if you are concerned 
    +DONATION_ART200=Show article 200 from CGI if you are concerned
     DONATION_ART238=Show article 238 from CGI if you are concerned
     DONATION_ART885=Show article 885 from CGI if you are concerned
     DonationPayment=Donation payment
    diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
    index 45c1426556e..29dbf4b4287 100644
    --- a/htdocs/langs/en_US/errors.lang
    +++ b/htdocs/langs/en_US/errors.lang
    @@ -42,7 +42,7 @@ ErrorBadDateFormat=Value '%s' has wrong date format
     ErrorWrongDate=Date is not correct!
     ErrorFailedToWriteInDir=Failed to write in directory %s
     ErrorFoundBadEmailInFile=Found incorrect email syntax for %s lines in file (example line %s with email=%s)
    -ErrorUserCannotBeDelete=User cannot be deleted. May be it is associated to Dolibarr entities.
    +ErrorUserCannotBeDelete=User cannot be deleted. Maybe it is associated to Dolibarr entities.
     ErrorFieldsRequired=Some required fields were not filled.
     ErrorSubjectIsRequired=The email topic is required
     ErrorFailedToCreateDir=Failed to create a directory. Check that Web server user has permissions to write into Dolibarr documents directory. If parameter <b>safe_mode</b> is enabled on this PHP, check that Dolibarr php files owns to web server user (or group).
    @@ -65,21 +65,22 @@ ErrorNoValueForSelectType=Please fill value for select list
     ErrorNoValueForCheckBoxType=Please fill value for checkbox list
     ErrorNoValueForRadioType=Please fill value for radio list
     ErrorBadFormatValueList=The list value cannot have more than one comma: <u>%s</u>, but need at least one: key,value
    -ErrorFieldCanNotContainSpecialCharacters=Field <b>%s</b> must not contains special characters.
    -ErrorFieldCanNotContainSpecialNorUpperCharacters=Field <b>%s</b> must not contain special characters, nor upper case characters and cannot contain only numbers.
    +ErrorFieldCanNotContainSpecialCharacters=The field <b>%s</b> must not contains special characters.
    +ErrorFieldCanNotContainSpecialNorUpperCharacters=The field <b>%s</b> must not contain special characters, nor upper case characters and cannot contain only numbers.
    +ErrorFieldMustHaveXChar=The field <b>%s</b> must have at least %s characters.
     ErrorNoAccountancyModuleLoaded=No accountancy module activated
     ErrorExportDuplicateProfil=This profile name already exists for this export set.
     ErrorLDAPSetupNotComplete=Dolibarr-LDAP matching is not complete.
     ErrorLDAPMakeManualTest=A .ldif file has been generated in directory %s. Try to load it manually from command line to have more information on errors.
    -ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "statut not started" if field "done by" is also filled.
    +ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "status not started" if field "done by" is also filled.
     ErrorRefAlreadyExists=Ref used for creation already exists.
    -ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD) 
    -ErrorRecordHasChildren=Failed to delete record since it has some childs.
    +ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD)
    +ErrorRecordHasChildren=Failed to delete record since it has some child records.
     ErrorRecordHasAtLeastOneChildOfType=Object has at least one child of type %s
    -ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into other object.
    +ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into another object.
     ErrorModuleRequireJavascript=Javascript must not be disabled to have this feature working. To enable/disable Javascript, go to menu Home->Setup->Display.
     ErrorPasswordsMustMatch=Both typed passwords must match each other
    -ErrorContactEMail=A technical error occured. Please, contact administrator to following email <b>%s</b> en provide the error code <b>%s</b> in your message, or even better by adding a screen copy of this page.
    +ErrorContactEMail=A technical error occured. Please, contact administrator to following email <b>%s</b> and provide the error code <b>%s</b> in your message, or add a screen copy of this page.
     ErrorWrongValueForField=Wrong value for field number <b>%s</b> (value '<b>%s</b>' does not match regex rule <b>%s</b>)
     ErrorFieldValueNotIn=Wrong value for field number <b>%s</b> (value '<b>%s</b>' is not a value available into field <b>%s</b> of table <b>%s</b>)
     ErrorFieldRefNotIn=Wrong value for field number <b>%s</b> (value '<b>%s</b>' is not a <b>%s</b> existing ref)
    @@ -95,7 +96,7 @@ ErrorBadMaskBadRazMonth=Error, bad reset value
     ErrorMaxNumberReachForThisMask=Max number reach for this mask
     ErrorCounterMustHaveMoreThan3Digits=Counter must have more than 3 digits
     ErrorSelectAtLeastOne=Error. Select at least one entry.
    -ErrorDeleteNotPossibleLineIsConsolidated=Delete not possible because record is linked to a bank transation that is conciliated
    +ErrorDeleteNotPossibleLineIsConsolidated=Delete not possible because record is linked to a bank transaction that is conciliated
     ErrorProdIdAlreadyExist=%s is assigned to another third
     ErrorFailedToSendPassword=Failed to send password
     ErrorFailedToLoadRSSFile=Fails to get RSS feed. Try to add constant MAIN_SIMPLEXMLLOAD_DEBUG if error messages does not provide enough information.
    @@ -115,7 +116,7 @@ ErrorLoginDoesNotExists=User with login <b>%s</b> could not be found.
     ErrorLoginHasNoEmail=This user has no email address. Process aborted.
     ErrorBadValueForCode=Bad value for security code. Try again with new value...
     ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative
    -ErrorFieldCantBeNegativeOnInvoice=Field <strong>%s</strong> can't be negative on such type of invoice. If you want to add a discount line, just create the discount first with link %s on screen and apply it to invoice. You can also ask your admin to set option FACTURE_ENABLE_NEGATIVE_LINES to 1 to restore old behaviour. 
    +ErrorFieldCantBeNegativeOnInvoice=Field <strong>%s</strong> can't be negative on such type of invoice. If you want to add a discount line, just create the discount first with link %s on screen and apply it to invoice. You can also ask your admin to set option FACTURE_ENABLE_NEGATIVE_LINES to 1 to restore old behaviour.
     ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative
     ErrorWebServerUserHasNotPermission=User account <b>%s</b> used to execute web server has no permission for that
     ErrorNoActivatedBarcode=No barcode type activated
    @@ -139,7 +140,7 @@ ErrorBadFormat=Bad format!
     ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst=Error, this member is not yet linked to any third party. Link member to an existing third party or create a new third party before creating subscription with invoice.
     ErrorThereIsSomeDeliveries=Error, there is some deliveries linked to this shipment. Deletion refused.
     ErrorCantDeletePaymentReconciliated=Can't delete a payment that had generated a bank entry that was reconciled
    -ErrorCantDeletePaymentSharedWithPayedInvoice=Can't delete a payment shared by at least one invoice with status Payed
    +ErrorCantDeletePaymentSharedWithPayedInvoice=Can't delete a payment shared by at least one invoice with status Paid
     ErrorPriceExpression1=Cannot assign to constant '%s'
     ErrorPriceExpression2=Cannot redefine built-in function '%s'
     ErrorPriceExpression3=Undefined variable '%s' in function definition
    @@ -148,7 +149,7 @@ ErrorPriceExpression5=Unexpected '%s'
     ErrorPriceExpression6=Wrong number of arguments (%s given, %s expected)
     ErrorPriceExpression8=Unexpected operator '%s'
     ErrorPriceExpression9=An unexpected error occured
    -ErrorPriceExpression10=Iperator '%s' lacks operand
    +ErrorPriceExpression10=Operator '%s' lacks operand
     ErrorPriceExpression11=Expecting '%s'
     ErrorPriceExpression14=Division by zero
     ErrorPriceExpression17=Undefined variable '%s'
    @@ -172,10 +173,10 @@ ErrorGlobalVariableUpdater4=SOAP client failed with error '%s'
     ErrorGlobalVariableUpdater5=No global variable selected
     ErrorFieldMustBeANumeric=Field <b>%s</b> must be a numeric value
     ErrorMandatoryParametersNotProvided=Mandatory parameter(s) not provided
    -ErrorOppStatusRequiredIfAmount=You set an estimated amount for this opportunity/lead. So you must also enter its status
    +ErrorOppStatusRequiredIfAmount=You set an estimated amount for this lead/lead. So you must also enter its status
     ErrorFailedToLoadModuleDescriptorForXXX=Failed to load module descriptor class for %s
     ErrorBadDefinitionOfMenuArrayInModuleDescriptor=Bad Definition Of Menu Array In Module Descriptor (bad value for key fk_menu)
    -ErrorSavingChanges=An error has ocurred when saving the changes
    +ErrorSavingChanges=An error has occurred when saving the changes
     ErrorWarehouseRequiredIntoShipmentLine=Warehouse is required on the line to ship
     ErrorFileMustHaveFormat=File must have format %s
     ErrorSupplierCountryIsNotDefined=Country for this vendor is not defined. Correct this first.
    @@ -197,38 +198,39 @@ ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong
     ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (<strong>%s</strong>) does not match expected name syntax: <strong>%s</strong>
     ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s.
     ErrorNoWarehouseDefined=Error, no warehouses defined.
    -ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' for payment is defined, but value for 'ref' is not valid. 
    +ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' for payment is defined, but value for 'ref' is not valid.
     ErrorTooManyErrorsProcessStopped=Too many errors. Process was stopped.
     ErrorMassValidationNotAllowedWhenStockIncreaseOnAction=Mass validation is not possible when option to increase/decrease stock is set on this action (you must validate one by one so you can define the warehouse to increase/decrease)
     ErrorObjectMustHaveStatusDraftToBeValidated=Object %s must have status 'Draft' to be validated.
     ErrorObjectMustHaveLinesToBeValidated=Object %s must have lines to be validated.
    -ErrorOnlyInvoiceValidatedCanBeSentInMassAction=Only validated invoices can be sent using the "Send by email" mass action. 
    +ErrorOnlyInvoiceValidatedCanBeSentInMassAction=Only validated invoices can be sent using the "Send by email" mass action.
     ErrorChooseBetweenFreeEntryOrPredefinedProduct=You must choose if article is a predefined product or not
     ErrorDiscountLargerThanRemainToPaySplitItBefore=The discount you try to apply is larger than remain to pay. Split the discount in 2 smaller discounts before.
     ErrorFileNotFoundWithSharedLink=File was not found. May be the share key was modified or file was removed recently.
     ErrorProductBarCodeAlreadyExists=The product barcode %s already exists on another product reference.
     ErrorNoteAlsoThatSubProductCantBeFollowedByLot=Note also that using virtual product to have auto increase/decrease of subproducts is not possible when at least one subproduct (or subproduct of subproducts) needs a serial/lot number.
     ErrorDescRequiredForFreeProductLines=Description is mandatory for lines with free product
    +ErrorAPageWithThisNameOrAliasAlreadyExists=The page/container <strong>%s</strong> has the same name or alternative alias that the one your try to use
     
     # Warnings
    -WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.  
    +WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.
     WarningMandatorySetupNotComplete=Mandatory setup parameters are not yet defined
     WarningSafeModeOnCheckExecDir=Warning, PHP option <b>safe_mode</b> is on so command must be stored inside a directory declared by php parameter <b>safe_mode_exec_dir</b>.
     WarningBookmarkAlreadyExists=A bookmark with this title or this target (URL) already exists.
     WarningPassIsEmpty=Warning, database password is empty. This is a security hole. You should add a password to your database and change your conf.php file to reflect this.
     WarningConfFileMustBeReadOnly=Warning, your config file (<b>htdocs/conf/conf.php</b>) can be overwritten by the web server. This is a serious security hole. Modify permissions on file to be in read only mode for operating system user used by Web server. If you use Windows and FAT format for your disk, you must know that this file system does not allow to add permissions on file, so can't be completely safe.
     WarningsOnXLines=Warnings on <b>%s</b> source record(s)
    -WarningNoDocumentModelActivated=No model, for document generation, has been activated. A model will be choosed by default until you check your module setup.
    -WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable install/migrate tools by adding a file <b>install.lock</b> into directory <b>%s</b>. Missing this file is a security hole. 
    -WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other setup).
    +WarningNoDocumentModelActivated=No model, for document generation, has been activated. A model will be chosen by default until you check your module setup.
    +WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable install/migrate tools by adding a file <b>install.lock</b> into directory <b>%s</b>. Missing this file is a security hole.
    +WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other Setup).
     WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution.
     WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box.
     WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card).
     WarningFeatureDisabledWithDisplayOptimizedForBlindNoJs=Feature disabled when display setup is optimized for blind person or text browsers.
    -WarningPaymentDateLowerThanInvoiceDate=Payment date (%s) is earlier than invoice date (%s) for invoice %s. 
    -WarningTooManyDataPleaseUseMoreFilters=Too many data (more than %s lines). Please use more filters or set the constant %s to a higher limit. 
    +WarningPaymentDateLowerThanInvoiceDate=Payment date (%s) is earlier than invoice date (%s) for invoice %s.
    +WarningTooManyDataPleaseUseMoreFilters=Too many data (more than %s lines). Please use more filters or set the constant %s to a higher limit.
     WarningSomeLinesWithNullHourlyRate=Some times were recorded by some users while their hourly rate was not defined. A value of 0 %s per hour was used but this may result in wrong valuation of time spent.
     WarningYourLoginWasModifiedPleaseLogin=Your login was modified. For security purpose you will have to login with your new login before next action.
     WarningAnEntryAlreadyExistForTransKey=An entry already exists for the translation key for this language
    -WarningNumberOfRecipientIsRestrictedInMassAction=Warning, number of different recipient is limited to <b>%s</b> when using the bulk actions on lists
    -WarningDateOfLineMustBeInExpenseReportRange=Warning, the date of line is not in the range of the expense report
    \ No newline at end of file
    +WarningNumberOfRecipientIsRestrictedInMassAction=Warning, number of different recipient is limited to <b>%s</b> when using the mass actions on lists
    +WarningDateOfLineMustBeInExpenseReportRange=Warning, the date of line is not in the range of the expense report
    diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang
    index 093b4f4b46c..179556ddb19 100644
    --- a/htdocs/langs/en_US/exports.lang
    +++ b/htdocs/langs/en_US/exports.lang
    @@ -7,17 +7,17 @@ ExportableDatas=Exportable dataset
     ImportableDatas=Importable dataset
     SelectExportDataSet=Choose dataset you want to export...
     SelectImportDataSet=Choose dataset you want to import...
    -SelectExportFields=Choose fields you want to export, or select a predefined export profile
    -SelectImportFields=Choose source file fields you want to import and their target field in database by moving them up and down with anchor %s, or select a predefined import profile:
    +SelectExportFields=Choose the fields you want to export, or select a predefined export profile
    +SelectImportFields=Choose the source file fields you want to import and their target field in database by moving them up and down with anchor %s, or select a predefined import profile:
     NotImportedFields=Fields of source file not imported
     SaveExportModel=Save your selections as an export profile/template (for reuse).
     SaveImportModel=Save this import profile (for reuse) ...
     ExportModelName=Export profile name
    -ExportModelSaved=Export profile saved under name <b>%s</b>.
    +ExportModelSaved=Export profile saved as <b>%s</b>.
     ExportableFields=Exportable fields
     ExportedFields=Exported fields
     ImportModelName=Import profile name
    -ImportModelSaved=Import profile saved under name <b>%s</b>.
    +ImportModelSaved=Import profile saved as <b>%s</b>.
     DatasetToExport=Dataset to export
     DatasetToImport=Import file into dataset
     ChooseFieldsOrdersAndTitle=Choose fields order...
    @@ -83,25 +83,25 @@ ErrorMissingMandatoryValue=Mandatory data is empty in the source file for field
     TooMuchErrors=There are still <b>%s</b> other source lines with errors but output has been limited.
     TooMuchWarnings=There are still <b>%s</b> other source lines with warnings but output has been limited.
     EmptyLine=Empty line (will be discarded)
    -CorrectErrorBeforeRunningImport=You must first correct all errors before running definitive import.
    -FileWasImported=File was imported with number <b>%s</b>. 
    -YouCanUseImportIdToFindRecord=You can find all imported record in your database by filtering on field <b>import_key='%s'</b>.
    +CorrectErrorBeforeRunningImport=You <b>must</b> correct all errors <b>before</b> running the definitive import.
    +FileWasImported=File was imported with number <b>%s</b>.
    +YouCanUseImportIdToFindRecord=You can find all the imported records in your database by filtering on field <b>import_key='%s'</b>.
     NbOfLinesOK=Number of lines with no errors and no warnings: <b>%s</b>.
     NbOfLinesImported=Number of lines successfully imported: <b>%s</b>.
     DataComeFromNoWhere=Value to insert comes from nowhere in source file.
     DataComeFromFileFieldNb=Value to insert comes from field number <b>%s</b> in source file.
    -DataComeFromIdFoundFromRef=Value that comes from field number <b>%s</b> of source file will be used to find id of parent object to use (So the objet <b>%s</b> that has the ref. from source file must exists into Dolibarr).
    -DataComeFromIdFoundFromCodeId=Code that comes from field number <b>%s</b> of source file will be used to find id of parent object to use (So the code from source file must exists into dictionary <b>%s</b>). Note that if you know id, you can also use it into source file instead of code. Import should work in both cases. 
    +DataComeFromIdFoundFromRef=Value that comes from field number <b>%s</b> of source file will be used to find the id of the parent object to use (so the object <b>%s</b> that has the ref. from source file must exist in the database).
    +DataComeFromIdFoundFromCodeId=Code that comes from field number <b>%s</b> of source file will be used to find the id of the parent object to use (so the code from source file must exist in the dictionary <b>%s</b>). Note that if you know the id, you can also use it in the source file instead of the code. Import should work in both cases.
     DataIsInsertedInto=Data coming from source file will be inserted into the following field:
    -DataIDSourceIsInsertedInto=The id of parent object found using the data in source file, will be inserted into the following field:
    +DataIDSourceIsInsertedInto=The id of parent object was found using the data in the source file, will be inserted into the following field:
     DataCodeIDSourceIsInsertedInto=The id of parent line found from code, will be inserted into following field:
     SourceRequired=Data value is mandatory
     SourceExample=Example of possible data value
     ExampleAnyRefFoundIntoElement=Any ref found for element <b>%s</b>
     ExampleAnyCodeOrIdFoundIntoDictionary=Any code (or id) found into dictionary <b>%s</b>
    -CSVFormatDesc=<b>Comma Separated Value</b> file format (.csv).<br>This is a text file format where fields are separated by separator [ %s ]. If separator is found inside a field content, field is rounded by round character [ %s ]. Escape character to escape round character is [ %s ].
    -Excel95FormatDesc=<b>Excel</b> file format (.xls)<br>This is native Excel 95 format (BIFF5).
    -Excel2007FormatDesc=<b>Excel</b> file format (.xlsx)<br>This is native Excel 2007 format (SpreadsheetML).
    +CSVFormatDesc=<b>Comma Separated Value</b> file format (.csv).<br>This is a text file format where fields are separated by a separator [ %s ]. If separator is found inside a field content, field is rounded by round character [ %s ]. Escape character to escape round character is [ %s ].
    +Excel95FormatDesc=<b>Excel</b> file format (.xls)<br>This is the native Excel 95 format (BIFF5).
    +Excel2007FormatDesc=<b>Excel</b> file format (.xlsx)<br>This is the native Excel 2007 format (SpreadsheetML).
     TsvFormatDesc=<b>Tab Separated Value</b> file format (.tsv)<br>This is a text file format where fields are separated by a tabulator [tab].
     ExportFieldAutomaticallyAdded=Field <b>%s</b> was automatically added. It will avoid you to have similar lines to be treated as duplicate record (with this field added, all lines will own their own id and will differ).
     CsvOptions=CSV format options
    @@ -118,7 +118,7 @@ SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude th
     KeepEmptyToGoToEndOfFile=Keep this field empty to go up to the end of file
     SelectPrimaryColumnsForUpdateAttempt=Select column(s) to use as primary key for update attempt
     UpdateNotYetSupportedForThisImport=Update is not supported for this type of import (only insert)
    -NoUpdateAttempt=No update attempt was performed, only insert 
    +NoUpdateAttempt=No update attempt was performed, only insert
     ImportDataset_user_1=Users (employees or not) and properties
     ComputedField=Computed field
     ## filters
    @@ -130,4 +130,4 @@ FormatControlRule=Format control rule
     KeysToUseForUpdates=Key (column) to use for <b>updating</b> existing data
     NbInsert=Number of inserted lines: %s
     NbUpdate=Number of updated lines: %s
    -MultipleRecordFoundWithTheseFilters=Multiple records have been found with these filters: %s
    \ No newline at end of file
    +MultipleRecordFoundWithTheseFilters=Multiple records have been found with these filters: %s
    diff --git a/htdocs/langs/en_US/externalsite.lang b/htdocs/langs/en_US/externalsite.lang
    index afec761f5fe..da4853df0df 100644
    --- a/htdocs/langs/en_US/externalsite.lang
    +++ b/htdocs/langs/en_US/externalsite.lang
    @@ -2,4 +2,4 @@
     ExternalSiteSetup=Setup link to external website
     ExternalSiteURL=External Site URL
     ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly.
    -ExampleMyMenuEntry=My menu entry
    \ No newline at end of file
    +ExampleMyMenuEntry=My menu entry
    diff --git a/htdocs/langs/en_US/ftp.lang b/htdocs/langs/en_US/ftp.lang
    index d6b9d2ca070..8ecb0c55cad 100644
    --- a/htdocs/langs/en_US/ftp.lang
    +++ b/htdocs/langs/en_US/ftp.lang
    @@ -11,4 +11,4 @@ FTPFailedToRemoveFile=Failed to remove file <b>%s</b>.
     FTPFailedToRemoveDir=Failed to remove directory <b>%s</b> (Check permissions and that directory is empty).
     FTPPassiveMode=Passive mode
     ChooseAFTPEntryIntoMenu=Choose a FTP entry into menu...
    -FailedToGetFile=Failed to get files %s
    \ No newline at end of file
    +FailedToGetFile=Failed to get files %s
    diff --git a/htdocs/langs/en_US/help.lang b/htdocs/langs/en_US/help.lang
    index 2ddbc51ce3a..d5a19d6d119 100644
    --- a/htdocs/langs/en_US/help.lang
    +++ b/htdocs/langs/en_US/help.lang
    @@ -5,9 +5,9 @@ RemoteControlSupport=Online real time / remote support
     OtherSupport=Other support
     ToSeeListOfAvailableRessources=To contact/see available resources:
     HelpCenter=Help center
    -DolibarrHelpCenter=Dolibarr help and support center
    -ToGoBackToDolibarr=Otherwise, click <a href="%s">here to use Dolibarr</a>
    -TypeOfSupport=Source of support
    +DolibarrHelpCenter=Dolibarr Help and Support Center
    +ToGoBackToDolibarr=Otherwise, <a href="%s">click here to continue to use Dolibarr</a>.
    +TypeOfSupport=Type of support
     TypeSupportCommunauty=Community (free)
     TypeSupportCommercial=Commercial
     TypeOfHelp=Type
    @@ -15,12 +15,12 @@ NeedHelpCenter=Need help or support?
     Efficiency=Efficiency
     TypeHelpOnly=Help only
     TypeHelpDev=Help+Development
    -TypeHelpDevForm=Help+Development+Formation
    -ToGetHelpGoOnSparkAngels1=Some companies can provide a fast (sometime immediate) and more efficient online support by taking control of your computer. Such helpers can be found on <b>%s</b> web site:
    -ToGetHelpGoOnSparkAngels3=You can also go to the list of all available coaches for Dolibarr, for this click on button 
    -ToGetHelpGoOnSparkAngels2=Sometimes, there is no company available at the moment you make your search, so think to change the filter to look for "all availability". You will be able to send more requests.
    -BackToHelpCenter=Otherwise, click here to go <a href="%s">back to help center home page</a>.
    -LinkToGoldMember=You can call one of the coach preselected by Dolibarr for your language (%s) by clicking his Widget (status and maximum price are automatically updated):
    +TypeHelpDevForm=Help+Development+Training
    +ToGetHelpGoOnSparkAngels1=Some companies can provide a fast (sometime immediate) and more efficient online support by remote control of your computer. Such help can be found on <b>%s</b> web site:
    +ToGetHelpGoOnSparkAngels3=You can also go to the list of all available trainers for Dolibarr, for this click on button
    +ToGetHelpGoOnSparkAngels2=Sometimes, there is no company available when you make your search, so change the filter to look for "all availability". You will be able to send more requests.
    +BackToHelpCenter=Otherwise, <a href="%s">go back to Help center home page</a>.
    +LinkToGoldMember=You can call one of the trainers preselected by Dolibarr for your language (%s) by clicking their Widget (status and maximum price are automatically updated):
     PossibleLanguages=Supported languages
    -SubscribeToFoundation=Help Dolibarr project, subscribe to the foundation
    +SubscribeToFoundation=Help the Dolibarr project, subscribe to the foundation
     SeeOfficalSupport=For official Dolibarr support in your language: <br><b><a href="%s" target="_blank">%s</a></b>
    diff --git a/htdocs/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang
    index eca2bbdfe46..8cf5ec2c1e6 100644
    --- a/htdocs/langs/en_US/holiday.lang
    +++ b/htdocs/langs/en_US/holiday.lang
    @@ -1,10 +1,10 @@
     # Dolibarr language file - Source file is en_US - holiday
     HRM=HRM
    -Holidays=Leaves
    -CPTitreMenu=Leaves
    +Holidays=Leave
    +CPTitreMenu=Leave
     MenuReportMonth=Monthly statement
     MenuAddCP=New leave request
    -NotActiveModCP=You must enable the module Leaves to view this page.
    +NotActiveModCP=You must enable the module Leave to view this page.
     AddCP=Make a leave request
     DateDebCP=Start date
     DateFinCP=End date
    @@ -15,18 +15,18 @@ ApprovedCP=Approved
     CancelCP=Canceled
     RefuseCP=Refused
     ValidatorCP=Approbator
    -ListeCP=List of leaves
    +ListeCP=List of leave
     LeaveId=Leave ID
     ReviewedByCP=Will be approved by
     UserForApprovalID=User for approval ID
    -UserForApprovalFirstname=Firstname of approval user
    -UserForApprovalLastname=Lastname of approval user
    +UserForApprovalFirstname=First name of approval user
    +UserForApprovalLastname=Last name of approval user
     UserForApprovalLogin=Login of approval user
     DescCP=Description
     SendRequestCP=Create leave request
     DelayToRequestCP=Leave requests must be made at least <b>%s day(s)</b> before them.
    -MenuConfCP=Balance of leaves
    -SoldeCPUser=Leaves balance is <b>%s</b> days.
    +MenuConfCP=Balance of leave
    +SoldeCPUser=Leave balance is <b>%s</b> days.
     ErrorEndDateCP=You must select an end date greater than the start date.
     ErrorSQLCreateCP=An SQL error occurred during the creation:
     ErrorIDFicheCP=An error has occurred, the leave request does not exist.
    @@ -85,7 +85,7 @@ NewSoldeCP=New Balance
     alreadyCPexist=A leave request has already been done on this period.
     FirstDayOfHoliday=First day of vacation
     LastDayOfHoliday=Last day of vacation
    -BoxTitleLastLeaveRequests=Latest %s modified leave requests 
    +BoxTitleLastLeaveRequests=Latest %s modified leave requests
     HolidaysMonthlyUpdate=Monthly update
     ManualUpdate=Manual update
     HolidaysCancelation=Leave request cancelation
    @@ -101,8 +101,8 @@ LEAVE_SICK=Sick leave
     LEAVE_OTHER=Other leave
     LEAVE_PAID_FR=Paid vacation
     ## Configuration du Module ##
    -LastUpdateCP=Latest automatic update of leaves allocation
    -MonthOfLastMonthlyUpdate=Month of latest automatic update of leaves allocation
    +LastUpdateCP=Latest automatic update of leave allocation
    +MonthOfLastMonthlyUpdate=Month of latest automatic update of leave allocation
     UpdateConfCPOK=Updated successfully.
     Module27130Name= Management of leave requests
     Module27130Desc= Management of leave requests
    @@ -112,7 +112,7 @@ NoticePeriod=Notice period
     HolidaysToValidate=Validate leave requests
     HolidaysToValidateBody=Below is a leave request to validate
     HolidaysToValidateDelay=This leave request will take place within a period of less than %s days.
    -HolidaysToValidateAlertSolde=The user who made this leave reques do not have enough available days.
    +HolidaysToValidateAlertSolde=The user who made this leave request does have enough available days.
     HolidaysValidated=Validated leave requests
     HolidaysValidatedBody=Your leave request for %s to %s has been validated.
     HolidaysRefused=Request denied
    @@ -121,4 +121,9 @@ HolidaysCanceled=Canceled leaved request
     HolidaysCanceledBody=Your leave request for %s to %s has been canceled.
     FollowedByACounter=1: This type of leave need to be followed by a counter. Counter is incremented manually or automatically and when a leave request is validated, counter is decremented.<br>0: Not followed by a counter.
     NoLeaveWithCounterDefined=There is no leave types defined that need to be followed by a counter
    -GoIntoDictionaryHolidayTypes=Go into <strong>Home - Setup - Dictionaries - Type of leaves</strong> to setup the different types of leaves.
    +GoIntoDictionaryHolidayTypes=Go into <strong>Home - Setup - Dictionaries - Type of leave</strong> to setup the different types of leaves.
    +HolidaySetup=Setup of module Holiday
    +HolidaysNumberingModules=Leave requests numbering models
    +TemplatePDFHolidays=Template for leave requests PDF
    +FreeLegalTextOnHolidays=Free text on PDF
    +WatermarkOnDraftHolidayCards=Watermarks on draft leave requests
    \ No newline at end of file
    diff --git a/htdocs/langs/en_US/hrm.lang b/htdocs/langs/en_US/hrm.lang
    index 3889c73dbbb..12bb1592cbc 100644
    --- a/htdocs/langs/en_US/hrm.lang
    +++ b/htdocs/langs/en_US/hrm.lang
    @@ -5,7 +5,7 @@ Establishments=Establishments
     Establishment=Establishment
     NewEstablishment=New establishment
     DeleteEstablishment=Delete establishment
    -ConfirmDeleteEstablishment=Are-you sure to delete this establishment?
    +ConfirmDeleteEstablishment=Are you sure you wish to delete this establishment?
     OpenEtablishment=Open establishment
     CloseEtablishment=Close establishment
     # Dictionary
    diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang
    index 00d4be864ff..bcca348c861 100644
    --- a/htdocs/langs/en_US/install.lang
    +++ b/htdocs/langs/en_US/install.lang
    @@ -2,37 +2,37 @@
     InstallEasy=Just follow the instructions step by step.
     MiscellaneousChecks=Prerequisites check
     ConfFileExists=Configuration file <b>%s</b> exists.
    -ConfFileDoesNotExistsAndCouldNotBeCreated=Configuration file <b>%s</b> does not exist and could not be created !
    +ConfFileDoesNotExistsAndCouldNotBeCreated=Configuration file <b>%s</b> does not exist and could not be created!
     ConfFileCouldBeCreated=Configuration file <b>%s</b> could be created.
    -ConfFileIsNotWritable=Configuration file <b>%s</b> is not writable. Check permissions. For first install, your web server must be granted to be able to write into this file during configuration process ("chmod 666" for example on a Unix like OS).
    +ConfFileIsNotWritable=Configuration file <b>%s</b> is not writable. Check permissions. For first install, your web server must be able to write into this file during configuration process ("chmod 666" for example on a Unix like OS).
     ConfFileIsWritable=Configuration file <b>%s</b> is writable.
     ConfFileMustBeAFileNotADir=Configuration file <b>%s</b> must be a file, not a directory.
    -ConfFileReload=Reload all information from configuration file.
    +ConfFileReload=Reloading parameters from configuration file.
     PHPSupportSessions=This PHP supports sessions.
     PHPSupportPOSTGETOk=This PHP supports variables POST and GET.
    -PHPSupportPOSTGETKo=It's possible your PHP setup does not support variables POST and/or GET. Check your parameter <b>variables_order</b> in php.ini.
    -PHPSupportGD=This PHP support GD graphical functions.
    -PHPSupportCurl=This PHP support Curl.
    -PHPSupportUTF8=This PHP support UTF8 functions.
    +PHPSupportPOSTGETKo=It's possible your PHP setup does not support variables POST and/or GET. Check the parameter <b>variables_order</b> in php.ini.
    +PHPSupportGD=This PHP supports GD graphical functions.
    +PHPSupportCurl=This PHP supports Curl.
    +PHPSupportUTF8=This PHP supports UTF8 functions.
     PHPMemoryOK=Your PHP max session memory is set to <b>%s</b>. This should be enough.
    -PHPMemoryTooLow=Your PHP max session memory is set to <b>%s</b> bytes. This should be too low. Change your <b>php.ini</b> to set <b>memory_limit</b> parameter to at least <b>%s</b> bytes.
    -Recheck=Click here for a more significative test
    -ErrorPHPDoesNotSupportSessions=Your PHP installation does not support sessions. This feature is required to make Dolibarr working. Check your PHP setup.
    -ErrorPHPDoesNotSupportGD=Your PHP installation does not support graphical function GD. No graph will be available.
    +PHPMemoryTooLow=Your PHP max session memory is set to <b>%s</b> bytes. This is too low. Change your <b>php.ini</b> to set <b>memory_limit</b> parameter to at least <b>%s</b> bytes.
    +Recheck=Click here for a more detailed test
    +ErrorPHPDoesNotSupportSessions=Your PHP installation does not support sessions. This feature is required to allow Dolibarr to work. Check your PHP setup and permissions of the sessions directory.
    +ErrorPHPDoesNotSupportGD=Your PHP installation does not support GD graphical functions. No graphs will be available.
     ErrorPHPDoesNotSupportCurl=Your PHP installation does not support Curl.
    -ErrorPHPDoesNotSupportUTF8=Your PHP installation does not support UTF8 functions. Dolibarr can't work correctly. Solve this before installing Dolibarr.
    +ErrorPHPDoesNotSupportUTF8=Your PHP installation does not support UTF8 functions. Dolibarr cannot work correctly. Resolve this before installing Dolibarr.
     ErrorDirDoesNotExists=Directory %s does not exist.
    -ErrorGoBackAndCorrectParameters=Go backward and correct wrong parameters.
    +ErrorGoBackAndCorrectParameters=Go back and check/correct the parameters.
     ErrorWrongValueForParameter=You may have typed a wrong value for parameter '%s'.
     ErrorFailedToCreateDatabase=Failed to create database '%s'.
     ErrorFailedToConnectToDatabase=Failed to connect to database '%s'.
     ErrorDatabaseVersionTooLow=Database version (%s) too old. Version %s or higher is required.
     ErrorPHPVersionTooLow=PHP version too old. Version %s is required.
    -ErrorConnectedButDatabaseNotFound=Connection to server successfull but database '%s' not found.
    +ErrorConnectedButDatabaseNotFound=Connection to server successful but database '%s' not found.
     ErrorDatabaseAlreadyExists=Database '%s' already exists.
    -IfDatabaseNotExistsGoBackAndUncheckCreate=If database does not exists, go back and check option "Create database".
    +IfDatabaseNotExistsGoBackAndUncheckCreate=If the database does not exist, go back and check option "Create database".
     IfDatabaseExistsGoBackAndCheckCreate=If database already exists, go back and uncheck "Create database" option.
    -WarningBrowserTooOld=Too old version of browser. Upgrading your browser to a recent version of Firefox, Chrome or Opera is highly recommanded.
    +WarningBrowserTooOld=Version of browser is too old. Upgrading your browser to a recent version of Firefox, Chrome or Opera is highly recommended.
     PHPVersion=PHP Version
     License=Using license
     ConfigurationFile=Configuration file
    @@ -45,22 +45,23 @@ DolibarrDatabase=Dolibarr Database
     DatabaseType=Database type
     DriverType=Driver type
     Server=Server
    -ServerAddressDescription=Name or ip address for database server, usually 'localhost' when database server is hosted on same server than web server
    +ServerAddressDescription=Name or ip address for the database server. Usually 'localhost' when the database server is hosted on the same server as the web server.
     ServerPortDescription=Database server port. Keep empty if unknown.
     DatabaseServer=Database server
     DatabaseName=Database name
    -DatabasePrefix=Database prefix table
    -AdminLogin=Login for Dolibarr database owner.
    -PasswordAgain=Retype password a second time
    +DatabasePrefix=Database table prefix
    +DatabasePrefixDescription=Database table prefix. If empty, defaults to llx_.
    +AdminLogin=User account for the Dolibarr database owner.
    +PasswordAgain=Retype password confirmation
     AdminPassword=Password for Dolibarr database owner.
     CreateDatabase=Create database
    -CreateUser=Create owner or grant him permission on database
    +CreateUser=Create user account or grant user account permission on the Dolibarr database
     DatabaseSuperUserAccess=Database server - Superuser access
    -CheckToCreateDatabase=Check box if database does not exist and must be created.<br>In this case, you must fill the login/password for superuser account at the bottom of this page.
    -CheckToCreateUser=Check box if database owner does not exist and must be created, or if it exists but database does not exists and permissions must be granted.<br>In this case, you must choose its login and password and also fill the login/password for the superuser account at the bottom of this page. If this box is unchecked, owner database and its passwords must exists.
    -DatabaseRootLoginDescription=Login of the user allowed to create new databases or new users, mandatory if your database or its owner does not already exists.
    -KeepEmptyIfNoPassword=Leave empty if user has no password (avoid this)
    -SaveConfigurationFile=Save values
    +CheckToCreateDatabase=Check the box if the database does not exist yet and so must be created.<br>In this case, you must also fill in the user name and password for the superuser account at the bottom of this page.
    +CheckToCreateUser=Check the box if:<br>the database user account does not yet exist and so must be created, or<br>if the user account exists but the database does not exist and permissions must be granted.<br>In this case, you must enter the user account and password and <b>also</b> the superuser account name and password at the bottom of this page. If this box is unchecked, database owner and password must already exist.
    +DatabaseRootLoginDescription=Superuser account name (to create new databases or new users), mandatory if the database or its owner does not already exist.
    +KeepEmptyIfNoPassword=Leave empty if superuser has no password (NOT recommended)
    +SaveConfigurationFile=Saving parameters to
     ServerConnection=Server connection
     DatabaseCreation=Database creation
     CreateDatabaseObjects=Database objects creation
    @@ -71,9 +72,9 @@ CreateOtherKeysForTable=Create foreign keys and indexes for table %s
     OtherKeysCreation=Foreign keys and indexes creation
     FunctionsCreation=Functions creation
     AdminAccountCreation=Administrator login creation
    -PleaseTypePassword=Please type a password, empty passwords are not allowed !
    -PleaseTypeALogin=Please type a login !
    -PasswordsMismatch=Passwords differs, please try again !
    +PleaseTypePassword=Please type a password, empty passwords are not allowed!
    +PleaseTypeALogin=Please type a login!
    +PasswordsMismatch=Passwords differs, please try again!
     SetupEnd=End of setup
     SystemIsInstalled=This installation is complete.
     SystemIsUpgraded=Dolibarr has been upgraded successfully.
    @@ -81,65 +82,65 @@ YouNeedToPersonalizeSetup=You need to configure Dolibarr to suit your needs (app
     AdminLoginCreatedSuccessfuly=Dolibarr administrator login '<b>%s</b>' created successfully.
     GoToDolibarr=Go to Dolibarr
     GoToSetupArea=Go to Dolibarr (setup area)
    -MigrationNotFinished=Version of your database is not completely up to date, so you'll have to run the upgrade process again. 
    +MigrationNotFinished=The database version is not completely up to date: run the upgrade process again.
     GoToUpgradePage=Go to upgrade page again
     WithNoSlashAtTheEnd=Without the slash "/" at the end
    -DirectoryRecommendation=It is recommanded to use a directory outside of your directory of your web pages.
    +DirectoryRecommendation=It is recommended to use a directory outside of the web pages.
     LoginAlreadyExists=Already exists
     DolibarrAdminLogin=Dolibarr admin login
    -AdminLoginAlreadyExists=Dolibarr administrator account '<b>%s</b>' already exists. Go back, if you want to create another one.
    +AdminLoginAlreadyExists=Dolibarr administrator account '<b>%s</b>' already exists. Go back if you want to create another one.
     FailedToCreateAdminLogin=Failed to create Dolibarr administrator account.
    -WarningRemoveInstallDir=Warning, for security reasons, once the install or upgrade is complete, to avoid using install tools again, you should add a file called <b>install.lock</b> into Dolibarr document directory, in order to avoid malicious use of it.
    -FunctionNotAvailableInThisPHP=Not available on this PHP
    +WarningRemoveInstallDir=Warning, for security reasons, once the install or upgrade is complete, you should add a file called <b>install.lock</b> into the Dolibarr document directory in order to prevent the accidental/malicious use of the install tools again.
    +FunctionNotAvailableInThisPHP=Not available in this PHP
     ChoosedMigrateScript=Choose migration script
     DataMigration=Database migration (data)
     DatabaseMigration=Database migration (structure + some data)
     ProcessMigrateScript=Script processing
     ChooseYourSetupMode=Choose your setup mode and click "Start"...
     FreshInstall=Fresh install
    -FreshInstallDesc=Use this mode if this is your first install. If not, this mode can repair a incomplete previous install, but if you want to upgrade your version, choose "Upgrade" mode.
    +FreshInstallDesc=Use this mode if this is your first install. If not, this mode can repair a incomplete previous install. If you want to upgrade your version, choose "Upgrade" mode.
     Upgrade=Upgrade
     UpgradeDesc=Use this mode if you have replaced old Dolibarr files with files from a newer version. This will upgrade your database and data.
     Start=Start
     InstallNotAllowed=Setup not allowed by <b>conf.php</b> permissions
     YouMustCreateWithPermission=You must create file %s and set write permissions on it for the web server during install process.
    -CorrectProblemAndReloadPage=Please fix the problem and press F5 to reload page.
    +CorrectProblemAndReloadPage=Please fix the problem and press F5 to reload the page.
     AlreadyDone=Already migrated
     DatabaseVersion=Database version
     ServerVersion=Database server version
     YouMustCreateItAndAllowServerToWrite=You must create this directory and allow for the web server to write into it.
     DBSortingCollation=Character sorting order
    -YouAskDatabaseCreationSoDolibarrNeedToConnect=You ask to create database <b>%s</b>, but for this, Dolibarr need to connect to server <b>%s</b> with super user <b>%s</b> permissions.
    -YouAskLoginCreationSoDolibarrNeedToConnect=You ask to create database login <b>%s</b>, but for this, Dolibarr need to connect to server <b>%s</b> with super user <b>%s</b> permissions.
    -BecauseConnectionFailedParametersMayBeWrong=As connection failed, host or super user parameters must be wrong.
    +YouAskDatabaseCreationSoDolibarrNeedToConnect=You selected create database <b>%s</b>, but for this, Dolibarr needs to connect to server <b>%s</b> with super user <b>%s</b> permissions.
    +YouAskLoginCreationSoDolibarrNeedToConnect=You selected create database user <b>%s</b>, but for this, Dolibarr needs to connect to server <b>%s</b> with super user <b>%s</b> permissions.
    +BecauseConnectionFailedParametersMayBeWrong=The database connection failed: the host or super user parameters must be wrong.
     OrphelinsPaymentsDetectedByMethod=Orphans payment detected by method %s
     RemoveItManuallyAndPressF5ToContinue=Remove it manually and press F5 to continue.
     FieldRenamed=Field renamed
    -IfLoginDoesNotExistsCheckCreateUser=If login does not exists yet, you must check option "Create user"
    -ErrorConnection=Server "<b>%s</b>", database name "<b>%s</b>", login "<b>%s</b>", or database password may be wrong or PHP client version may be too old compared to database version.
    +IfLoginDoesNotExistsCheckCreateUser=If the user does not exist yet, you must check option "Create user"
    +ErrorConnection=Server "<b>%s</b>", database name "<b>%s</b>", login "<b>%s</b>", or database password may be wrong or the PHP client version may be too old compared to the database version.
     InstallChoiceRecommanded=Recommended choice to install version <b>%s</b> from your current version <b>%s</b>
     InstallChoiceSuggested=<b>Install choice suggested by installer</b>.
    -MigrateIsDoneStepByStep=The targeted version (%s) has a gap of several versions, so install wizard will come back to suggest next migration once this one will be finished.
    -CheckThatDatabasenameIsCorrect=Check that database name "<b>%s</b>" is correct.
    +MigrateIsDoneStepByStep=The targeted version (%s) has a gap of several versions. The install wizard will come back to suggest a further migration once this one is complete.
    +CheckThatDatabasenameIsCorrect=Check that the database name "<b>%s</b>" is correct.
     IfAlreadyExistsCheckOption=If this name is correct and that database does not exist yet, you must check option "Create database".
     OpenBaseDir=PHP openbasedir parameter
    -YouAskToCreateDatabaseSoRootRequired=You checked the box "Create database". For this, you need to provide login/password of superuser (bottom of form).
    -YouAskToCreateDatabaseUserSoRootRequired=You checked the box "Create database owner". For this, you need to provide login/password of superuser (bottom of form).
    -NextStepMightLastALongTime=Current step may last several minutes. Please wait until the next screen is shown completely before continuing.
    -MigrationCustomerOrderShipping=Migrate shipping for customer orders storage 
    -MigrationShippingDelivery=Upgrade storage of shipping 
    -MigrationShippingDelivery2=Upgrade storage of shipping 2 
    +YouAskToCreateDatabaseSoRootRequired=You checked the box "Create database". For this, you need to provide the login/password of superuser (bottom of form).
    +YouAskToCreateDatabaseUserSoRootRequired=You checked the box "Create database owner". For this, you need to provide the login/password of superuser (bottom of form).
    +NextStepMightLastALongTime=The current step may take several minutes. Please wait until the next screen is shown completely before continuing.
    +MigrationCustomerOrderShipping=Migrate shipping for customer orders storage
    +MigrationShippingDelivery=Upgrade storage of shipping
    +MigrationShippingDelivery2=Upgrade storage of shipping 2
     MigrationFinished=Migration finished
    -LastStepDesc=<strong>Last step</strong>: Define here login and password you plan to use to connect to software. Do not loose this as it is the account to administer all others.
    +LastStepDesc=<strong>Last step</strong>: Define here the login and password you wish to use to connect to Dolibarr. <b>Do not lose this as it is the master account to administer all other/additional user accounts.</b>
     ActivateModule=Activate module %s
     ShowEditTechnicalParameters=Click here to show/edit advanced parameters (expert mode)
    -WarningUpgrade=Warning:\nDid your run a database backup first?\nThis is highly recommanded: for example, due to some bugs into databases systems (for example mysql version 5.5.40/41/42/43), some data or tables may be lost during this process, so it is highly recommanded to have a complete dump of your database before starting migration.\n\nClick OK to start migration process...
    -ErrorDatabaseVersionForbiddenForMigration=Your database version is %s. It has a critical bug making data loss if you make structure change on your database, like it is required by the migration process. For his reason, migration will not be allowed until you upgrade your database to a higher fixed version (list of known bugged version: %s) 
    -KeepDefaultValuesWamp=You use the Dolibarr setup wizard from DoliWamp, so values proposed here are already optimized. Change them only if you know what you do.
    -KeepDefaultValuesDeb=You use the Dolibarr setup wizard from a Linux package (Ubuntu, Debian, Fedora...), so values proposed here are already optimized. Only the password of the database owner to create must be completed. Change other parameters only if you know what you do.
    -KeepDefaultValuesMamp=You use the Dolibarr setup wizard from DoliMamp, so values proposed here are already optimized. Change them only if you know what you do.
    -KeepDefaultValuesProxmox=You use the Dolibarr setup wizard from a Proxmox virtual appliance, so values proposed here are already optimized. Change them only if you know what you do.
    -UpgradeExternalModule=Run dedicated upgrade process of external modules
    +WarningUpgrade=Warning:\nDid you run a database backup first?\nThis is highly recommended. Loss of data (due to for example bugs in mysql version 5.5.40/41/42/43) may be possible during this process, so it is essential to take a complete dump of your database before starting any migration.\n\nClick OK to start migration process...
    +ErrorDatabaseVersionForbiddenForMigration=Your database version is %s. It has a critical bug, making data loss possible if you make structural changes in your database, such as is required by the migration process. For his reason, migration will not be allowed until you upgrade your database to a layer (patched) version (list of known buggy versions: %s)
    +KeepDefaultValuesWamp=You used the Dolibarr setup wizard from DoliWamp, so values proposed here are already optimized. Change them only if you know what you are doing.
    +KeepDefaultValuesDeb=You used the Dolibarr setup wizard from a Linux package (Ubuntu, Debian, Fedora...), so the values proposed here are already optimized. Only the password of the database owner to create must be entered. Change other parameters only if you know what you are doing.
    +KeepDefaultValuesMamp=You used the Dolibarr setup wizard from DoliMamp, so the values proposed here are already optimized. Change them only if you know what you are doing.
    +KeepDefaultValuesProxmox=You used the Dolibarr setup wizard from a Proxmox virtual appliance, so the values proposed here are already optimized. Change them only if you know what you are doing.
    +UpgradeExternalModule=Run dedicated upgrade process of external module
     SetAtLeastOneOptionAsUrlParameter=Set at least one option as a parameter in URL. For example:  '...repair.php?standard=confirmed'
     NothingToDelete=Nothing to clean/delete
     NothingToDo=Nothing to do
    @@ -151,7 +152,7 @@ MigrationSupplierOrder=Data migration for vendor's orders
     MigrationProposal=Data migration for commercial proposals
     MigrationInvoice=Data migration for customer's invoices
     MigrationContract=Data migration for contracts
    -MigrationSuccessfullUpdate=Upgrade successfull
    +MigrationSuccessfullUpdate=Upgrade successful
     MigrationUpdateFailed=Failed upgrade process
     MigrationRelationshipTables=Data migration for relationship tables (%s)
     MigrationPaymentsUpdate=Payment data correction
    @@ -163,9 +164,9 @@ MigrationContractsUpdate=Contract data correction
     MigrationContractsNumberToUpdate=%s contract(s) to update
     MigrationContractsLineCreation=Create contract line for contract ref %s
     MigrationContractsNothingToUpdate=No more things to do
    -MigrationContractsFieldDontExist=Field fk_facture does not exists anymore. Nothing to do.
    +MigrationContractsFieldDontExist=Field fk_facture does not exist anymore. Nothing to do.
     MigrationContractsEmptyDatesUpdate=Contract empty date correction
    -MigrationContractsEmptyDatesUpdateSuccess=Contract emtpy date correction done successfully
    +MigrationContractsEmptyDatesUpdateSuccess=Contract empty date correction done successfully
     MigrationContractsEmptyDatesNothingToUpdate=No contract empty date to correct
     MigrationContractsEmptyCreationDatesNothingToUpdate=No contract creation date to correct
     MigrationContractsInvalidDatesUpdate=Bad value date contract correction
    @@ -187,24 +188,24 @@ MigrationDeliveryDetail=Delivery update
     MigrationStockDetail=Update stock value of products
     MigrationMenusDetail=Update dynamic menus tables
     MigrationDeliveryAddress=Update delivery address in shipments
    -MigrationProjectTaskActors=Data migration for llx_projet_task_actors table
    +MigrationProjectTaskActors=Data migration for table llx_projet_task_actors
     MigrationProjectUserResp=Data migration field fk_user_resp of llx_projet to llx_element_contact
     MigrationProjectTaskTime=Update time spent in seconds
     MigrationActioncommElement=Update data on actions
     MigrationPaymentMode=Data migration for payment mode
     MigrationCategorieAssociation=Migration of categories
    -MigrationEvents=Migration of events to add event owner into assignement table
    -MigrationEventsContact=Migration of events to add event contact into assignement table
    +MigrationEvents=Migration of events to add event owner into assignment table
    +MigrationEventsContact=Migration of events to add event contact into assignment table
     MigrationRemiseEntity=Update entity field value of llx_societe_remise
     MigrationRemiseExceptEntity=Update entity field value of llx_societe_remise_except
     MigrationUserRightsEntity=Update entity field value of llx_user_rights
     MigrationUserGroupRightsEntity=Update entity field value of llx_usergroup_rights
     MigrationReloadModule=Reload module %s
     MigrationResetBlockedLog=Reset module BlockedLog for v7 algorithm
    -ShowNotAvailableOptions=Show not available options
    -HideNotAvailableOptions=Hide not available options
    -ErrorFoundDuringMigration=Error were reported during migration process so next step is not available. To ignore errors, you can <a href="%s">click here</a>, but application or some features may not work correctly until fixed.
    -YouTryInstallDisabledByDirLock=The application try to sefl upgrade, but install/upgrade pages have been disabled for security reason (directory renamed with .lock suffix).<br>
    -YouTryInstallDisabledByFileLock=The application try to sefl upgrade, but install/upgrade pages pages have been disabled for security reason (by lock file <strong>install.lock</strong> into dolibarr documents directory).<br>
    +ShowNotAvailableOptions=Show unavailable options
    +HideNotAvailableOptions=Hide unavailable options
    +ErrorFoundDuringMigration=Error(s) were reported during the migration process so next step is not available. To ignore errors, you can <a href="%s">click here</a>, but the application or some features may not work correctly until the errors are resolved.
    +YouTryInstallDisabledByDirLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (directory renamed with .lock suffix).<br>
    +YouTryInstallDisabledByFileLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (by the existence of a lock file <strong>install.lock</strong> in the dolibarr documents directory).<br>
     ClickHereToGoToApp=Click here to go to your application
    -ClickOnLinkOrRemoveManualy=Click on following link and if you always reach this page, you must remove the file install.lock into documents directory manually
    \ No newline at end of file
    +ClickOnLinkOrRemoveManualy=Click on the following link. If you always see this same page, you must remove/rename the file install.lock in the documents directory.
    diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang
    index a062883d667..99c9b6486e0 100644
    --- a/htdocs/langs/en_US/languages.lang
    +++ b/htdocs/langs/en_US/languages.lang
    @@ -86,3 +86,4 @@ Language_uz_UZ=Uzbek
     Language_vi_VN=Vietnamese
     Language_zh_CN=Chinese
     Language_zh_TW=Chinese (Traditional)
    +Language_bh_MY=Malay
    diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang
    index 67824ccd237..abe11602147 100644
    --- a/htdocs/langs/en_US/ldap.lang
    +++ b/htdocs/langs/en_US/ldap.lang
    @@ -24,4 +24,4 @@ MemberTypeSynchronized=Member type synchronized
     ContactSynchronized=Contact synchronized
     ForceSynchronize=Force synchronizing Dolibarr -> LDAP
     ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility.
    -PasswordOfUserInLDAP=Password of user in LDAP
    \ No newline at end of file
    +PasswordOfUserInLDAP=Password of user in LDAP
    diff --git a/htdocs/langs/en_US/link.lang b/htdocs/langs/en_US/link.lang
    index 77a1814f1ca..fdcf07aeff4 100644
    --- a/htdocs/langs/en_US/link.lang
    +++ b/htdocs/langs/en_US/link.lang
    @@ -7,4 +7,4 @@ ErrorFileNotLinked=The file could not be linked
     LinkRemoved=The link %s has been removed
     ErrorFailedToDeleteLink= Failed to remove link '<b>%s</b>'
     ErrorFailedToUpdateLink= Failed to update link '<b>%s</b>'
    -URLToLink=URL to link
    \ No newline at end of file
    +URLToLink=URL to link
    diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang
    index 23fc671e9b1..d4f835874e7 100644
    --- a/htdocs/langs/en_US/mails.lang
    +++ b/htdocs/langs/en_US/mails.lang
    @@ -33,7 +33,7 @@ ValidMailing=Valid emailing
     MailingStatusDraft=Draft
     MailingStatusValidated=Validated
     MailingStatusSent=Sent
    -MailingStatusSentPartialy=Sent partialy
    +MailingStatusSentPartialy=Sent partially
     MailingStatusSentCompletely=Sent completely
     MailingStatusError=Error
     MailingStatusNotSent=Not sent
    @@ -45,7 +45,7 @@ MailingStatusReadAndUnsubscribe=Read and unsubscribe
     ErrorMailRecipientIsEmpty=Email recipient is empty
     WarningNoEMailsAdded=No new Email to add to recipient's list.
     ConfirmValidMailing=Are you sure you want to validate this emailing?
    -ConfirmResetMailing=Warning, by reinitializing emailing <b>%s</b>, you will allow resending this email in a mass mailing. Are you sure you this is what you want to do?
    +ConfirmResetMailing=Warning, by re-initializing emailing <b>%s</b> , you will allow resending this email in a mass mailing. Are you sure you want to do this?
     ConfirmDeleteMailing=Are you sure you want to delete this emailing?
     NbOfUniqueEMails=No. of unique emails
     NbOfEMails=No. of EMails
    @@ -66,16 +66,16 @@ DateLastSend=Date of latest sending
     DateSending=Date sending
     SentTo=Sent to <b>%s</b>
     MailingStatusRead=Read
    -YourMailUnsubcribeOK=The email <b>%s</b>  is correctly unsubcribe from mailing list
    -ActivateCheckReadKey=Key used to encrypt URL used for "Read Receipt" and "Unsubcribe" feature
    +YourMailUnsubcribeOK=The email <b>%s</b>  is correctly unsubscribe from mailing list
    +ActivateCheckReadKey=Key used to encrypt URL used for "Read Receipt" and "Unsubscribe" feature
     EMailSentToNRecipients=EMail sent to %s recipients.
     EMailSentForNElements=EMail sent for %s elements.
     XTargetsAdded=<b>%s</b> recipients added into target list
    -OnlyPDFattachmentSupported=If the PDF documents were already generated for the objects to send, they will be attached to email. If not, no email will be sent (also, note that only pdf documents are supported as attachment in mass sending in this version).
    +OnlyPDFattachmentSupported=If the PDF documents were already generated for the objects to send, they will be attached to email. If not, no email will be sent (also, note that only pdf documents are supported as attachments in mass sending in this version).
     AllRecipientSelected=The recipients of the %s record selected (if their email is known).
     GroupEmails=Group emails
     OneEmailPerRecipient=One email per recipient (by default, one email per record selected)
    -WarningIfYouCheckOneRecipientPerEmail=Warning, if you check this box, it means only one email will be sent for several different record selected, so, if your message contains substitution variables that refers to data of a record, it becomes not possible to replace them. 
    +WarningIfYouCheckOneRecipientPerEmail=Warning, if you check this box, it means only one email will be sent for several different record selected, so, if your message contains substitution variables that refers to data of a record, it becomes not possible to replace them.
     ResultOfMailSending=Result of mass EMail sending
     NbSelected=No. selected
     NbIgnored=No. ignored
    @@ -105,7 +105,7 @@ SearchAMailing=Search mailing
     SendMailing=Send emailing
     SentBy=Sent by
     MailingNeedCommand=Sending an emailing can be performed from command line. Ask your server administrator to launch the following command to send the emailing to all recipients:
    -MailingNeedCommand2=You can however send them online by adding parameter MAILING_LIMIT_SENDBYWEB with value of max number of emails you want to send by session. For this, go on Home - Setup - Other. 
    +MailingNeedCommand2=You can however send them online by adding parameter MAILING_LIMIT_SENDBYWEB with value of max number of emails you want to send by session. For this, go on Home - Setup - Other.
     ConfirmSendingEmailing=If you want to send emailing directly from this screen, please confirm you are sure you want to send emailing now from your browser ?
     LimitSendingEmailing=Note: Sending of emailings from web interface is done in several times for security and timeout reasons, <b>%s</b> recipients at a time for each sending session.
     TargetsReset=Clear list
    @@ -121,7 +121,7 @@ TagUnsubscribe=Unsubscribe link
     TagSignature=Signature of sending user
     EMailRecipient=Recipient EMail
     TagMailtoEmail=Recipient EMail (including html "mailto:" link)
    -NoEmailSentBadSenderOrRecipientEmail=No email sent. Bad sender or recipient email. Verify user profile. 
    +NoEmailSentBadSenderOrRecipientEmail=No email sent. Bad sender or recipient email. Verify user profile.
     # Module Notifications
     Notifications=Notifications
     NoNotificationsWillBeSent=No email notifications are planned for this event and company
    @@ -133,13 +133,13 @@ ListOfNotificationsDone=List all email notifications sent
     MailSendSetupIs=Configuration of email sending has been setup to '%s'. This mode can't be used to send mass emailing.
     MailSendSetupIs2=You must first go, with an admin account, into menu %sHome - Setup - EMails%s to change parameter <strong>'%s'</strong> to use mode '%s'. With this mode, you can enter setup of the SMTP server provided by your Internet Service Provider and use Mass emailing feature.
     MailSendSetupIs3=If you have any questions on how to setup your SMTP server, you can ask to %s.
    -YouCanAlsoUseSupervisorKeyword=You can also add the keyword <strong>__SUPERVISOREMAIL__</strong> to have email being sent to the supervisor of user (works only if an email is defined for this supervisor) 
    +YouCanAlsoUseSupervisorKeyword=You can also add the keyword <strong>__SUPERVISOREMAIL__</strong> to have email being sent to the supervisor of user (works only if an email is defined for this supervisor)
     NbOfTargetedContacts=Current number of targeted contact emails
     UseFormatFileEmailToTarget=Imported file must have format <strong>email;name;firstname;other</strong>
     UseFormatInputEmailToTarget=Enter a string with format <strong>email;name;firstname;other</strong>
     MailAdvTargetRecipients=Recipients (advanced selection)
     AdvTgtTitle=Fill input fields to preselect the third parties or contacts/addresses to target
    -AdvTgtSearchTextHelp=Use %% as magic caracters. For exemple to find all item like <b>jean, joe, jim</b>, you can input <b>j%%</b>, you can also use ; as separator for value, and use ! for except this value. For exemple  <b>jean;joe;jim%%;!jimo;!jima%</b> will target all jean, joe, start with jim but not jimo and not everythnig taht start by jima 
    +AdvTgtSearchTextHelp=Use %% as wildcards. For example to find all item like <b>jean, joe, jim</b>, you can input <b>j%%</b>, you can also use ; as separator for value, and use ! for except this value. For example  <b>jean;joe;jim%%;!jimo;!jima%</b> will target all jean, joe, start with jim but not jimo and not everything that starts with jima
     AdvTgtSearchIntHelp=Use interval to select int or float value
     AdvTgtMinVal=Minimum value
     AdvTgtMaxVal=Maximum value
    @@ -153,7 +153,7 @@ AddAll=Add all
     RemoveAll=Remove all
     ItemsCount=Item(s)
     AdvTgtNameTemplate=Filter name
    -AdvTgtAddContact=Add emails according to criterias
    +AdvTgtAddContact=Add emails according to criteria
     AdvTgtLoadFilter=Load filter
     AdvTgtDeleteFilter=Delete filter
     AdvTgtSaveFilter=Save filter
    @@ -166,4 +166,4 @@ InGoingEmailSetup=Incoming email setup
     OutGoingEmailSetupForEmailing=Outgoing email setup (for mass emailing)
     DefaultOutgoingEmailSetup=Default outgoing email setup
     Information=Information
    -ContactsWithThirdpartyFilter=Contacts avec filtre client
    +ContactsWithThirdpartyFilter=Contacts with third party filter
    diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
    index b52301bd3fe..fa74cfa44bc 100644
    --- a/htdocs/langs/en_US/main.lang
    +++ b/htdocs/langs/en_US/main.lang
    @@ -50,21 +50,21 @@ ErrorFailedToSendMail=Failed to send mail (sender=%s, receiver=%s)
     ErrorFileNotUploaded=File was not uploaded. Check that size does not exceed maximum allowed, that free space is available on disk and that there is not already a file with same name in this directory.
     ErrorInternalErrorDetected=Error detected
     ErrorWrongHostParameter=Wrong host parameter
    -ErrorYourCountryIsNotDefined=Your country is not defined. Go to Home-Setup-Edit and post again the form.
    -ErrorRecordIsUsedByChild=Failed to delete this record. This record is used by at least one child records.
    +ErrorYourCountryIsNotDefined=Your country is not defined. Go to Home-Setup-Edit and post the form again.
    +ErrorRecordIsUsedByChild=Failed to delete this record. This record is used by at least one child record.
     ErrorWrongValue=Wrong value
     ErrorWrongValueForParameterX=Wrong value for parameter %s
     ErrorNoRequestInError=No request in error
    -ErrorServiceUnavailableTryLater=Service not available for the moment. Try again later.
    +ErrorServiceUnavailableTryLater=Service not available at the moment. Try again later.
     ErrorDuplicateField=Duplicate value in a unique field
    -ErrorSomeErrorWereFoundRollbackIsDone=Some errors were found. We rollback changes.
    -ErrorConfigParameterNotDefined=Parameter <b>%s</b> is not defined inside Dolibarr config file <b>conf.php</b>.
    +ErrorSomeErrorWereFoundRollbackIsDone=Some errors were found. Changes have been rolled back.
    +ErrorConfigParameterNotDefined=Parameter <b>%s</b> is not defined in Dolibarr config file <b>conf.php</b>.
     ErrorCantLoadUserFromDolibarrDatabase=Failed to find user <b>%s</b> in Dolibarr database.
     ErrorNoVATRateDefinedForSellerCountry=Error, no vat rates defined for country '%s'.
     ErrorNoSocialContributionForSellerCountry=Error, no social/fiscal taxes type defined for country '%s'.
     ErrorFailedToSaveFile=Error, failed to save file.
    -ErrorCannotAddThisParentWarehouse=You are trying to add a parent warehouse which is already a child of current one
    -MaxNbOfRecordPerPage=Max number of record per page
    +ErrorCannotAddThisParentWarehouse=You are trying to add a parent warehouse which is already a child of a current one
    +MaxNbOfRecordPerPage=Max number of records per page
     NotAuthorized=You are not authorized to do that.
     SetDate=Set date
     SelectDate=Select a date
    @@ -78,7 +78,7 @@ FileRenamed=The file was successfully renamed
     FileGenerated=The file was successfully generated
     FileSaved=The file was successfully saved
     FileUploaded=The file was successfully uploaded
    -FileTransferComplete=File(s) was uploaded successfully
    +FileTransferComplete=File(s) uploaded successfully
     FilesDeleted=File(s) successfully deleted
     FileWasNotUploaded=A file is selected for attachment but was not yet uploaded. Click on "Attach file" for this.
     NbOfEntries=No. of entries
    @@ -154,7 +154,7 @@ Update=Update
     Close=Close
     CloseBox=Remove widget from your dashboard
     Confirm=Confirm
    -ConfirmSendCardByMail=Do you really want to send content of this card by mail to <b>%s</b>?
    +ConfirmSendCardByMail=Do you really want to send the content of this card by mail to <b>%s</b>?
     Delete=Delete
     Remove=Remove
     Resiliate=Terminate
    @@ -232,7 +232,7 @@ Numero=Number
     Limit=Limit
     Limits=Limits
     Logout=Logout
    -NoLogoutProcessWithAuthMode=No applicative disconnect feature with authentication mode <b>%s</b> 
    +NoLogoutProcessWithAuthMode=No applicative disconnect feature with authentication mode <b>%s</b>
     Connection=Login
     Setup=Setup
     Alert=Alert
    @@ -348,7 +348,7 @@ AmountTTCShort=Amount (inc. tax)
     AmountHT=Amount (net of tax)
     AmountTTC=Amount (inc. tax)
     AmountVAT=Amount tax
    -MulticurrencyAlreadyPaid=Already payed, original currency
    +MulticurrencyAlreadyPaid=Already paid, original currency
     MulticurrencyRemainderToPay=Remain to pay, original currency
     MulticurrencyPaymentAmount=Payment amount, original currency
     MulticurrencyAmountHT=Amount (net of tax), original currency
    @@ -429,7 +429,7 @@ ActionNotApplicable=Not applicable
     ActionRunningNotStarted=To start
     ActionRunningShort=In progress
     ActionDoneShort=Finished
    -ActionUncomplete=Uncomplete
    +ActionUncomplete=Incomplete
     LatestLinkedEvents=Latest %s linked events
     CompanyFoundation=Company/Organization
     Accountant=Accountant
    @@ -445,7 +445,7 @@ Completed=Completed
     Running=In progress
     RequestAlreadyDone=Request already recorded
     Filter=Filter
    -FilterOnInto=Search criteria '<strong>%s</strong>' into fields %s 
    +FilterOnInto=Search criteria '<strong>%s</strong>' into fields %s
     RemoveFilter=Remove filter
     ChartGenerated=Chart generated
     ChartNotGenerated=Chart not generated
    @@ -469,7 +469,7 @@ and=and
     or=or
     Other=Other
     Others=Others
    -OtherInformations=Other informations
    +OtherInformations=Other information
     Quantity=Quantity
     Qty=Qty
     ChangedBy=Changed by
    @@ -507,7 +507,7 @@ None=None
     NoneF=None
     NoneOrSeveral=None or several
     Late=Late
    -LateDesc=Delay to define if a record is late or not depends on your setup. Ask your admin to change delay from menu Home - Setup - Alerts.
    +LateDesc=The delay to define if a record is late or not depends on your setup. Ask your admin to change the delay from menu Home - Setup - Alerts.
     NoItemLate=No late item
     Photo=Picture
     Photos=Pictures
    @@ -531,18 +531,6 @@ September=September
     October=October
     November=November
     December=December
    -JanuaryMin=Jan
    -FebruaryMin=Feb
    -MarchMin=Mar
    -AprilMin=Apr
    -MayMin=May
    -JuneMin=Jun
    -JulyMin=Jul
    -AugustMin=Aug
    -SeptemberMin=Sep
    -OctoberMin=Oct
    -NovemberMin=Nov
    -DecemberMin=Dec
     Month01=January
     Month02=February
     Month03=March
    @@ -671,14 +659,14 @@ Method=Method
     Receive=Receive
     CompleteOrNoMoreReceptionExpected=Complete or nothing more expected
     ExpectedValue=Expected Value
    -CurrentValue=Current Value
    +CurrentValue=Current value
     PartialWoman=Partial
     TotalWoman=Total
     NeverReceived=Never received
     Canceled=Canceled
     YouCanChangeValuesForThisListFromDictionarySetup=You can change values for this list from menu Setup - Dictionaries
     YouCanChangeValuesForThisListFrom=You can change values for this list from menu %s
    -YouCanSetDefaultValueInModuleSetup=You can set the default value used when creating a new record into module setup
    +YouCanSetDefaultValueInModuleSetup=You can set the default value used when creating a new record in module setup
     Color=Color
     Documents=Linked files
     Documents2=Documents
    @@ -704,7 +692,7 @@ DateOfSignature=Date of signature
     HidePassword=Show command with password hidden
     UnHidePassword=Show real command with clear password
     Root=Root
    -Informations=Informations
    +Informations=Information
     Page=Page
     Notes=Notes
     AddNewLine=Add new line
    @@ -717,15 +705,15 @@ Merge=Merge
     DocumentModelStandardPDF=Standard PDF template
     PrintContentArea=Show page to print main content area
     MenuManager=Menu manager
    -WarningYouAreInMaintenanceMode=Warning, you are in a maintenance mode, so only login <b>%s</b> is allowed to use application at the moment.
    +WarningYouAreInMaintenanceMode=Warning, you are in maintenance mode, so only login <b>%s</b> is allowed to use the application at this time.
     CoreErrorTitle=System error
     CoreErrorMessage=Sorry, an error occurred. Contact your system administrator to check the logs or disable $dolibarr_main_prod=1 to get more information.
     CreditCard=Credit card
     ValidatePayment=Validate payment
     CreditOrDebitCard=Credit or debit card
     FieldsWithAreMandatory=Fields with <b>%s</b> are mandatory
    -FieldsWithIsForPublic=Fields with <b>%s</b> are shown on public list of members. If you don't want this, check off the "public" box.
    -AccordingToGeoIPDatabase=(according to GeoIP convertion)
    +FieldsWithIsForPublic=Fields with <b>%s</b> are shown in public list of members. If you don't want this, uncheck the "public" box.
    +AccordingToGeoIPDatabase=(according to GeoIP conversion)
     Line=Line
     NotSupported=Not supported
     RequiredField=Required field
    @@ -733,6 +721,8 @@ Result=Result
     ToTest=Test
     ValidateBefore=Card must be validated before using this feature
     Visibility=Visibility
    +Totalizable=Totalizable
    +TotalizableDesc=This field is totalizable in list
     Private=Private
     Hidden=Hidden
     Resources=Resources
    @@ -760,6 +750,7 @@ LinkToIntervention=Link to intervention
     CreateDraft=Create draft
     SetToDraft=Back to draft
     ClickToEdit=Click to edit
    +ClickToRefresh=Click to refresh
     EditWithEditor=Edit with CKEditor
     EditWithTextEditor=Edit with Text editor
     EditHTMLSource=Edit HTML Source
    @@ -804,7 +795,7 @@ PrintFile=Print File %s
     ShowTransaction=Show entry on bank account
     ShowIntervention=Show intervention
     ShowContract=Show contract
    -GoIntoSetupToChangeLogo=Go into Home - Setup - Company to change logo or go into Home - Setup - Display to hide.
    +GoIntoSetupToChangeLogo=Go to Home - Setup - Company to change logo or go to Home - Setup - Display to hide.
     Deny=Deny
     Denied=Denied
     ListOf=List of %s
    @@ -820,12 +811,12 @@ Sincerely=Sincerely
     DeleteLine=Delete line
     ConfirmDeleteLine=Are you sure you want to delete this line?
     NoPDFAvailableForDocGenAmongChecked=No PDF were available for the document generation among checked record
    -TooManyRecordForMassAction=Too many record selected for mass action. The action is restricted to a list of %s record.
    +TooManyRecordForMassAction=Too many records selected for mass action. The action is restricted to a list of %s records.
     NoRecordSelected=No record selected
     MassFilesArea=Area for files built by mass actions
     ShowTempMassFilesArea=Show area of files built by mass actions
    -ConfirmMassDeletion=Bulk delete confirmation
    -ConfirmMassDeletionQuestion=Are you sure you want to delete the %s selected record ?
    +ConfirmMassDeletion=Mass delete confirmation
    +ConfirmMassDeletionQuestion=Are you sure you want to delete the %s selected record?
     RelatedObjects=Related Objects
     ClassifyBilled=Classify billed
     ClassifyUnbilled=Classify unbilled
    @@ -843,7 +834,7 @@ Calendar=Calendar
     GroupBy=Group by...
     ViewFlatList=View flat list
     RemoveString=Remove string '%s'
    -SomeTranslationAreUncomplete=Some languages may be partially translated or may contains errors. If you detect some, you can fix language files registering to <a href="https://transifex.com/projects/p/dolibarr/" target="_blank">https://transifex.com/projects/p/dolibarr/</a>. 
    +SomeTranslationAreUncomplete=Some of the languages offered may be only partially translated or may contain errors. Please help to correct your language by registering at <a href="https://transifex.com/projects/p/dolibarr/" target="_blank">https://transifex.com/projects/p/dolibarr/</a> to add your improvements.
     DirectDownloadLink=Direct download link (public/external)
     DirectDownloadInternalLink=Direct download link (need to be logged and need permissions)
     Download=Download
    @@ -863,16 +854,25 @@ HR=HR
     HRAndBank=HR and Bank
     AutomaticallyCalculated=Automatically calculated
     TitleSetToDraft=Go back to draft
    -ConfirmSetToDraft=Are you sure you want to go back to Draft status ?
    +ConfirmSetToDraft=Are you sure you want to go back to Draft status?
     ImportId=Import id
     Events=Events
     EMailTemplates=Email templates
    -FileNotShared=File not shared to exernal public
    +FileNotShared=File not shared to external public
     Project=Project
     Projects=Projects
    +LeadOrProject=Lead | Project
    +LeadsOrProjects=Leads | Projects
    +Lead=Lead
    +Leads=Leads
    +ListOpenLeads=List open leads
    +ListOpenProjects=List open projects
    +NewLeadOrProject=New lead or project
     Rights=Permissions
     LineNb=Line no.
     IncotermLabel=Incoterms
    +TabLetteringCustomer=Customer lettering
    +TabLetteringSupplier=Supplier lettering
     # Week day
     Monday=Monday
     Tuesday=Tuesday
    @@ -929,15 +929,15 @@ SearchIntoInterventions=Interventions
     SearchIntoContracts=Contracts
     SearchIntoCustomerShipments=Customer shipments
     SearchIntoExpenseReports=Expense reports
    -SearchIntoLeaves=Leaves
    +SearchIntoLeaves=Leave
     CommentLink=Comments
     NbComments=Number of comments
     CommentPage=Comments space
     CommentAdded=Comment added
     CommentDeleted=Comment deleted
     Everybody=Everybody
    -PayedBy=Payed by
    -PayedTo=Payed to
    +PayedBy=Paid by
    +PayedTo=Paid to
     Monthly=Monthly
     Quarterly=Quarterly
     Annual=Annual
    @@ -947,6 +947,7 @@ LocalAndRemote=Local and Remote
     KeyboardShortcut=Keyboard shortcut
     AssignedTo=Assigned to
     Deletedraft=Delete draft
    -ConfirmMassDraftDeletion=Draft Bulk delete confirmation
    +ConfirmMassDraftDeletion=Draft mass delete confirmation
     FileSharedViaALink=File shared via a link
     SelectAThirdPartyFirst=Select a third party first...
    +YouAreCurrentlyInSandboxMode=You are currently in the %s "sandbox" mode
    diff --git a/htdocs/langs/en_US/margins.lang b/htdocs/langs/en_US/margins.lang
    index b9d52dcfdc6..167e316703c 100644
    --- a/htdocs/langs/en_US/margins.lang
    +++ b/htdocs/langs/en_US/margins.lang
    @@ -41,4 +41,4 @@ rateMustBeNumeric=Rate must be a numeric value
     markRateShouldBeLesserThan100=Mark rate should be lower than 100
     ShowMarginInfos=Show margin infos
     CheckMargins=Margins detail
    -MarginPerSaleRepresentativeWarning=The report of margin per user use the link between third parties and sale representatives to calculate the margin of each sale representative. Because some thirdparties may not have any ddiated sale representative and some thirdparties may be linked to several, some amounts may not be included into this report (if there is no sale representative) and some may appear on different lines (for each sale representative).
    +MarginPerSaleRepresentativeWarning=The report of margin per user use the link between third parties and sale representatives to calculate the margin of each sale representative. Because some thirdparties may not have any dedicated sale representative and some third parties may be linked to several, some amounts may not be included into this report (if there is no sale representative) and some may appear on different lines (for each sale representative).
    diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang
    index b74ad44b45f..e28f242d964 100644
    --- a/htdocs/langs/en_US/members.lang
    +++ b/htdocs/langs/en_US/members.lang
    @@ -33,7 +33,7 @@ DateSubscription=Subscription date
     DateEndSubscription=Subscription end date
     EndSubscription=End subscription
     SubscriptionId=Subscription id
    -MemberId=Member id 
    +MemberId=Member id
     NewMember=New member
     MemberType=Member type
     MemberTypeId=Member type id
    @@ -61,7 +61,7 @@ ConfirmDeleteMemberType=Are you sure you want to delete this member type?
     MemberTypeDeleted=Member type deleted
     MemberTypeCanNotBeDeleted=Member type can not be deleted
     NewSubscription=New subscription
    -NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s. 
    +NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s.
     Subscription=Subscription
     Subscriptions=Subscriptions
     SubscriptionLate=Late
    @@ -88,7 +88,7 @@ ConfirmDeleteSubscription=Are you sure you want to delete this subscription?
     Filehtpasswd=htpasswd file
     ValidateMember=Validate a member
     ConfirmValidateMember=Are you sure you want to validate this member?
    -FollowingLinksArePublic=The following links are open pages not protected by any Dolibarr permission. They are not formated pages, provided as example to show how to list members database. 
    +FollowingLinksArePublic=The following links are open pages not protected by any Dolibarr permission. They are not formatted pages, provided as example to show how to list members database.
     PublicMemberList=Public member list
     BlankSubscriptionForm=Public self-subscription form
     BlankSubscriptionFormDesc=Dolibarr can provide you a public URL/website to allow external visitors to ask to subscribe to the foundation. If an online payment module is enabled, a payment form may also be automatically provided.
    @@ -115,7 +115,7 @@ SendingReminderForExpiredSubscription=Sending reminder for expired subscriptions
     SendingEmailOnCancelation=Sending email on cancelation
     # Topic of email templates
     YourMembershipRequestWasReceived=Your membership was received.
    -YourMembershipWasValidated=Your membership was validated 
    +YourMembershipWasValidated=Your membership was validated
     YourSubscriptionWasRecorded=Your new subscription was recorded
     SubscriptionReminderEmail=Subscription reminder
     YourMembershipWasCanceled=Your membership was canceled
    @@ -125,7 +125,7 @@ ThisIsContentOfYourMembershipRequestWasReceived=We want to let you know that you
     ThisIsContentOfYourMembershipWasValidated=We want to let you know that your membership was validated with the following information:<br><br>
     ThisIsContentOfYourSubscriptionWasRecorded=We want to let you know that your new subscription was recorded.<br><br>
     ThisIsContentOfSubscriptionReminderEmail=We want to let you know that your subscription is about to expire or is already expired (__MEMBER_LAST_SUBSCRIPTION_DATE_END__). We hope you can make a renewal of it.<br><br>
    -ThisIsContentOfYourCard=This is a remind of the information we get about you. Feel free to contact us if something looks wrong.<br><br> 
    +ThisIsContentOfYourCard=This is a remind of the information we get about you. Feel free to contact us if something looks wrong.<br><br>
     DescADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT=Subject of the e-mail received in case of auto-inscription of a guest
     DescADHERENT_AUTOREGISTER_NOTIF_MAIL=E-mail received in case of auto-inscription of a guest
     DescADHERENT_EMAIL_TEMPLATE_AUTOREGISTER=Template Email to use to send email to a member on member autosubscription
    diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang
    index 6638e1fa674..6aef75a5746 100644
    --- a/htdocs/langs/en_US/modulebuilder.lang
    +++ b/htdocs/langs/en_US/modulebuilder.lang
    @@ -1,10 +1,10 @@
     # Dolibarr language file - Source file is en_US - loan
    -ModuleBuilderDesc=This tools must be used by experienced users or developers. It gives you utilities to build or edit your own module (Documentation for alternative <a href="%s" target="_blank">manual development is here</a>).
    +ModuleBuilderDesc=This tool must be used by only by experienced users or developers. It gives you utilities to build or edit your own module.<br>Documentation for alternative <a href="%s" target="_blank">manual development is here</a>.
     EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...)
     EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated.
     ModuleBuilderDesc2=Path where modules are generated/edited (first alternative directory defined into %s): <strong>%s</strong>
     ModuleBuilderDesc3=Generated/editable modules found: <strong>%s</strong>
    -ModuleBuilderDesc4=A module is detected as 'editable' when the file <strong>%s</strong> exists in root of module directory 
    +ModuleBuilderDesc4=A module is detected as 'editable' when the file <strong>%s</strong> exists in root of module directory
     NewModule=New module
     NewObject=New object
     ModuleKey=Module key
    @@ -13,7 +13,7 @@ ModuleInitialized=Module initialized
     FilesForObjectInitialized=Files for new object '%s' initialized
     FilesForObjectUpdated=Files for object '%s' updated (.sql files and .class.php file)
     ModuleBuilderDescdescription=Enter here all general information that describe your module.
    -ModuleBuilderDescspecifications=You can enter here a long text to describe the specifications of your module that is not already structured into other tabs. So you have within easy reach all the rules to develop. Also this text content will be included into the generated documentation (see last tab). You can use Markdown format, but it is recommanded to use Asciidoc format (Comparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown)
    +ModuleBuilderDescspecifications=You can enter here a detailed description of the specifications of your module that is not already structured into other tabs. So you have within easy reach all the rules to develop. Also this text content will be included into the generated documentation (see last tab). You can use Markdown format, but it is recommended to use Asciidoc format (comparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown).
     ModuleBuilderDescobjects=Define here the objects you want to manage with your module. A CRUD DAO class, SQL files, page to list record of objects, to create/edit/view a record and an API will be generated.
     ModuleBuilderDescmenus=This tab is dedicated to define menu entries provided by your module.
     ModuleBuilderDescpermissions=This tab is dedicated to define the new permissions you want to provide with your module.
    @@ -21,12 +21,12 @@ ModuleBuilderDesctriggers=This is the view of triggers provided by your module.
     ModuleBuilderDeschooks=This tab is dedicated to hooks.
     ModuleBuilderDescwidgets=This tab is dedicated to manage/build widgets.
     ModuleBuilderDescbuildpackage=You can generate here a "ready to distribute" package file (a normalized .zip file) of your module and a "ready to distribute" documentation file. Just click on button to build the package or documentation file.
    -EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: All files of module but also structured data and documentation will be definitly lost !
    -EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All files related to object will be definitly lost !
    +EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: ALL files of module AND structured data and documentation will be deleted!
    +EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All files related to object will be deleted!
     DangerZone=Danger zone
     BuildPackage=Build package/documentation
     BuildDocumentation=Build documentation
    -ModuleIsNotActive=This module was not activated yet. Go into %s to make it live or click here:
    +ModuleIsNotActive=This module is not activated yet. Go to %s to make it live or click here:
     ModuleIsLive=This module has been activated. Any change on it may break a current active feature.
     DescriptionLong=Long description
     EditorName=Name of editor
    @@ -47,9 +47,9 @@ RegenerateClassAndSql=Erase and regenerate class and sql files
     RegenerateMissingFiles=Generate missing files
     SpecificationFile=File with business rules
     LanguageFile=File for language
    -ConfirmDeleteProperty=Are you sure you want to delete the property <strong>%s</strong> ? This will change code in PHP class but also remove column from table definition of object.
    +ConfirmDeleteProperty=Are you sure you want to delete the property <strong>%s</strong>? This will change code in PHP class but also remove column from table definition of object.
     NotNull=Not NULL
    -NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0). 
    +NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0).
     SearchAll=Used for 'search all'
     DatabaseIndex=Database index
     FileAlreadyExists=File %s already exists
    @@ -66,7 +66,7 @@ PageForLib=File for PHP libraries
     SqlFileExtraFields=Sql file for complementary attributes
     SqlFileKey=Sql file for keys
     AnObjectAlreadyExistWithThisNameAndDiffCase=An object already exists with this name and a different case
    -UseAsciiDocFormat=You can use Markdown format, but it is recommanded to use Asciidoc format (Comparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown)
    +UseAsciiDocFormat=You can use Markdown format, but it is recommended to use Asciidoc format (omparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown)
     IsAMeasure=Is a measure
     DirScanned=Directory scanned
     NoTrigger=No trigger
    @@ -74,10 +74,11 @@ NoWidget=No widget
     GoToApiExplorer=Go to API explorer
     ListOfMenusEntries=List of menu entries
     ListOfPermissionsDefined=List of defined permissions
    +SeeExamples=See examples here
     EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION)
     VisibleDesc=Is the field visible ? (Examples: 0=Never visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only. Using a negative value means field is not shown by default on list but can be selected for viewing)
    -IsAMeasureDesc=Can the value of field be cumulated to get a total into list ? (Examples: 1 or 0)
    -SearchAllDesc=Is the field used to make a search from the quick search tool ? (Examples: 1 or 0)
    +IsAMeasureDesc=Can the value of field be cumulated to get a total into list? (Examples: 1 or 0)
    +SearchAllDesc=Is the field used to make a search from the quick search tool? (Examples: 1 or 0)
     SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax.
     LanguageDefDesc=Enter in this files, all the key and the translation for each language file.
     MenusDefDesc=Define here the menus provided by your module (once defined, they are visible into the menu editor %s)
    @@ -87,11 +88,15 @@ TriggerDefDesc=Define in the trigger file the code you want to execute for each
     SeeIDsInUse=See IDs in use in your installation
     SeeReservedIDsRangeHere=See range of reserved IDs
     ToolkitForDevelopers=Toolkit for Dolibarr developers
    -TryToUseTheModuleBuilder=If you have knowledge in SQL and PHP, you can try to use the native module builder wizard. Just enable the module and use the wizard by clicking the <span class="fa fa-bug"></span> on the top right menu. Warning: This is a developer feature, bad use may breaks your application.
    +TryToUseTheModuleBuilder=If you have knowledge of SQL and PHP, you may use the native module builder wizard.<br>Enable the module <strong>%s</strong> and use the wizard by clicking the <span class="fa fa-bug"></span> on the top right menu.<br>Warning: This is an advanced developer feature, do <b>not</b> experiment on your production site!
     SeeTopRightMenu=See <span class="fa fa-bug"></span> on the top right menu
     AddLanguageFile=Add language file
     YouCanUseTranslationKey=You can use here a key that is the translation key found into language file (see tab "Languages")
     DropTableIfEmpty=(Delete table if empty)
     TableDoesNotExists=The table %s does not exists
     TableDropped=Table %s deleted
    -InitStructureFromExistingTable=Build the structure array string of an existing table 
    \ No newline at end of file
    +InitStructureFromExistingTable=Build the structure array string of an existing table
    +UseAboutPage=Disable the about page
    +UseDocFolder=Disable the documentation folder
    +UseSpecificReadme=Use a specific ReadMe
    +RealPathOfModule=Real path of module
    diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang
    index 0da2ee58b60..47c5590b862 100644
    --- a/htdocs/langs/en_US/multicurrency.lang
    +++ b/htdocs/langs/en_US/multicurrency.lang
    @@ -3,18 +3,18 @@ MultiCurrency=Multi currency
     ErrorAddRateFail=Error in added rate
     ErrorAddCurrencyFail=Error in added currency
     ErrorDeleteCurrencyFail=Error delete fail
    -multicurrency_syncronize_error=Synchronisation error: %s
    -MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE=Use date of document to find currency rate, instead of using latest known rate 
    -multicurrency_useOriginTx=When an object is created from another, keep the original rate of source object (otherwise use the latest known rate)
    +multicurrency_syncronize_error=Synchronization error: %s
    +MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE=Use the date of the document to find the currency rate, instead of using the latest known rate
    +multicurrency_useOriginTx=When an object is created from another, keep the original rate from the source object (otherwise use the latest known rate)
     CurrencyLayerAccount=CurrencyLayer API
    -CurrencyLayerAccount_help_to_synchronize=You sould create an account on their website to use this functionnality<br>Get your <b>API key</b><br>If you use a free account you can't change the <b>currency source</b> (USD by default)<br>But if your main currency isn't USD you can use the <b>alternate currency source</b> to force you main currency<br><br>You are limited at 1000 synchronizations per month 
    +CurrencyLayerAccount_help_to_synchronize=You must create an account on their website to use this functionality.<br>Get your <b>API key</b>.<br>If you use a free account you can't change the <b>currency source</b> (USD by default).<br>If your main currency is not USD you can use the <b>alternate currency source</b> to force your main currency.<br><br>You are limited to 1000 synchronizations per month.
     multicurrency_appId=API key
     multicurrency_appCurrencySource=Currency source
     multicurrency_alternateCurrencySource=Alternate currency source
     CurrenciesUsed=Currencies used
    -CurrenciesUsed_help_to_add=Add the differents currencies and rates you need to use on you <b>proposals</b>, <b>orders</b>, etc.
    +CurrenciesUsed_help_to_add=Add the different currencies and rates you need to use on your <b>proposals</b>, <b>orders</b> etc.
     rate=rate
     MulticurrencyReceived=Received, original currency
    -MulticurrencyRemainderToTake=Remaining amout, original currency
    +MulticurrencyRemainderToTake=Remaining amount, original currency
     MulticurrencyPaymentAmount=Payment amount, original currency
    -AmountToOthercurrency=Amount To (in currency of receiving account)
    \ No newline at end of file
    +AmountToOthercurrency=Amount To (in currency of receiving account)
    diff --git a/htdocs/langs/en_US/opensurvey.lang b/htdocs/langs/en_US/opensurvey.lang
    index 0203bf74b28..906de8c2f37 100644
    --- a/htdocs/langs/en_US/opensurvey.lang
    +++ b/htdocs/langs/en_US/opensurvey.lang
    @@ -11,7 +11,7 @@ PollTitle=Poll title
     ToReceiveEMailForEachVote=Receive an email for each vote
     TypeDate=Type date
     TypeClassic=Type standard
    -OpenSurveyStep2=Select your dates amoung the free days (grey). The selected days are green. You can unselect a day previously selected by clicking again on it
    +OpenSurveyStep2=Select your dates among the free days (grey). The selected days are green. You can unselect a day previously selected by clicking again on it
     RemoveAllDays=Remove all days
     CopyHoursOfFirstDay=Copy hours of first day
     RemoveAllHours=Remove all hours
    @@ -19,7 +19,7 @@ SelectedDays=Selected days
     TheBestChoice=The best choice currently is
     TheBestChoices=The best choices currently are
     with=with
    -OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line. 
    +OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.
     CommentsOfVoters=Comments of voters
     ConfirmRemovalOfPoll=Are you sure you want to remove this poll (and all votes)
     RemovePoll=Remove poll
    @@ -58,4 +58,4 @@ MoreChoices=Enter more choices for the voters
     SurveyExpiredInfo=The poll has been closed or voting delay has expired.
     EmailSomeoneVoted=%s has filled a line.\nYou can find your poll at the link: \n%s
     ShowSurvey=Show survey
    -UserMustBeSameThanUserUsedToVote=You must have voted and use the same user name that the one used to vote, to post a comment
    \ No newline at end of file
    +UserMustBeSameThanUserUsedToVote=You must have voted and use the same user name that the one used to vote, to post a comment
    diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang
    index 94ed74acb4e..66073b8f0c9 100644
    --- a/htdocs/langs/en_US/orders.lang
    +++ b/htdocs/langs/en_US/orders.lang
    @@ -56,7 +56,7 @@ StatusOrderReceivedAll=All products received
     ShippingExist=A shipment exists
     QtyOrdered=Qty ordered
     ProductQtyInDraft=Product quantity into draft orders
    -ProductQtyInDraftOrWaitingApproved=Product quantity into draft or approved orders, not yet ordered 
    +ProductQtyInDraftOrWaitingApproved=Product quantity into draft or approved orders, not yet ordered
     MenuOrdersToBill=Orders delivered
     MenuOrdersToBill2=Billable orders
     ShipProduct=Ship product
    @@ -88,7 +88,7 @@ NumberOfOrdersByMonth=Number of orders by month
     AmountOfOrdersByMonthHT=Amount of orders by month (net of tax)
     ListOfOrders=List of orders
     CloseOrder=Close order
    -ConfirmCloseOrder=Are you sure you want to set this order to deliverd? Once an order is delivered, it can be set to billed.
    +ConfirmCloseOrder=Are you sure you want to set this order to delivered? Once an order is delivered, it can be set to billed.
     ConfirmDeleteOrder=Are you sure you want to delete this order?
     ConfirmValidateOrder=Are you sure you want to validate this order under name <b>%s</b>?
     ConfirmUnvalidateOrder=Are you sure you want to restore order <b>%s</b> to draft status?
    @@ -116,7 +116,7 @@ DispatchSupplierOrder=Receiving supplier order %s
     FirstApprovalAlreadyDone=First approval already done
     SecondApprovalAlreadyDone=Second approval already done
     SupplierOrderReceivedInDolibarr=Purchase Order %s received %s
    -SupplierOrderSubmitedInDolibarr=Purchase Order %s submited
    +SupplierOrderSubmitedInDolibarr=Purchase Order %s submitted
     SupplierOrderClassifiedBilled=Purchase Order %s set billed
     OtherOrders=Other orders
     ##### Types de contacts #####
    @@ -141,18 +141,19 @@ OrderByWWW=Online
     OrderByPhone=Phone
     # Documents models
     PDFEinsteinDescription=A complete order model (logo...)
    +PDFEratostheneDescription=A complete order model (logo...)
     PDFEdisonDescription=A simple order model
     PDFProformaDescription=A complete proforma invoice (logo…)
     CreateInvoiceForThisCustomer=Bill orders
     NoOrdersToInvoice=No orders billable
    -CloseProcessedOrdersAutomatically=Classify "Processed" all selected orders. 
    +CloseProcessedOrdersAutomatically=Classify "Processed" all selected orders.
     OrderCreation=Order creation
     Ordered=Ordered
     OrderCreated=Your orders have been created
     OrderFail=An error happened during your orders creation
     CreateOrders=Create orders
     ToBillSeveralOrderSelectCustomer=To create an invoice for several orders, click first onto customer, then choose "%s".
    -OptionToSetOrderBilledNotEnabled=Option (from module Workflow) to set order to 'Billed' automatically when invoice is validated is off, so you will have to set status of order to 'Billed' manually.  
    +OptionToSetOrderBilledNotEnabled=Option (from module Workflow) to set order to 'Billed' automatically when invoice is validated is off, so you will have to set status of order to 'Billed' manually.
     IfValidateInvoiceIsNoOrderStayUnbilled=If invoice validation is 'No', the order will remain to status 'Unbilled' until the invoice is validated.
     CloseReceivedSupplierOrdersAutomatically=Close order to "%s" automatically if all products are received.
    -SetShippingMode=Set shipping mode
    \ No newline at end of file
    +SetShippingMode=Set shipping mode
    diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang
    index f6bb3e76e95..91442bbd05d 100644
    --- a/htdocs/langs/en_US/other.lang
    +++ b/htdocs/langs/en_US/other.lang
    @@ -23,7 +23,7 @@ MessageForm=Message on online payment form
     MessageOK=Message on validated payment return page
     MessageKO=Message on canceled payment return page
     ContentOfDirectoryIsNotEmpty=Content of this directory is not empty.
    -DeleteAlsoContentRecursively=Check to delete all content recursiveley
    +DeleteAlsoContentRecursively=Check to delete all content recursively
     
     YearOfInvoice=Year of invoice date
     PreviousYearOfInvoice=Previous year of invoice date
    @@ -31,9 +31,6 @@ NextYearOfInvoice=Following year of invoice date
     DateNextInvoiceBeforeGen=Date of next invoice (before generation)
     DateNextInvoiceAfterGen=Date of next invoice (after generation)
     
    -Notify_FICHINTER_ADD_CONTACT=Added contact to Intervention
    -Notify_FICHINTER_VALIDATE=Intervention validated
    -Notify_FICHINTER_SENTBYMAIL=Intervention sent by mail
     Notify_ORDER_VALIDATE=Customer order validated
     Notify_ORDER_SENTBYMAIL=Customer order sent by mail
     Notify_ORDER_SUPPLIER_SENTBYMAIL=Supplier order sent by mail
    @@ -41,8 +38,8 @@ Notify_ORDER_SUPPLIER_VALIDATE=Supplier order recorded
     Notify_ORDER_SUPPLIER_APPROVE=Supplier order approved
     Notify_ORDER_SUPPLIER_REFUSE=Supplier order refused
     Notify_PROPAL_VALIDATE=Customer proposal validated
    -Notify_PROPAL_CLOSE_SIGNED=Customer propal closed signed
    -Notify_PROPAL_CLOSE_REFUSED=Customer propal closed refused
    +Notify_PROPAL_CLOSE_SIGNED=Customer proposal closed signed
    +Notify_PROPAL_CLOSE_REFUSED=Customer proposal closed refused
     Notify_PROPAL_SENTBYMAIL=Commercial proposal sent by mail
     Notify_WITHDRAW_TRANSMIT=Transmission withdrawal
     Notify_WITHDRAW_CREDIT=Credit withdrawal
    @@ -51,15 +48,17 @@ Notify_COMPANY_CREATE=Third party created
     Notify_COMPANY_SENTBYMAIL=Mails sent from third party card
     Notify_BILL_VALIDATE=Customer invoice validated
     Notify_BILL_UNVALIDATE=Customer invoice unvalidated
    -Notify_BILL_PAYED=Customer invoice payed
    +Notify_BILL_PAYED=Customer invoice paid
     Notify_BILL_CANCEL=Customer invoice canceled
     Notify_BILL_SENTBYMAIL=Customer invoice sent by mail
     Notify_BILL_SUPPLIER_VALIDATE=Supplier invoice validated
    -Notify_BILL_SUPPLIER_PAYED=Supplier invoice payed
    +Notify_BILL_SUPPLIER_PAYED=Supplier invoice paid
     Notify_BILL_SUPPLIER_SENTBYMAIL=Supplier invoice sent by mail
     Notify_BILL_SUPPLIER_CANCELED=Supplier invoice cancelled
     Notify_CONTRACT_VALIDATE=Contract validated
     Notify_FICHEINTER_VALIDATE=Intervention validated
    +Notify_FICHINTER_ADD_CONTACT=Added contact to Intervention
    +Notify_FICHINTER_SENTBYMAIL=Intervention sent by mail
     Notify_SHIPPING_VALIDATE=Shipping validated
     Notify_SHIPPING_SENTBYMAIL=Shipping sent by mail
     Notify_MEMBER_VALIDATE=Member validated
    @@ -71,6 +70,10 @@ Notify_PROJECT_CREATE=Project creation
     Notify_TASK_CREATE=Task created
     Notify_TASK_MODIFY=Task modified
     Notify_TASK_DELETE=Task deleted
    +Notify_EXPENSE_REPORT_VALIDATE=Expense report validated (approval required)
    +Notify_EXPENSE_REPORT_APPROVE=Expense report approved
    +Notify_HOLIDAY_VALIDATE=Leave request validated (approval required)
    +Notify_HOLIDAY_APPROVE=Leave request approved
     SeeModuleSetup=See setup of module %s
     NbOfAttachedFiles=Number of attached files/documents
     TotalSizeOfAttachedFiles=Total size of attached files/documents
    @@ -80,15 +83,15 @@ LinkedObject=Linked object
     NbOfActiveNotifications=Number of notifications (no. of recipient emails)
     PredefinedMailTest=__(Hello)__\nThis is a test mail sent to __EMAIL__.\nThe two lines are separated by a carriage return.\n\n__USER_SIGNATURE__
     PredefinedMailTestHtml=__(Hello)__\nThis is a <b>test</b> mail (the word test must be in bold).<br>The two lines are separated by a carriage return.<br><br>__USER_SIGNATURE__
    -PredefinedMailContentSendInvoice=__(Hello)__\n\nYou will find here the invoice __REF__\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendInvoiceReminder=__(Hello)__\n\nWe would like to warn you that the invoice  __REF__ seems to not be payed. So this is the invoice in attachment again, as a reminder.\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendProposal=__(Hello)__\n\nYou will find here the commercial proposal __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendSupplierProposal=__(Hello)__\n\nYou will find here the price request __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendOrder=__(Hello)__\n\nYou will find here the order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nYou will find here our order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendSupplierInvoice=__(Hello)__\n\nYou will find here the invoice __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendShipping=__(Hello)__\n\nYou will find here the shipping __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendFichInter=__(Hello)__\n\nYou will find here the intervention __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendInvoice=__(Hello)__\n\nPlease find attached invoice __REF__\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendInvoiceReminder=__(Hello)__\n\nWe would like to warn you that the invoice  __REF__ seems to have not been paid. The invoice is attached, as a reminder.\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendProposal=__(Hello)__\n\nPlease find attached commercial proposal __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendSupplierProposal=__(Hello)__\n\nPlease find attached price request __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendOrder=__(Hello)__\n\nPlease find attached order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nPlease find attached our order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendSupplierInvoice=__(Hello)__\n\nPlease find attached invoice __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendShipping=__(Hello)__\n\nPlease find attached shipping __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendFichInter=__(Hello)__\n\nPlease find attached intervention __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
     PredefinedMailContentThirdparty=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
     PredefinedMailContentUser=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
     PredefinedMailContentLink=You can click on the link below to make your payment if it is not already done.\n\n%s\n\n
    @@ -185,10 +188,10 @@ NumberOfUnitsCustomerInvoices=Number of units on customer invoices
     NumberOfUnitsSupplierProposals=Number of units on supplier proposals
     NumberOfUnitsSupplierOrders=Number of units on supplier orders
     NumberOfUnitsSupplierInvoices=Number of units on supplier invoices
    -EMailTextInterventionAddedContact=A newintervention %s has been assigned to you.
    +EMailTextInterventionAddedContact=A new intervention %s has been assigned to you.
     EMailTextInterventionValidated=The intervention %s has been validated.
     EMailTextInvoiceValidated=The invoice %s has been validated.
    -EMailTextInvoicePayed=The invoice %s has been payed.
    +EMailTextInvoicePayed=The invoice %s has been paid.
     EMailTextProposalValidated=The proposal %s has been validated.
     EMailTextProposalClosedSigned=The proposal %s has been closed signed.
     EMailTextOrderValidated=The order %s has been validated.
    @@ -198,6 +201,10 @@ EMailTextOrderApprovedBy=The order %s has been approved by %s.
     EMailTextOrderRefused=The order %s has been refused.
     EMailTextOrderRefusedBy=The order %s has been refused by %s.
     EMailTextExpeditionValidated=The shipping %s has been validated.
    +EMailTextExpenseReportValidated=The expense report %s has been validated.
    +EMailTextExpenseReportApproved=The expensereport %s has been approved.
    +EMailTextHolidayValidated=The leave request %s has been validated.
    +EMailTextHolidayApproved=The leave request %s has been approved.
     ImportedWithSet=Importation data set
     DolibarrNotification=Automatic notification
     ResizeDesc=Enter new width <b>OR</b> new height. Ratio will be kept during resizing...
    @@ -205,7 +212,7 @@ NewLength=New width
     NewHeight=New height
     NewSizeAfterCropping=New size after cropping
     DefineNewAreaToPick=Define new area on image to pick (left click on image then drag until you reach the opposite corner)
    -CurrentInformationOnImage=This tool was designed to help you to resize or crop an image. This is informations on current edited image
    +CurrentInformationOnImage=This tool was designed to help you to resize or crop an image. This is the information on the current edited image
     ImageEditor=Image editor
     YouReceiveMailBecauseOfNotification=You receive this message because your email has been added to list of targets to be informed of particular events into %s software of %s.
     YouReceiveMailBecauseOfNotification2=This event is the following:
    @@ -236,6 +243,7 @@ YourPasswordMustHaveAtLeastXChars=Your password must have at least <strong>%s</s
     YourPasswordHasBeenReset=Your password has been reset successfully
     ApplicantIpAddress=IP address of applicant
     SMSSentTo=SMS sent to %s
    +MissingIds=Missing ids
     
     ##### Export #####
     ExportsArea=Exports area
    diff --git a/htdocs/langs/en_US/paybox.lang b/htdocs/langs/en_US/paybox.lang
    index e87c7058121..cf0bd40b716 100644
    --- a/htdocs/langs/en_US/paybox.lang
    +++ b/htdocs/langs/en_US/paybox.lang
    @@ -21,9 +21,9 @@ ToOfferALinkForOnlinePaymentOnContractLine=URL to offer a %s online payment user
     ToOfferALinkForOnlinePaymentOnFreeAmount=URL to offer a %s online payment user interface for a free amount
     ToOfferALinkForOnlinePaymentOnMemberSubscription=URL to offer a %s online payment user interface for a member subscription
     YouCanAddTagOnUrl=You can also add url parameter <b>&tag=<i>value</i></b> to any of those URL (required only for free payment) to add your own payment comment tag.
    -SetupPayBoxToHavePaymentCreatedAutomatically=Setup your PayBox with url <b>%s</b> to have payment created automatically when validated by paybox. 
    +SetupPayBoxToHavePaymentCreatedAutomatically=Setup your Paybox with url <b>%s</b> to have payment created automatically when validated by Paybox.
     YourPaymentHasBeenRecorded=This page confirms that your payment has been recorded. Thank you.
    -YourPaymentHasNotBeenRecorded=You payment has NOT been recorded and transaction has been canceled. Thank you.
    +YourPaymentHasNotBeenRecorded=Your payment has NOT been recorded and the transaction has been canceled. Thank you.
     AccountParameter=Account parameters
     UsageParameter=Usage parameters
     InformationToFindParameters=Help to find your %s account information
    @@ -35,4 +35,4 @@ NewPayboxPaymentFailed=New Paybox payment tried but failed
     PAYBOX_PAYONLINE_SENDEMAIL=EMail to warn after a payment (success or failed)
     PAYBOX_PBX_SITE=Value for PBX SITE
     PAYBOX_PBX_RANG=Value for PBX Rang
    -PAYBOX_PBX_IDENTIFIANT=Value for PBX ID
    \ No newline at end of file
    +PAYBOX_PBX_IDENTIFIANT=Value for PBX ID
    diff --git a/htdocs/langs/en_US/paypal.lang b/htdocs/langs/en_US/paypal.lang
    index ad8b9612935..d34bb4baf18 100644
    --- a/htdocs/langs/en_US/paypal.lang
    +++ b/htdocs/langs/en_US/paypal.lang
    @@ -1,25 +1,24 @@
     # Dolibarr language file - Source file is en_US - paypal
     PaypalSetup=PayPal module setup
    -PaypalDesc=This module offer pages to allow payment on <a href="http://www.paypal.com" target="_blank">PayPal</a> by customers. This can be used for a free payment or for a payment on a particular Dolibarr object (invoice, order, ...)
    -PaypalOrCBDoPayment=Pay with Paypal (Credit Card or Paypal)
    -PaypalDoPayment=Pay with Paypal
    +PaypalDesc=This module allows payment on <a href="http://www.paypal.com" target="_blank">PayPal</a> by customers. This can be used for a free payment or for a payment on a particular Dolibarr object (invoice, order, ...)
    +PaypalOrCBDoPayment=Pay with PayPal (Credit Card or PayPal)
    +PaypalDoPayment=Pay with PayPal
     PAYPAL_API_SANDBOX=Mode test/sandbox
     PAYPAL_API_USER=API username
     PAYPAL_API_PASSWORD=API password
     PAYPAL_API_SIGNATURE=API signature
     PAYPAL_SSLVERSION=Curl SSL Version
    -PAYPAL_API_INTEGRAL_OR_PAYPALONLY=Offer payment "integral" (Credit card+Paypal) or "Paypal" only
    +PAYPAL_API_INTEGRAL_OR_PAYPALONLY=Offer payment "integral" (Credit card+PayPal) or "PayPal" only
     PaypalModeIntegral=Integral
     PaypalModeOnlyPaypal=PayPal only
    -ONLINE_PAYMENT_CSS_URL=Optionnal URL of CSS style sheet on online payment page
    +ONLINE_PAYMENT_CSS_URL=Optional URL of CSS stylesheet on online payment page
     ThisIsTransactionId=This is id of transaction: <b>%s</b>
    -PAYPAL_ADD_PAYMENT_URL=Add the url of Paypal payment when you send a document by mail
    -YouAreCurrentlyInSandboxMode=You are currently in the %s "sandbox" mode
    +PAYPAL_ADD_PAYMENT_URL=Add the url of PayPal payment when you send a document by mail
     NewOnlinePaymentReceived=New online payment received
     NewOnlinePaymentFailed=New online payment tried but failed
     ONLINE_PAYMENT_SENDEMAIL=EMail to warn after a payment (success or not)
     ReturnURLAfterPayment=Return URL after payment
    -ValidationOfOnlinePaymentFailed=Validation of online payment failed 
    +ValidationOfOnlinePaymentFailed=Validation of online payment failed
     PaymentSystemConfirmPaymentPageWasCalledButFailed=Payment confirmation page was called by payment system returned an error
     SetExpressCheckoutAPICallFailed=SetExpressCheckout API call failed.
     DoExpressCheckoutPaymentAPICallFailed=DoExpressCheckoutPayment API call failed.
    @@ -28,8 +27,8 @@ ShortErrorMessage=Short Error Message
     ErrorCode=Error Code
     ErrorSeverityCode=Error Severity Code
     OnlinePaymentSystem=Online payment system
    -PaypalLiveEnabled=Paypal live enabled (otherwise test/sandbox mode)
    -PaypalImportPayment=Import Paypal payments
    +PaypalLiveEnabled=PayPal live enabled (otherwise test/sandbox mode)
    +PaypalImportPayment=Import PayPal payments
     PostActionAfterPayment=Post actions after payments
     ARollbackWasPerformedOnPostActions=A rollback was performed on all Post actions. You must complete post actions manually if they are necessary.
    -ValidationOfPaymentFailed=Validation of payment has failed
    \ No newline at end of file
    +ValidationOfPaymentFailed=Validation of payment has failed
    diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang
    index e8349453247..d2399823e37 100644
    --- a/htdocs/langs/en_US/printing.lang
    +++ b/htdocs/langs/en_US/printing.lang
    @@ -2,7 +2,7 @@
     Module64000Name=Direct Printing
     Module64000Desc=Enable Direct Printing System
     PrintingSetup=Setup of Direct Printing System
    -PrintingDesc=This module adds a Print button to send documents directly to a printer (without opening document into an application) with various module.
    +PrintingDesc=This module adds a Print button to various modules to allow documents to be printed directly to a printer without needing to open the document in another application.
     MenuDirectPrinting=Direct Printing jobs
     DirectPrint=Direct print
     PrintingDriverDesc=Configuration variables for printing driver.
    @@ -19,7 +19,7 @@ UserConf=Setup per user
     PRINTGCP_INFO=Google OAuth API setup
     PRINTGCP_AUTHLINK=Authentication
     PRINTGCP_TOKEN_ACCESS=Google Cloud Print OAuth Token
    -PrintGCPDesc=This driver allow to send documents directly to a printer with Google Cloud Print.
    +PrintGCPDesc=This driver allows sending documents directly to a printer using Google Cloud Print.
     GCP_Name=Name
     GCP_displayName=Display Name
     GCP_Id=Printer Id
    @@ -27,7 +27,7 @@ GCP_OwnerName=Owner Name
     GCP_State=Printer State
     GCP_connectionStatus=Online State
     GCP_Type=Printer Type
    -PrintIPPDesc=This driver allow to send documents directly to a printer. It requires a Linux system with CUPS installed.
    +PrintIPPDesc=This driver allows sending of documents directly to a printer. It requires a Linux system with CUPS installed.
     PRINTIPP_HOST=Print server
     PRINTIPP_PORT=Port
     PRINTIPP_USER=Login
    diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang
    index f0eafc807cf..54270c4a23b 100644
    --- a/htdocs/langs/en_US/productbatch.lang
    +++ b/htdocs/langs/en_US/productbatch.lang
    @@ -21,4 +21,4 @@ ProductDoesNotUseBatchSerial=This product does not use lot/serial number
     ProductLotSetup=Setup of module lot/serial
     ShowCurrentStockOfLot=Show current stock for couple product/lot
     ShowLogOfMovementIfLot=Show log of movements for couple product/lot
    -StockDetailPerBatch=Stock detail per lot
    \ No newline at end of file
    +StockDetailPerBatch=Stock detail per lot
    diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
    index 88d06eb9939..95b93aba4e9 100644
    --- a/htdocs/langs/en_US/products.lang
    +++ b/htdocs/langs/en_US/products.lang
    @@ -17,12 +17,12 @@ Reference=Reference
     NewProduct=New product
     NewService=New service
     ProductVatMassChange=Mass VAT change
    -ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from a value to another. Warning, this change is done on all database.
    +ProductVatMassChangeDesc=This page can be used to modify a VAT rate defined on products or services from one value to another. Warning, this change is global/done on all database.
     MassBarcodeInit=Mass barcode init
     MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete.
     ProductAccountancyBuyCode=Accounting code (purchase)
     ProductAccountancySellCode=Accounting code (sale)
    -ProductAccountancySellIntraCode=Accounting code (sale intra-community)
    +ProductAccountancySellIntraCode=Accounting code (sale intra-Community)
     ProductAccountancySellExportCode=Accounting code (sale export)
     ProductOrService=Product or Service
     ProductsAndServices=Products and Services
    @@ -130,11 +130,11 @@ DiscountQtyMin=Default discount for qty
     NoPriceDefinedForThisSupplier=No price/qty defined for this supplier/product
     NoSupplierPriceDefinedForThisProduct=No supplier price/qty defined for this product
     PredefinedProductsToSell=Predefined products to sell
    -PredefinedServicesToSell=Predefined services to sell 
    +PredefinedServicesToSell=Predefined services to sell
     PredefinedProductsAndServicesToSell=Predefined products/services to sell
     PredefinedProductsToPurchase=Predefined product to purchase
     PredefinedServicesToPurchase=Predefined services to purchase
    -PredefinedProductsAndServicesToPurchase=Predefined products/services to puchase
    +PredefinedProductsAndServicesToPurchase=Predefined products/services to purchase
     NotPredefinedProducts=Not predefined products/services
     GenerateThumb=Generate thumb
     ServiceNb=Service #%s
    @@ -145,7 +145,7 @@ Finished=Manufactured product
     RowMaterial=Raw Material
     CloneProduct=Clone product or service
     ConfirmCloneProduct=Are you sure you want to clone product or service <b>%s</b>?
    -CloneContentProduct=Clone all main informations of product/service
    +CloneContentProduct=Clone all main information of product/service
     ClonePricesProduct=Clone prices
     CloneCompositionProduct=Clone packaged product/service
     CloneCombinationsProduct=Clone product variants
    @@ -202,7 +202,7 @@ PriceByQuantity=Different prices by quantity
     DisablePriceByQty=Disable prices by quantity
     PriceByQuantityRange=Quantity range
     MultipriceRules=Price segment rules
    -UseMultipriceRules=Use price segment rules (defined into product module setup) to autocalculate prices of all other segment according to first segment
    +UseMultipriceRules=Use price segment rules (defined into product module setup) to auto calculate prices of all other segments according to first segment
     PercentVariationOver=%% variation over %s
     PercentDiscountOver=%% discount over %s
     KeepEmptyForAutoCalculation=Keep empty to have this calculated automatically from weight or volume of products
    @@ -233,7 +233,7 @@ BarCodeDataForThirdparty=Barcode information of third party %s :
     ResetBarcodeForAllRecords=Define barcode value for all record (this will also reset barcode value already defined with new values)
     PriceByCustomer=Different prices for each customer
     PriceCatalogue=A single sell price per product/service
    -PricingRule=Rules for sell prices
    +PricingRule=Rules for selling prices
     AddCustomerPrice=Add price by customer
     ForceUpdateChildPriceSoc=Set same price on customer subsidiaries
     PriceByCustomerLog=Log of previous customer prices
    @@ -254,7 +254,7 @@ ComposedProduct=Sub-product
     MinSupplierPrice=Minimum buying price
     MinCustomerPrice=Minimum selling price
     DynamicPriceConfiguration=Dynamic price configuration
    -DynamicPriceDesc=On product card, with this module enabled, you should be able to set mathematic functions to calculate Customer or Supplier prices. Such function can use all mathematic operators, some constants and variables. You can set here the variables you want to be able to use and if the variable need an automatic update, the external URL to use to ask Dolibarr to update automaticaly the value.
    +DynamicPriceDesc=On product card, with this module enabled, you should be able to set mathematic functions to calculate Customer or Supplier prices. Such function can use all mathematic operators, some constants and variables. You can set here the variables you want to be able to use and if the variable need an automatic update, the external URL to use to ask Dolibarr to update the value automatically.
     AddVariable=Add Variable
     AddUpdater=Add Updater
     GlobalVariables=Global variables
    @@ -269,7 +269,7 @@ GlobalVariableUpdaterHelpFormat1=Format for request is {"URL": "http://example.c
     UpdateInterval=Update interval (minutes)
     LastUpdated=Latest update
     CorrectlyUpdated=Correctly updated
    -PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is 
    +PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is
     PropalMergePdfProductChooseFile=Select PDF files
     IncludingProductWithTag=Including product/service with tag
     DefaultPriceRealPriceMayDependOnCustomer=Default price, real price may depend on customer
    @@ -292,8 +292,9 @@ SubProduct=Sub product
     ProductSheet=Product sheet
     ServiceSheet=Service sheet
     PossibleValues=Possible values
    -GoOnMenuToCreateVairants=Go on menu %s - %s to prepare attribute variants (like colors, size, ...) 
    -
    +GoOnMenuToCreateVairants=Go on menu %s - %s to prepare attribute variants (like colors, size, ...)
    +UseProductFournDesc=Use supplier descriptions of products in supplier documents
    +ProductSupplierDescription=Supplier description for the product
     #Attributes
     VariantAttributes=Variant attributes
     ProductAttributes=Variant attributes for products
    @@ -329,6 +330,8 @@ NbOfDifferentValues=No. of different values
     NbProducts=No. of products
     ParentProduct=Parent product
     HideChildProducts=Hide variant products
    +ShowChildProducts=Show variant products
    +NoEditVariants=Go to Parent product card and edit variants price impact in the variants tab
     ConfirmCloneProductCombinations=Would you like to copy all the product variants to the other parent product with the given reference?
     CloneDestinationReference=Destination product reference
     ErrorCopyProductCombinations=There was an error while copying the product variants
    diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
    index 5c66e298fe8..c83bccd19ad 100644
    --- a/htdocs/langs/en_US/projects.lang
    +++ b/htdocs/langs/en_US/projects.lang
    @@ -7,7 +7,7 @@ ProjectsArea=Projects Area
     ProjectStatus=Project status
     SharedProject=Everybody
     PrivateProject=Project contacts
    -ProjectsImContactFor=Projects I'm explicitely a contact of 
    +ProjectsImContactFor=Projects I'm explicitely a contact of
     AllAllowedProjects=All project I can read (mine + public)
     AllProjects=All projects
     MyProjectsDesc=This view is limited to projects you are a contact for
    @@ -33,8 +33,8 @@ ConfirmDeleteAProject=Are you sure you want to delete this project?
     ConfirmDeleteATask=Are you sure you want to delete this task?
     OpenedProjects=Open projects
     OpenedTasks=Open tasks
    -OpportunitiesStatusForOpenedProjects=Opportunities amount of open projects by status
    -OpportunitiesStatusForProjects=Opportunities amount of projects by status
    +OpportunitiesStatusForOpenedProjects=Leads amount of open projects by status
    +OpportunitiesStatusForProjects=Leads amount of projects by status
     ShowProject=Show project
     ShowTask=Show task
     SetProject=Set project
    @@ -79,19 +79,20 @@ GoToListOfTimeConsumed=Go to list of time consumed
     GoToListOfTasks=Go to list of tasks
     GoToGanttView=Go to Gantt view
     GanttView=Gantt View
    -ListProposalsAssociatedProject=List of the commercial proposals associated with the project
    -ListOrdersAssociatedProject=List of customer orders associated with the project
    -ListInvoicesAssociatedProject=List of customer invoices associated with the project
    -ListPredefinedInvoicesAssociatedProject=List of customer template invoices associated with project
    -ListSupplierOrdersAssociatedProject=List of supplier orders associated with the project
    -ListSupplierInvoicesAssociatedProject=List of supplier invoices associated with the project
    -ListContractAssociatedProject=List of contracts associated with the project
    -ListShippingAssociatedProject=List of shippings associated with the project
    -ListFichinterAssociatedProject=List of interventions associated with the project
    -ListExpenseReportsAssociatedProject=List of expense reports associated with the project
    -ListDonationsAssociatedProject=List of donations associated with the project
    -ListVariousPaymentsAssociatedProject=List of miscellaneous payments associated with the project
    -ListActionsAssociatedProject=List of events associated with the project
    +ListProposalsAssociatedProject=List of the commercial proposals related to the project
    +ListOrdersAssociatedProject=List of customer orders related to the project
    +ListInvoicesAssociatedProject=List of customer invoices related to the project
    +ListPredefinedInvoicesAssociatedProject=List of customer template invoices related to the project
    +ListSupplierOrdersAssociatedProject=List of supplier orders related to the project
    +ListSupplierInvoicesAssociatedProject=List of supplier invoices related to the project
    +ListContractAssociatedProject=List of contracts related to the project
    +ListShippingAssociatedProject=List of shippings related to the project
    +ListFichinterAssociatedProject=List of interventions related to the project
    +ListExpenseReportsAssociatedProject=List of expense reports related to the project
    +ListDonationsAssociatedProject=List of donations related to the project
    +ListVariousPaymentsAssociatedProject=List of miscellaneous payments related to the project
    +ListSalariesAssociatedProject=List of payments of salaries related to the project
    +ListActionsAssociatedProject=List of events related to the project
     ListTaskTimeUserProject=List of time consumed on tasks of project
     ListTaskTimeForTask=List of time consumed on task
     ActivityOnProjectToday=Activity on project today
    @@ -125,7 +126,7 @@ TaskRessourceLinks=Contacts task
     ProjectsDedicatedToThisThirdParty=Projects dedicated to this third party
     NoTasks=No tasks for this project
     LinkedToAnotherCompany=Linked to other third party
    -TaskIsNotAssignedToUser=Task not assigned to user. Use button '<strong>%s</strong>' to assign task now. 
    +TaskIsNotAssignedToUser=Task not assigned to user. Use button '<strong>%s</strong>' to assign task now.
     ErrorTimeSpentIsEmpty=Time spent is empty
     ThisWillAlsoRemoveTasks=This action will also delete all tasks of project (<b>%s</b> tasks at the moment) and all inputs of time spent.
     IfNeedToUseOhterObjectKeepEmpty=If some objects (invoice, order, ...), belonging to another third party, must be linked to the project to create, keep this empty to have the project being multi third parties.
    @@ -146,11 +147,11 @@ ProjectModifiedInDolibarr=Project %s modified
     TaskCreatedInDolibarr=Task %s created
     TaskModifiedInDolibarr=Task %s modified
     TaskDeletedInDolibarr=Task %s deleted
    -OpportunityStatus=Opportunity status
    +OpportunityStatus=Lead status
     OpportunityStatusShort=Opp. status
    -OpportunityProbability=Opportunity probability
    +OpportunityProbability=Lead probability
     OpportunityProbabilityShort=Opp. probab.
    -OpportunityAmount=Opportunity amount
    +OpportunityAmount=Lead amount
     OpportunityAmountShort=Opp. amount
     OpportunityAmountAverageShort=Average Opp. amount
     OpportunityAmountWeigthedShort=Weighted Opp. amount
    @@ -190,25 +191,26 @@ AssignTaskToUser=Assign task to %s
     SelectTaskToAssign=Select task to assign...
     AssignTask=Assign
     ProjectOverview=Overview
    -ManageTasks=Use projects to follow tasks and time
    +ManageTasks=Use projects to follow tasks and/or report time spent (timesheets)
     ManageOpportunitiesStatus=Use projects to follow leads/opportinuties
     ProjectNbProjectByMonth=No. of created projects by month
     ProjectNbTaskByMonth=No. of created tasks by month
    -ProjectOppAmountOfProjectsByMonth=Amount of opportunities by month
    -ProjectWeightedOppAmountOfProjectsByMonth=Weighted amount of opportunities by month
    -ProjectOpenedProjectByOppStatus=Open project/lead by opportunity status
    +ProjectOppAmountOfProjectsByMonth=Amount of leads by month
    +ProjectWeightedOppAmountOfProjectsByMonth=Weighted amount of leads by month
    +ProjectOpenedProjectByOppStatus=Open project/lead by lead status
     ProjectsStatistics=Statistics on projects/leads
     TasksStatistics=Statistics on project/lead tasks
     TaskAssignedToEnterTime=Task assigned. Entering time on this task should be possible.
     IdTaskTime=Id task time
     YouCanCompleteRef=If you want to complete the ref with some information (to use it as search filters), it is recommanded to add a - character to separate it, so the automatic numbering will still work correctly for next projects. For example %s-ABC. You may also prefer to add search keys into label. But best practice may be to add a dedicated field, also called complementary attributes.
     OpenedProjectsByThirdparties=Open projects by third parties
    -OnlyOpportunitiesShort=Only opportunities
    -OpenedOpportunitiesShort=Open opportunities
    -NotAnOpportunityShort=Not an opportunity
    -OpportunityTotalAmount=Opportunities total amount
    -OpportunityPonderatedAmount=Opportunities weighted amount
    -OpportunityPonderatedAmountDesc=Opportunities amount weighted with probability
    +OnlyOpportunitiesShort=Only leads
    +OpenedOpportunitiesShort=Open leads
    +NotOpenedOpportunitiesShort=Not open leads
    +NotAnOpportunityShort=Not a lead
    +OpportunityTotalAmount=Total amount of leads
    +OpportunityPonderatedAmount=Weighted amount of leads
    +OpportunityPonderatedAmountDesc=Leads amount weighted with probability
     OppStatusPROSP=Prospection
     OppStatusQUAL=Qualification
     OppStatusPROPO=Proposal
    diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang
    index 3552076a4e7..fd1240e3ea6 100644
    --- a/htdocs/langs/en_US/propal.lang
    +++ b/htdocs/langs/en_US/propal.lang
    @@ -53,7 +53,7 @@ ErrorPropalNotFound=Propal %s not found
     AddToDraftProposals=Add to draft proposal
     NoDraftProposals=No draft proposals
     CopyPropalFrom=Create commercial proposal by copying existing proposal
    -CreateEmptyPropal=Create empty commercial proposals vierge or from list of products/services
    +CreateEmptyPropal=Create empty commercial proposal or from list of products/services
     DefaultProposalDurationValidity=Default commercial proposal validity duration (in days)
     UseCustomerContactAsPropalRecipientIfExist=Use customer contact address if defined instead of third party address as proposal recipient address
     ClonePropal=Clone commercial proposal
    @@ -78,8 +78,9 @@ TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal
     TypeContact_propal_external_SHIPPING=Customer contact for delivery
     # Document models
     DocModelAzurDescription=A complete proposal model (logo...)
    +DocModelCyanDescription=A complete proposal model (logo...)
     DefaultModelPropalCreate=Default model creation
     DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced)
     DefaultModelPropalClosed=Default template when closing a business proposal (unbilled)
     ProposalCustomerSignature=Written acceptance, company stamp, date and signature
    -ProposalsStatisticsSuppliers=Supplier proposals statistics 
    +ProposalsStatisticsSuppliers=Supplier proposals statistics
    diff --git a/htdocs/langs/en_US/resource.lang b/htdocs/langs/en_US/resource.lang
    index 5a907f6ba23..33a5046e006 100644
    --- a/htdocs/langs/en_US/resource.lang
    +++ b/htdocs/langs/en_US/resource.lang
    @@ -5,7 +5,7 @@ DeleteResource=Delete resource
     ConfirmDeleteResourceElement=Confirm delete the resource for this element
     NoResourceInDatabase=No resource in database.
     NoResourceLinked=No resource linked
    -
    +ActionsOnResource=Events about this resource
     ResourcePageIndex=Resources list
     ResourceSingular=Resource
     ResourceCard=Resource card
    diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang
    index 432ab894040..620517b5324 100644
    --- a/htdocs/langs/en_US/salaries.lang
    +++ b/htdocs/langs/en_US/salaries.lang
    @@ -1,10 +1,11 @@
     # Dolibarr language file - Source file is en_US - salaries
     SALARIES_ACCOUNTING_ACCOUNT_PAYMENT=Accounting account used for user third parties
    -SALARIES_ACCOUNTING_ACCOUNT_PAYMENT_Desc=The dedicated accounting account defined on user card will be used for Subledger accouting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated user accouting account on user is not defined.
    +SALARIES_ACCOUNTING_ACCOUNT_PAYMENT_Desc=The dedicated accounting account defined on user card will be used for Subledger accounting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated user accounting account on user is not defined.
     SALARIES_ACCOUNTING_ACCOUNT_CHARGE=Accounting account by default for wage payments
     Salary=Salary
     Salaries=Salaries
     NewSalaryPayment=New salary payment
    +AddSalaryPayment=Add salary payment
     SalaryPayment=Salary payment
     SalariesPayments=Salaries payments
     ShowSalaryPayment=Show salary payment
    @@ -15,4 +16,4 @@ THMDescription=This value may be used to calculate cost of time consumed on a pr
     TJMDescription=This value is currently as information only and is not used for any calculation
     LastSalaries=Latest %s salary payments
     AllSalaries=All salary payments
    -SalariesStatistics=Statistiques salaires
    \ No newline at end of file
    +SalariesStatistics=Salary statistics
    diff --git a/htdocs/langs/en_US/sendings.lang b/htdocs/langs/en_US/sendings.lang
    index b8474775e75..2b46ada5ee9 100644
    --- a/htdocs/langs/en_US/sendings.lang
    +++ b/htdocs/langs/en_US/sendings.lang
    @@ -56,7 +56,7 @@ ProductQtyInCustomersOrdersRunning=Product quantity into open customer orders
     ProductQtyInSuppliersOrdersRunning=Product quantity into open purchase orders
     ProductQtyInShipmentAlreadySent=Product quantity from open customer order already sent
     ProductQtyInSuppliersShipmentAlreadyRecevied=Product quantity from open supplier order already received
    -NoProductToShipFoundIntoStock=No product to ship found into warehouse <b>%s</b>. Correct stock or go back to choose another warehouse. 
    +NoProductToShipFoundIntoStock=No product to ship found in warehouse <b>%s</b>. Correct stock or go back to choose another warehouse.
     WeightVolShort=Weight/Vol.
     ValidateOrderFirstBeforeShipment=You must first validate the order before being able to make shipments.
     
    diff --git a/htdocs/langs/en_US/sms.lang b/htdocs/langs/en_US/sms.lang
    index b333d7887bb..79bd8827198 100644
    --- a/htdocs/langs/en_US/sms.lang
    +++ b/htdocs/langs/en_US/sms.lang
    @@ -1,9 +1,9 @@
     # Dolibarr language file - Source file is en_US - sms
     Sms=Sms
    -SmsSetup=Sms setup
    -SmsDesc=This page allows you to define globals options on SMS features
    +SmsSetup=SMS setup
    +SmsDesc=This page allows you to define global options on SMS features
     SmsCard=SMS Card
    -AllSms=All SMS campains
    +AllSms=All SMS campaigns
     SmsTargets=Targets
     SmsRecipients=Targets
     SmsRecipient=Target
    @@ -13,20 +13,20 @@ SmsTo=Target
     SmsTopic=Topic of SMS
     SmsText=Message
     SmsMessage=SMS Message
    -ShowSms=Show Sms
    -ListOfSms=List SMS campains
    -NewSms=New SMS campain
    -EditSms=Edit Sms
    +ShowSms=Show SMS
    +ListOfSms=List SMS campaigns
    +NewSms=New SMS campaign
    +EditSms=Edit SMS
     ResetSms=New sending
    -DeleteSms=Delete Sms campain
    -DeleteASms=Remove a Sms campain
    -PreviewSms=Previuw Sms
    -PrepareSms=Prepare Sms
    -CreateSms=Create Sms
    -SmsResult=Result of Sms sending
    -TestSms=Test Sms
    -ValidSms=Validate Sms
    -ApproveSms=Approve Sms
    +DeleteSms=Delete SMS campaign
    +DeleteASms=Remove a SMS campaign
    +PreviewSms=Previuw SMS
    +PrepareSms=Prepare SMS
    +CreateSms=Create SMS
    +SmsResult=Result of SMS sending
    +TestSms=Test SMS
    +ValidSms=Validate SMS
    +ApproveSms=Approve SMS
     SmsStatusDraft=Draft
     SmsStatusValidated=Validated
     SmsStatusApproved=Approved
    @@ -35,7 +35,7 @@ SmsStatusSentPartialy=Sent partially
     SmsStatusSentCompletely=Sent completely
     SmsStatusError=Error
     SmsStatusNotSent=Not sent
    -SmsSuccessfulySent=Sms correctly sent (from %s to %s)
    +SmsSuccessfulySent=SMS correctly sent (from %s to %s)
     ErrorSmsRecipientIsEmpty=Number of target is empty
     WarningNoSmsAdded=No new phone number to add to target list
     ConfirmValidSms=Do you confirm validation of this campaign?
    @@ -48,4 +48,4 @@ SmsInfoNumero= (international format ie : +33899701761)
     DelayBeforeSending=Delay before sending (minutes)
     SmsNoPossibleSenderFound=No sender available. Check setup of your SMS provider.
     SmsNoPossibleRecipientFound=No target available. Check setup of your SMS provider.
    -DisableStopIfSupported=Disable STOP message (if supported) 
    +DisableStopIfSupported=Disable STOP message (if supported)
    diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
    index 0d22a3b3c75..fbbc00887aa 100644
    --- a/htdocs/langs/en_US/stocks.lang
    +++ b/htdocs/langs/en_US/stocks.lang
    @@ -44,7 +44,6 @@ TransferStock=Transfer stock
     MassStockTransferShort=Mass stock transfer
     StockMovement=Stock movement
     StockMovements=Stock movements
    -LabelMovement=Movement label
     NumberOfUnit=Number of units
     UnitPurchaseValue=Unit purchase price
     StockTooLow=Stock too low
    @@ -55,20 +54,20 @@ PMPValueShort=WAP
     EnhancedValueOfWarehouses=Warehouses value
     UserWarehouseAutoCreate=Create a user warehouse automatically when creating a user
     AllowAddLimitStockByWarehouse=Allow to add limit and desired stock per couple (product, warehouse) instead of per product
    -IndependantSubProductStock=Product stock and subproduct stock are independant
    +IndependantSubProductStock=Product stock and subproduct stock are independent
     QtyDispatched=Quantity dispatched
     QtyDispatchedShort=Qty dispatched
     QtyToDispatchShort=Qty to dispatch
     OrderDispatch=Item receipts
    -RuleForStockManagementDecrease=Rule for automatic stock management decrease (manual decrease is always possible, even if an automatic decrease rule is activated)
    -RuleForStockManagementIncrease=Rule for automatic stock management increase (manual increase is always possible, even if an automatic increase rule is activated)
    -DeStockOnBill=Decrease real stocks on customers invoices/credit notes validation
    -DeStockOnValidateOrder=Decrease real stocks on customers orders validation
    +RuleForStockManagementDecrease=Choose Rule for automatic stock decrease (manual decrease is always possible, even if an automatic decrease rule is activated)
    +RuleForStockManagementIncrease=Choose Rule for automatic stock increase (manual increase is always possible, even if an automatic increase rule is activated)
    +DeStockOnBill=Decrease real stocks on validation of customer invoice/credit note
    +DeStockOnValidateOrder=Decrease real stocks on validation of customer order
     DeStockOnShipment=Decrease real stocks on shipping validation
     DeStockOnShipmentOnClosing=Decrease real stocks on shipping classification closed
    -ReStockOnBill=Increase real stocks on suppliers invoices/credit notes validation
    -ReStockOnValidateOrder=Increase real stocks on purchase orders approbation
    -ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouses, after supplier order receipt of goods
    +ReStockOnBill=Increase real stocks on validation of supplier invoice/credit note
    +ReStockOnValidateOrder=Increase real stocks on purchase order approval
    +ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouse, after supplier order receipt of goods
     OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses.
     StockDiffPhysicTeoric=Explanation for difference between physical and virtual stock
     NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required.
    @@ -78,7 +77,7 @@ StockLimit=Stock limit for alert
     StockLimitDesc=(empty) means no warning.<br>0 can be used for a warning as soon as stock is empty.
     PhysicalStock=Physical stock
     RealStock=Real Stock
    -RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements. 
    +RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements.
     RealStockWillAutomaticallyWhen=The real stock will automatically change according to this rules (see stock module setup to change this):
     VirtualStock=Virtual stock
     VirtualStockDesc=Virtual stock is the stock you will get once all open pending actions that affect stocks will be closed (supplier order received, customer order shipped, ...)
    @@ -130,14 +129,15 @@ RecordMovement=Record transfer
     ReceivingForSameOrder=Receipts for this order
     StockMovementRecorded=Stock movements recorded
     RuleForStockAvailability=Rules on stock requirements
    -StockMustBeEnoughForInvoice=Stock level must be enough to add product/service to invoice (check is done on current real stock when adding a line into invoice whatever is rule for automatic stock change)
    -StockMustBeEnoughForOrder=Stock level must be enough to add product/service to order (check is done on current real stock when adding a line into order whatever is rule for automatic stock change)
    -StockMustBeEnoughForShipment= Stock level must be enough to add product/service to shipment (check is done on current real stock when adding a line into shipment whatever is rule for automatic stock change)
    +StockMustBeEnoughForInvoice=Stock level must be enough to add product/service to invoice (check is done on current real stock when adding a line into invoice whatever the rule for automatic stock change)
    +StockMustBeEnoughForOrder=Stock level must be enough to add product/service to order (check is done on current real stock when adding a line into order whatever the rule for automatic stock change)
    +StockMustBeEnoughForShipment= Stock level must be enough to add product/service to shipment (check is done on current real stock when adding a line into shipment whatever the rule for automatic stock change)
     MovementLabel=Label of movement
    +TypeMovement=Type of movement
     DateMovement=Date of movement
     InventoryCode=Movement or inventory code
     IsInPackage=Contained into package
    -WarehouseAllowNegativeTransfer=Stock can be negative 
    +WarehouseAllowNegativeTransfer=Stock can be negative
     qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse and your setup does not allow negative stocks.
     ShowWarehouse=Show warehouse
     MovementCorrectStock=Stock correction for product %s
    @@ -172,12 +172,12 @@ inventoryDraft=Running
     inventorySelectWarehouse=Warehouse choice
     inventoryConfirmCreate=Create
     inventoryOfWarehouse=Inventory for warehouse : %s
    -inventoryErrorQtyAdd=Error : one quantity is leaser than zero
    +inventoryErrorQtyAdd=Error : one quantity is less than zero
     inventoryMvtStock=By inventory
     inventoryWarningProductAlreadyExists=This product is already into list
     SelectCategory=Category filter
     SelectFournisseur=Supplier filter
    -inventoryOnDate=Inventory 
    +inventoryOnDate=Inventory
     INVENTORY_DISABLE_VIRTUAL=Allow to not destock child product from a kit on inventory
     INVENTORY_USE_MIN_PA_IF_NO_LAST_PA=Use the buy price if no last buy price can be found
     INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT=Stock movement have date of inventory
    @@ -195,12 +195,16 @@ AddInventoryProduct=Add product to inventory
     AddProduct=Add
     ApplyPMP=Apply PMP
     FlushInventory=Flush inventory
    -ConfirmFlushInventory=Do you confirm this action ?
    +ConfirmFlushInventory=Do you confirm this action?
     InventoryFlushed=Inventory flushed
     ExitEditMode=Exit edition
     inventoryDeleteLine=Delete line
     RegulateStock=Regulate Stock
     ListInventory=List
    -StockSupportServices=Stock management support services
    +StockSupportServices=Stock management supports Services
     StockSupportServicesDesc=By default, you can stock only product with type "product". If on, and if module service is on, you can also stock a product with type "service"
    -ReceiveProducts=Receive items
    \ No newline at end of file
    +ReceiveProducts=Receive items
    +StockIncreaseAfterCorrectTransfer=Increase by correction/transfer
    +StockDecreaseAfterCorrectTransfer=Decrease by correction/transfer
    +StockIncrease=Stock increase
    +StockDecrease=Stock decrease
    diff --git a/htdocs/langs/en_US/stripe.lang b/htdocs/langs/en_US/stripe.lang
    index ecd176a0ae7..ed3d24f4370 100644
    --- a/htdocs/langs/en_US/stripe.lang
    +++ b/htdocs/langs/en_US/stripe.lang
    @@ -22,7 +22,7 @@ ToOfferALinkForOnlinePaymentOnContractLine=URL to offer a %s online payment user
     ToOfferALinkForOnlinePaymentOnFreeAmount=URL to offer a %s online payment user interface for a free amount
     ToOfferALinkForOnlinePaymentOnMemberSubscription=URL to offer a %s online payment user interface for a member subscription
     YouCanAddTagOnUrl=You can also add url parameter <b>&tag=<i>value</i></b> to any of those URL (required only for free payment) to add your own payment comment tag.
    -SetupStripeToHavePaymentCreatedAutomatically=Setup your Stripe with url <b>%s</b> to have payment created automatically when validated by Stripe. 
    +SetupStripeToHavePaymentCreatedAutomatically=Setup your Stripe with url <b>%s</b> to have payment created automatically when validated by Stripe.
     AccountParameter=Account parameters
     UsageParameter=Usage parameters
     InformationToFindParameters=Help to find your %s account information
    @@ -60,4 +60,5 @@ DeleteACard=Delete Card
     ConfirmDeleteCard=Are you sure you want to delete this Credit or Debit card?
     CreateCustomerOnStripe=Create customer on Stripe
     CreateCardOnStripe=Create card on Stripe
    -ShowInStripe=Show in Stripe
    \ No newline at end of file
    +ShowInStripe=Show in Stripe
    +StripeUserAccountForActions=User account to use for some emails notification of Stripe events (Stripe payouts)
    diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang
    index d8f1137b7af..75de962b7ce 100644
    --- a/htdocs/langs/en_US/ticket.lang
    +++ b/htdocs/langs/en_US/ticket.lang
    @@ -138,7 +138,7 @@ TicketStatByStatus=Tickets by status
     #
     # Ticket card
     #
    -Ticket=Incident ticket
    +Ticket=Ticket
     TicketCard=Ticket card
     CreateTicket=Create ticket
     EditTicket=Edit ticket
    diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang
    index 0f9fcac1d02..2ede3bc474e 100644
    --- a/htdocs/langs/en_US/trips.lang
    +++ b/htdocs/langs/en_US/trips.lang
    @@ -33,7 +33,7 @@ ExpenseReportCanceledMessage=The expense report %s was canceled.<br> - User: %s<
     ExpenseReportPaid=An expense report was paid
     ExpenseReportPaidMessage=The expense report %s was paid.<br> - User: %s<br> - Paid by: %s<br>Click here to show the expense report: %s
     TripId=Id expense report
    -AnyOtherInThisListCanValidate=Person to inform for validation. 
    +AnyOtherInThisListCanValidate=Person to inform for validation.
     TripSociete=Information company
     TripNDF=Informations expense report
     PDFStandardExpenseReports=Standard template to generate a PDF document for expense report
    @@ -154,4 +154,4 @@ nolimitbyEX_EXP=by line (no limitation)
     
     CarCategory=Category of car
     ExpenseRangeOffset=Offset amount: %s
    -RangeIk=Mileage range
    \ No newline at end of file
    +RangeIk=Mileage range
    diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang
    index 20c3e90ae41..68fffde3bb0 100644
    --- a/htdocs/langs/en_US/users.lang
    +++ b/htdocs/langs/en_US/users.lang
    @@ -35,7 +35,7 @@ SuperAdministrator=Super Administrator
     SuperAdministratorDesc=Global administrator
     AdministratorDesc=Administrator
     DefaultRights=Default permissions
    -DefaultRightsDesc=Define here <u>default</u> permissions that are automatically granted to a <u>new created</u> user (Go on user card to change permission of an existing user).
    +DefaultRightsDesc=Define here <u>default</u> permissions that are automatically granted to a <u>new created</u> user (Go to user card to change permission of an existing user).
     DolibarrUsers=Dolibarr users
     LastName=Last name
     FirstName=First name
    @@ -108,4 +108,4 @@ UserAccountancyCode=User accounting code
     UserLogoff=User logout
     UserLogged=User logged
     DateEmployment=Date of Employment
    -DateEmploymentEnd=End date of Employment
    \ No newline at end of file
    +DateEmploymentEnd=End date of Employment
    diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
    index 21935b5dae0..bee23264d7a 100644
    --- a/htdocs/langs/en_US/website.lang
    +++ b/htdocs/langs/en_US/website.lang
    @@ -1,8 +1,8 @@
    -# Dolibarr language file - Source file is en_US - website 
    +# Dolibarr language file - Source file is en_US - website
     Shortname=Code
    -WebsiteSetupDesc=Create here as much entry as number of different websites you need. Then go into menu Websites to edit them.
    +WebsiteSetupDesc=Create here the websites you wish to use. Then go into menu Websites to edit them.
     DeleteWebsite=Delete website
    -ConfirmDeleteWebsite=Are you sure you want to delete this web site. All its pages and content will also be removed. 
    +ConfirmDeleteWebsite=Are you sure you want to delete this web site? All its pages and content will also be removed.
     WEBSITE_TYPE_CONTAINER=Type of page/container
     WEBSITE_PAGE_EXAMPLE=Web page to use as example
     WEBSITE_PAGENAME=Page name/alias
    @@ -16,19 +16,21 @@ WEBSITE_ROBOT=Robot file (robots.txt)
     WEBSITE_HTACCESS=Web site .htaccess file
     HtmlHeaderPage=HTML header (specific to this page only)
     PageNameAliasHelp=Name or alias of the page.<br>This alias is also used to forge a SEO URL when website is ran from a Virtual host of a Web server (like Apacke, Nginx, ...). Use the button "<strong>%s</strong>" to edit this alias.
    -EditTheWebSiteForACommonHeader=Note: If you want to define a personalized header for all pages, edit the header on the site level instead of on the page/container.   
    +EditTheWebSiteForACommonHeader=Note: If you want to define a personalized header for all pages, edit the header on the site level instead of on the page/container.
     MediaFiles=Media library
    -EditCss=Edit Style/CSS or HTML header
    +EditCss=Edit website properties
     EditMenu=Edit menu
     EditMedias=Edit medias
    -EditPageMeta=Edit Meta
    +EditPageMeta=Edit page/container properties
    +EditInLine=Edit inline
     AddWebsite=Add website
     Webpage=Web page/container
     AddPage=Add page/container
     HomePage=Home Page
     PageContainer=Page/container
    -PreviewOfSiteNotYetAvailable=Preview of your website <strong>%s</strong> not yet available. You must first add a page.
    +PreviewOfSiteNotYetAvailable=Preview of your website <strong>%s</strong> not yet available. You must first '<strong>Import a full website template</strong>' or just '<strong>Add a page/container</strong>'.
     RequestedPageHasNoContentYet=Requested page with id %s has no content yet, or cache file .tpl.php was removed. Edit content of the page to solve this.
    +SiteDeleted=Web site '%s' deleted
     PageContent=Page/Contenair
     PageDeleted=Page/Contenair '%s' of website %s deleted
     PageAdded=Page/Contenair '%s' added
    @@ -37,18 +39,19 @@ ViewPageInNewTab=View page in new tab
     SetAsHomePage=Set as Home page
     RealURL=Real URL
     ViewWebsiteInProduction=View web site using home URLs
    -SetHereVirtualHost=If you can create, on your web server (Apache, Nginx, ...), a dedicated Virtual Host with PHP enabled and a Root directory on<br><strong>%s</strong><br>then enter here the virtual hostname you have created, so the preview can be done also using this dedicated web server access instead of only using Dolibarr server.
    -YouCanAlsoTestWithPHPS=On develop environment, you may prefer to test the site with the PHP embedded web server (PHP 5.5 required) by running<br><strong>php -S 0.0.0.0:8080 -t %s</strong>
    +SetHereVirtualHost=<u>Use with Apache/NGinx/...</u><br>If you can create, on your web server (Apache, Nginx, ...), a dedicated Virtual Host with PHP enabled and a Root directory on<br><strong>%s</strong><br>then enter here the virtual hostname you have created, so the preview can be done also using this dedicated web server access instead of only using Dolibarr server.
    +YouCanAlsoTestWithPHPS=<u>Use with PHP embedded server</u><br>On develop environment, you may prefer to test the site with the PHP embedded web server (PHP 5.5 required) by running<br><strong>php -S 0.0.0.0:8080 -t %s</strong>
     CheckVirtualHostPerms=Check also that virtual host has permission <strong>%s</strong> on files into<br><strong>%s</strong>
     ReadPerm=Read
     WritePerm=Write
     PreviewSiteServedByWebServer=<u>Preview %s in a new tab.</u><br><br>The %s will be served by an external web server (like Apache, Nginx, IIS). You must install and setup this server before to point to directory:<br><strong>%s</strong><br>URL served by external server:<br><strong>%s</strong>
    -PreviewSiteServedByDolibarr=<u>Preview %s in a new tab.</u><br><br>The %s will be served by Dolibarr server so it does not need any extra web server (like Apache, Nginx, IIS) to be installed.<br>The inconvenient is that URL of pages are not user friendly and start with path of your Dolibarr.<br>URL served by Dolibarr:<br><strong>%s</strong><br><br>To use your own external web server to serve this web site, create a virtual host on your web server that point on directory<br><strong>%s</strong><br>then enter the name of this virtual server and click on the other preview button.  
    +PreviewSiteServedByDolibarr=<u>Preview %s in a new tab.</u><br><br>The %s will be served by Dolibarr server so it does not need any extra web server (like Apache, Nginx, IIS) to be installed.<br>The inconvenient is that URL of pages are not user friendly and start with path of your Dolibarr.<br>URL served by Dolibarr:<br><strong>%s</strong><br><br>To use your own external web server to serve this web site, create a virtual host on your web server that point on directory<br><strong>%s</strong><br>then enter the name of this virtual server and click on the other preview button.
     VirtualHostUrlNotDefined=URL of the virtual host served by external web server not defined
     NoPageYet=No pages yet
    +YouCanCreatePageOrImportTemplate=You can create a new page or import a full website template
     SyntaxHelp=Help on specific syntax tips
    -YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor. 
    -YouCanEditHtmlSource=<br><span class="fa fa-bug"></span> You can include PHP code into this source using tags <strong>&lt;?php ?&gt;</strong>. The following global variables are available: $conf, $langs, $db, $mysoc, $user, $website.<br><br><span class="fa fa-bug"></span> You can also include content of another Page/Container with the following syntax:<br><strong>&lt;?php includeContainer('alias_of_container_to_include'); ?&gt;</strong><br><br><span class="fa fa-bug"></span> You can make a redirect to another Page/Container with the following syntax:<br><strong>&lt;?php redirectToContainer('alias_of_container_to_redirect_to'); ?&gt;</strong><br><br><span class="fa fa-download"></span> To include a <strong>link to download</strong> a file stored into the <strong>documents</strong> directory, use the <strong>document.php</strong> wrapper:<br>Example, for a file into documents/ecm (need to be logged), syntax is:<br><strong>&lt;a href="/document.php?modulepart=ecm&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file into documents/medias (open directory for public access), syntax is:<br><strong>&lt;a href="/document.php?modulepart=medias&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file shared with a share link (open access using the sharing hash key of file), syntax is:<br><strong>&lt;a href="/document.php?hashp=publicsharekeyoffile"&gt;</strong><br><br><span class="fa fa-picture-o"></span> To include an <strong>image</strong> stored into the <strong>documents</strong> directory, use the <strong>viewimage.php</strong> wrapper:<br>Example, for an image into documents/medias (open access), syntax is:<br><strong>&lt;a href="/viewimage.php?modulepart=medias&amp;file=[relative_dir/]filename.ext"&gt;</strong><br>
    +YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor.
    +YouCanEditHtmlSource=<br><span class="fa fa-bug"></span> You can include PHP code into this source using tags <strong>&lt;?php ?&gt;</strong>. The following global variables are available: $conf, $db, $mysoc, $user, $website, $websitepage, $weblangs.<br><br><span class="fa fa-bug"></span> You can also include content of another Page/Container with the following syntax:<br><strong>&lt;?php includeContainer('alias_of_container_to_include'); ?&gt;</strong><br><br><span class="fa fa-bug"></span> You can make a redirect to another Page/Container with the following syntax (Note: do not output any content before a redirect):<br><strong>&lt;?php redirectToContainer('alias_of_container_to_redirect_to'); ?&gt;</strong><br><br><span class="fa fa-link"></span> To add a link to another page, use the syntax:<br><strong>&lt;a href="alias_of_page_to_link_to.php"&gt;mylink&lt;a&gt;</strong><br><br><span class="fa fa-download"></span> To include a <strong>link to download</strong> a file stored into the <strong>documents</strong> directory, use the <strong>document.php</strong> wrapper:<br>Example, for a file into documents/ecm (need to be logged), syntax is:<br><strong>&lt;a href="/document.php?modulepart=ecm&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file into documents/medias (open directory for public access), syntax is:<br><strong>&lt;a href="/document.php?modulepart=medias&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file shared with a share link (open access using the sharing hash key of file), syntax is:<br><strong>&lt;a href="/document.php?hashp=publicsharekeyoffile"&gt;</strong><br><br><span class="fa fa-picture-o"></span> To include an <strong>image</strong> stored into the <strong>documents</strong> directory, use the <strong>viewimage.php</strong> wrapper:<br>Example, for an image into documents/medias (open directory for public access), syntax is:<br><strong>&lt;img src="/viewimage.php?modulepart=medias&amp;file=[relative_dir/]filename.ext"&gt;</strong><br>
     ClonePage=Clone page/container
     CloneSite=Clone site
     SiteAdded=Web site added
    @@ -58,9 +61,10 @@ LanguageMustNotBeSameThanClonedPage=You clone a page as a translation. The langu
     ParentPageId=Parent page ID
     WebsiteId=Website ID
     CreateByFetchingExternalPage=Create page/container by fetching page from external URL...
    -OrEnterPageInfoManually=Or create empty page from scratch...
    +OrEnterPageInfoManually=Or create page from scratch or from a page template...
     FetchAndCreate=Fetch and Create
    -ExportSite=Export site
    +ExportSite=Export website
    +ImportSite=Import website template
     IDOfPage=Id of page
     Banner=Banner
     BlogPost=Blog post
    @@ -74,7 +78,7 @@ AnotherContainer=Another container
     WEBSITE_USE_WEBSITE_ACCOUNTS=Enable the web site account table
     WEBSITE_USE_WEBSITE_ACCOUNTSTooltip=Enable the table to store web site accounts (login/pass) for each website / thirdparty
     YouMustDefineTheHomePage=You must first define the default Home page
    -OnlyEditionOfSourceForGrabbedContentFuture=Note: only edition of HTML source will be possible when a page content is initiliazed by grabbing it from an external page (WYSIWYG editor will not be available)
    +OnlyEditionOfSourceForGrabbedContentFuture=Warning: Creating a web page by importing an external web page is reserved to experienced user. Depending on the complexity of source page, the result of importation may differs once imported from original. Also if the source page use common CSS style or not compatible javascript, it may break the look or features of the Web site editor when working on this page. This method is faster way to have a page but it is recommanded to create your new page from scratch or from a suggested page template.<br>Note also that only edition of HTML source will be possible when a page content has been initialized by grabbing it from an external page ("Online" editor will NOT be available)
     OnlyEditionOfSourceForGrabbedContent=Only edition of HTML source is possible when content was grabbed from an external site
     GrabImagesInto=Grab also images found into css and page.
     ImagesShouldBeSavedInto=Images should be saved into directory
    @@ -83,4 +87,9 @@ SubdirOfPage=Sub-directory dedicated to page
     AliasPageAlreadyExists=Alias page <strong>%s</strong> already exists
     CorporateHomePage=Corporate Home page
     EmptyPage=Empty page
    -ExternalURLMustStartWithHttp=External URL must start with http:// or https://
    \ No newline at end of file
    +ExternalURLMustStartWithHttp=External URL must start with http:// or https://
    +ZipOfWebsitePackageToImport=Zip file of website package
    +ShowSubcontainers=Show included containers
    +InternalURLOfPage=Internal URL of page
    +ThisPageIsTranslationOf=This page/container is translation of
    +ThisPageHasTranslationPages=This page/container has translation
    \ No newline at end of file
    diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang
    index fa02317b321..c2c384793c4 100644
    --- a/htdocs/langs/en_US/withdrawals.lang
    +++ b/htdocs/langs/en_US/withdrawals.lang
    @@ -26,7 +26,7 @@ LastWithdrawalReceipt=Latest %s direct debit receipts
     MakeWithdrawRequest=Make a direct debit payment request
     WithdrawRequestsDone=%s direct debit payment requests recorded
     ThirdPartyBankCode=Third party bank code
    -NoInvoiceCouldBeWithdrawed=No invoice withdrawed with success. Check that invoices are on companies with a valid default BAN and that BAN has a RUM with mode <strong>%s</strong>.
    +NoInvoiceCouldBeWithdrawed=No invoice debited successfully. Check that invoices are on companies with a valid IBAN and that IBAN has a UMR (Unique Mandate Reference) with mode <strong>%s</strong>.
     ClassCredited=Classify credited
     ClassCreditedConfirm=Are you sure you want to classify this withdrawal receipt as credited on your bank account?
     TransData=Transmission date
    @@ -61,7 +61,7 @@ CreateAll=Create direct debit file (all)
     CreateGuichet=Only office
     CreateBanque=Only bank
     OrderWaiting=Waiting for treatment
    -NotifyTransmision=Withdrawal Transmission 
    +NotifyTransmision=Withdrawal Transmission
     NotifyCredit=Withdrawal Credit
     NumeroNationalEmetter=National Transmitter Number
     WithBankUsingRIB=For bank accounts using RIB
    @@ -80,7 +80,7 @@ RUM=UMR
     RUMLong=Unique Mandate Reference
     RUMWillBeGenerated=If empty, UMR number will be generated once bank account information are saved
     WithdrawMode=Direct debit mode (FRST or RECUR)
    -WithdrawRequestAmount=Amount of Direct debit request: 
    +WithdrawRequestAmount=Amount of Direct debit request:
     WithdrawRequestErrorNilAmount=Unable to create direct debit request for empty amount.
     SepaMandate=SEPA Direct Debit Mandate
     SepaMandateShort=SEPA Mandate
    @@ -103,7 +103,7 @@ SEPAFRST=SEPA FRST
     ExecutionDate=Execution date
     CreateForSepa=Create direct debit file
     
    -### Notifications 
    +### Notifications
     InfoCreditSubject=Payment of direct debit payment order %s by the bank
     InfoCreditMessage=The direct debit payment order %s has been paid by the bank<br>Data of payment: %s
     InfoTransSubject=Transmission of direct debit payment order %s to bank
    diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang
    index ed19a531c07..c16caf44765 100644
    --- a/htdocs/langs/en_US/workflow.lang
    +++ b/htdocs/langs/en_US/workflow.lang
    @@ -1,20 +1,20 @@
    -# Dolibarr language file - Source file is en_US - workflow 
    +# Dolibarr language file - Source file is en_US - workflow
     WorkflowSetup=Workflow module setup
    -WorkflowDesc=This module is designed to modify the behaviour of automatic actions into application. By default, workflow is open (you can do things in the order you want). You can activate the automatic actions you are interested in.
    +WorkflowDesc=This module provides some automatic actions. By default, the workflow is open (you can do things in the order you want) but here you can activate some automatic actions.
     ThereIsNoWorkflowToModify=There is no workflow modifications available with the activated modules.
     # Autocreate
    -descWORKFLOW_PROPAL_AUTOCREATE_ORDER=Automatically create a customer order after a commercial proposal is signed (new order will have same amount than proposal)
    -descWORKFLOW_PROPAL_AUTOCREATE_INVOICE=Automatically create a customer invoice after a commercial proposal is signed (new invoice will have same amount than proposal)
    +descWORKFLOW_PROPAL_AUTOCREATE_ORDER=Automatically create a customer order after a commercial proposal is signed (the new order will have same amount as the proposal)
    +descWORKFLOW_PROPAL_AUTOCREATE_INVOICE=Automatically create a customer invoice after a commercial proposal is signed (the new invoice will have same amount as the proposal)
     descWORKFLOW_CONTRACT_AUTOCREATE_INVOICE=Automatically create a customer invoice after a contract is validated
    -descWORKFLOW_ORDER_AUTOCREATE_INVOICE=Automatically create a customer invoice after a customer order is closed (new invoice will have same amount than order)
    +descWORKFLOW_ORDER_AUTOCREATE_INVOICE=Automatically create a customer invoice after a customer order is closed (the new invoice will have same amount as the order)
     # Autoclassify customer proposal or order
    -descWORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL=Classify linked source proposal(s) to billed when customer order is set to billed (and if amount of the order is same than total amount of signed linked proposals)
    -descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal(s) to billed when customer invoice is validated (and if amount of the invoice is same than total amount of signed linked proposals)
    -descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source customer order(s) to billed when customer invoice is validated (and if amount of the invoice is same than total amount of linked orders)
    -descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source customer order(s) to billed when customer invoice is set to paid (and if amount of the invoice is same than total amount of linked orders)
    -descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source customer order to shipped when a shipment is validated (and if quantity shipped by all shipments is the same as in the order to update)
    +descWORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as billed when customer order is set to billed (and if the amount of the order is the same as the total amount of the signed linked proposal)
    +descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the signed linked proposal)
    +descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source customer order as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order)
    +descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source customer order as billed when customer invoice is set to paid (and if the amount of the invoice is the same as the total amount of the linked order)
    +descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source customer order as shipped when a shipment is validated (and if the quantity shipped by all shipments is the same as in the order to update)
     # Autoclassify supplier order
    -descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal(s) to billed when vendor invoice is validated (and if amount of the invoice is same than total amount of linked proposals)
    -descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order(s) to billed when vendor invoice is validated (and if amount of the invoice is same than total amount of linked orders)
    +descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked proposal)
    +descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order)
     AutomaticCreation=Automatic creation
    -AutomaticClassification=Automatic classification
    \ No newline at end of file
    +AutomaticClassification=Automatic classification
    diff --git a/htdocs/langs/es_ES/cashdesk.lang b/htdocs/langs/es_ES/cashdesk.lang
    index 326ccef53bb..518874346bf 100644
    --- a/htdocs/langs/es_ES/cashdesk.lang
    +++ b/htdocs/langs/es_ES/cashdesk.lang
    @@ -32,3 +32,10 @@ DeleteArticle=Haga clic para quitar este artículo
     FilterRefOrLabelOrBC=Búsqueda (Ref/Etiq.)
     UserNeedPermissionToEditStockToUsePos=Ha configurado el decremento de stock en la creación de facturas, por lo que el usuario que utilice el TPV deberá tener permiso para editar stock.
     DolibarrReceiptPrinter=Impresora de tickets Dolibarr
    +CloseBill=Cerrar venta
    +Floors=Salones
    +Floor=Salón
    +AddTable=Añadir mesa
    +Place=Puesto
    +TakeboxNecesary=Aplicación 'TakeBOX' requerida
    +OrderPrinters=Impresoras de pedido
    diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang
    index 58cd1d09b11..e81fbfcdbb8 100644
    --- a/htdocs/langs/fr_FR/admin.lang
    +++ b/htdocs/langs/fr_FR/admin.lang
    @@ -651,6 +651,7 @@ Permission32=Créer/modifier les produits
     Permission34=Supprimer les produits
     Permission36=Voir/gérer les produits cachés
     Permission38=Exporter les produits
    +Permission39=Outrepasser le prix de vente minimum d'un produit
     Permission41=Lire les projets et tâches (partagés ou dont vous êtes un contact). Permet la saisie de temps passé, par vous et votre hiérarchie (vos subordonnés), sur les tâches assignées.
     Permission42=Créer/modifier les projets (projets partagés et projets pour lesquels je suis contact). Permet aussi de créer des tâches et d'assigner des utilisateurs aux projets et tâches.
     Permission44=Supprimer les projets et tâches (partagés ou dont je suis contact)
    diff --git a/htdocs/langs/fr_FR/cashdesk.lang b/htdocs/langs/fr_FR/cashdesk.lang
    index 0227aee95ea..e152f2c4318 100644
    --- a/htdocs/langs/fr_FR/cashdesk.lang
    +++ b/htdocs/langs/fr_FR/cashdesk.lang
    @@ -32,3 +32,12 @@ DeleteArticle=Cliquez pour enlever cet article
     FilterRefOrLabelOrBC=Recherche (Ref/Lib.)
     UserNeedPermissionToEditStockToUsePos=Vous avez demandé de réduire le stock sur création de facture, aussi l'utilisateur qui utilise le Point De Vente doit avoir la permission d'éditer le stock.
     DolibarrReceiptPrinter=Imprimante reçu
    +PointOfSale=Point de Vente
    +CloseBill=Fermer Bill
    +Floors=Étages
    +Floor=Étage
    +AddTable=Ajouter une table
    +Place=Endroit
    +TakeboxNecesary='TakeBOX' Application requise
    +OrderPrinters=Commande imprimantes
    +SearchProduct=Recherche produit
    diff --git a/htdocs/langs/fr_FR/users.lang b/htdocs/langs/fr_FR/users.lang
    index e0f461cd196..fa5e772fe7e 100644
    --- a/htdocs/langs/fr_FR/users.lang
    +++ b/htdocs/langs/fr_FR/users.lang
    @@ -6,7 +6,7 @@ Permission=Droit
     Permissions=Droits
     EditPassword=Modifier mot de passe
     SendNewPassword=Régénérer et envoyer mot de passe
    -SendNewPasswordLink=Envoyer le lien pour réinitialiser le mot de passe
    +SendNewPasswordLink=Réinitialiser le mot de passe
     ReinitPassword=Régénérer mot de passe
     PasswordChangedTo=Mot de passe modifié en: %s
     SubjectNewPassword=Votre mot de passe pour %s
    diff --git a/htdocs/livraison/card.php b/htdocs/livraison/card.php
    index d6cefb24d83..06b9d6e5682 100644
    --- a/htdocs/livraison/card.php
    +++ b/htdocs/livraison/card.php
    @@ -5,7 +5,7 @@
      * Copyright (C) 2005-2014	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2007		Franky Van Liedekerke	<franky.van.liedekerke@telenet.be>
      * Copyright (C) 2013       Florian Henry		  	<florian.henry@open-concept.pro>
    - * Copyright (C) 2015			  Claudio Aschieri		<c.aschieri@19.coop>
    + * Copyright (C) 2015	    Claudio Aschieri		<c.aschieri@19.coop>
      *
      * 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
    @@ -241,7 +241,6 @@ if ($action == 'update_extras_line')
     			$error++;
     		}
     	}
    -
     }
     
     
    @@ -292,6 +291,7 @@ elseif ($action == 'remove_file')
     }
     */
     
    +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
     
     /*
      *	View
    @@ -356,7 +356,6 @@ else
     			{
     				$expedition_id = GETPOST("expid");
     				print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id.'&expid='.$expedition_id.'&backtopage='.urlencode($backtopage),$langs->trans("DeleteDeliveryReceipt"),$langs->trans("DeleteDeliveryReceiptConfirm",$object->ref),'confirm_delete','','',1);
    -
     			}
     
     			/*
    @@ -365,7 +364,6 @@ else
     			if ($action == 'valid')
     			{
     				print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans("ValidateDeliveryReceipt"),$langs->trans("ValidateDeliveryReceiptConfirm",$object->ref),'confirm_valid','','',1);
    -
     			}
     
     
    @@ -506,7 +504,7 @@ else
     				print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
     				print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     				print '<input type="hidden" name="action" value="setdate_livraison">';
    -				$form->select_date($object->date_delivery?$object->date_delivery:-1, 'liv_', 1, 1, '', "setdate_livraison", 1, 1);
    +				print $form->selectDate($object->date_delivery?$object->date_delivery:-1, 'liv_', 1, 1, '', "setdate_livraison", 1, 1);
     				print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">';
     				print '</form>';
     			}
    @@ -586,7 +584,7 @@ else
     			print '</div>';
     
     			/*
    -			 * Lignes produits
    +			 * Products lines
     			 */
     
     			$num_prod = count($object->lines);
    @@ -604,11 +602,8 @@ else
     				print '<td align="center">'.$langs->trans("QtyReceived").'</td>';
     				print "</tr>\n";
     			}
    -			$var=true;
     			while ($i < $num_prod)
     			{
    -
    -
     				print '<tr class="oddeven">';
     				if ($object->lines[$i]->fk_product > 0)
     				{
    @@ -686,7 +681,7 @@ else
     						$line->array_options = array_merge($line->array_options, $srcLine->array_options);
     					}
     					print '<tr class="oddeven">';
    -					print $line->showOptionals($extrafieldsline, $mode, array('style'=>$bc[$var], 'colspan'=>$colspan),$i);
    +					print $line->showOptionals($extrafieldsline, $mode, array('style'=>'class="oddeven"', 'colspan'=>$colspan),$i);
     					print '</tr>';
     				}
     
    @@ -784,6 +779,6 @@ else
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php
    index 46b3c113ff2..c5e4b36ed25 100644
    --- a/htdocs/livraison/class/livraison.class.php
    +++ b/htdocs/livraison/class/livraison.class.php
    @@ -3,8 +3,8 @@
      * Copyright (C) 2005-2014 Regis Houssin         <regis.houssin@capnetworks.com>
      * Copyright (C) 2006-2007 Laurent Destailleur   <eldy@users.sourceforge.net>
      * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
    - * Copyright (C) 2011-2012 Philippe Grand	     <philippe.grand@atoo-net.com>
    - * Copyright (C) 2013      Florian Henry		  	<florian.henry@open-concept.pro>
    + * Copyright (C) 2011-2018 Philippe Grand	     <philippe.grand@atoo-net.com>
    + * Copyright (C) 2013      Florian Henry	     <florian.henry@open-concept.pro>
      * Copyright (C) 2014-2015 Marcos García         <marcosgdf@gmail.com>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -24,7 +24,7 @@
     /**
      *  \file       htdocs/livraison/class/livraison.class.php
      *  \ingroup    delivery
    - *  \brief      Fichier de la classe de gestion des bons de livraison
    + *  \brief      Delivery Order Management Class File
      */
     
     require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
    @@ -39,19 +39,34 @@ if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande
      */
     class Livraison extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element="delivery";
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element="fk_livraison";
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element="livraison";
    +
    +	/**
    +	 * @var int    Name of subtable line
    +	 */
     	public $table_element_line="livraisondet";
     
    -	var $brouillon;
    -	var $socid;
    -	var $ref_customer;
    +	public $brouillon;
    +	public $socid;
    +	public $ref_customer;
     
    -	var $date_delivery;    // Date really received
    -	var $date_creation;
    -	var $date_valid;
    -	var $model_pdf;
    +	public $date_delivery;    // Date really received
    +	public $date_creation;
    +	public $date_valid;
    +	public $model_pdf;
     
     	/**
     	 * Constructor
    @@ -149,7 +164,7 @@ class Livraison extends CommonObject
     
     
     				/*
    -				 *  Insertion des produits dans la base
    +				 *  Inserting products into the database
     				 */
     				$num=count($this->lines);
     				for ($i = 0; $i < $num; $i++)
    @@ -212,6 +227,7 @@ class Livraison extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Create a line
     	 *
    @@ -223,6 +239,7 @@ class Livraison extends CommonObject
     	 */
     	function create_line($origin_id, $qty, $fk_product, $description)
     	{
    +        // phpcs:enable
     		$error = 0;
     		$idprod = $fk_product;
     		$j = 0;
    @@ -301,7 +318,7 @@ class Livraison extends CommonObject
     
     				if ($this->statut == 0) $this->brouillon = 1;
     
    -				// Retreive all extrafield
    +				// Retreive all extrafields
     				// fetch optionals attributes and labels
     				$this->fetch_optionals();
     
    @@ -352,7 +369,7 @@ class Livraison extends CommonObject
     		{
     			if (! empty($conf->global->LIVRAISON_ADDON_NUMBER))
     			{
    -				// Definition du nom de module de numerotation de commande
    +				// Setting the command numbering module name
     				$modName = $conf->global->LIVRAISON_ADDON_NUMBER;
     
     				if (is_readable(DOL_DOCUMENT_ROOT .'/core/modules/livraison/'.$modName.'.php'))
    @@ -361,7 +378,7 @@ class Livraison extends CommonObject
     
     					$now=dol_now();
     
    -					// Recuperation de la nouvelle reference
    +					// Retrieving the new reference
     					$objMod = new $modName($this->db);
     					$soc = new Societe($this->db);
     					$soc->fetch($this->socid);
    @@ -376,8 +393,7 @@ class Livraison extends CommonObject
     		            }
                 		$this->newref = $numref;
     
    -					// Tester si non deja au statut valide. Si oui, on arrete afin d'eviter
    -					// de decrementer 2 fois le stock.
    +					// Test if is not already in valid status. If so, we stop to avoid decrementing the stock twice.
     					$sql = "SELECT ref";
     					$sql.= " FROM ".MAIN_DB_PREFIX."livraison";
     					$sql.= " WHERE ref = '".$this->db->escape($numref)."'";
    @@ -483,15 +499,17 @@ class Livraison extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 * 	Cree le bon de livraison depuis une expedition existante
    +	 * 	Creating the delivery slip from an existing shipment
     	 *
    -	 *	@param	User	$user            Utilisateur qui cree
    -	 *	@param  int		$sending_id      Id de l'expedition qui sert de modele
    +	 *	@param	User	$user            User who creates
    +	 *	@param  int		$sending_id      Id of the expedition that serves as a model
     	 *	@return	integer
     	 */
     	function create_from_sending($user, $sending_id)
     	{
    +        // phpcs:enable
     		$expedition = new Expedition($this->db);
     		$result=$expedition->fetch($sending_id);
     
    @@ -528,6 +546,7 @@ class Livraison extends CommonObject
     		return $this->create($user);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Update a livraison line (only extrafields)
     	 *
    @@ -537,6 +556,7 @@ class Livraison extends CommonObject
     	 */
     	function update_line($id, $array_options=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$error = 0;
     
    @@ -725,6 +745,7 @@ class Livraison extends CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Load lines
     	 *
    @@ -732,6 +753,7 @@ class Livraison extends CommonObject
     	 */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		$this->lines = array();
     
     		$sql = "SELECT ld.rowid, ld.fk_product, ld.description, ld.subprice, ld.total_ht, ld.qty as qty_shipped, ld.fk_origin_line, ";
    @@ -794,6 +816,7 @@ class Livraison extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Renvoi le libelle d'un statut donne
     	 *
    @@ -803,31 +826,32 @@ class Livraison extends CommonObject
     	 */
     	function LibStatut($statut,$mode)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode==0)
     		{
     			if ($statut==-1) return $langs->trans('StatusDeliveryCanceled');
    -			if ($statut==0)  return $langs->trans('StatusDeliveryDraft');
    -			if ($statut==1)  return $langs->trans('StatusDeliveryValidated');
    +			elseif ($statut==0)  return $langs->trans('StatusDeliveryDraft');
    +			elseif ($statut==1)  return $langs->trans('StatusDeliveryValidated');
     		}
    -		if ($mode==1)
    +		elseif ($mode==1)
     		{
     			if ($statut==-1) return $langs->trans($this->statuts[$statut]);
    -			if ($statut==0)  return $langs->trans($this->statuts[$statut]);
    -			if ($statut==1)  return $langs->trans($this->statuts[$statut]);
    +			elseif ($statut==0)  return $langs->trans($this->statuts[$statut]);
    +			elseif ($statut==1)  return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==-1) return img_picto($langs->trans('StatusDeliveryCanceled'),'statut5').' '.$langs->trans('StatusDeliveryCanceled');
    -			if ($statut==0)  return img_picto($langs->trans('StatusDeliveryDraft'),'statut0').' '.$langs->trans('StatusDeliveryDraft');
    -			if ($statut==1)  return img_picto($langs->trans('StatusDeliveryValidated'),'statut4').' '.$langs->trans('StatusDeliveryValidated');
    +			elseif ($statut==0)  return img_picto($langs->trans('StatusDeliveryDraft'),'statut0').' '.$langs->trans('StatusDeliveryDraft');
    +			elseif ($statut==1)  return img_picto($langs->trans('StatusDeliveryValidated'),'statut4').' '.$langs->trans('StatusDeliveryValidated');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($statut==-1) return $langs->trans('StatusDeliveryCanceled').' '.img_picto($langs->trans('StatusDeliveryCanceled'),'statut5');
    -			if ($statut==0)  return $langs->trans('StatusDeliveryDraft').' '.img_picto($langs->trans('StatusDeliveryDraft'),'statut0');
    -			if ($statut==1)  return $langs->trans('StatusDeliveryValidated').' '.img_picto($langs->trans('StatusDeliveryValidated'),'statut4');
    +			elseif ($statut==0)  return $langs->trans('StatusDeliveryDraft').' '.img_picto($langs->trans('StatusDeliveryDraft'),'statut0');
    +			elseif ($statut==1)  return $langs->trans('StatusDeliveryValidated').' '.img_picto($langs->trans('StatusDeliveryValidated'),'statut4');
     		}
     	}
     
    @@ -965,6 +989,7 @@ class Livraison extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Set the planned delivery date
     	 *
    @@ -974,6 +999,7 @@ class Livraison extends CommonObject
     	 */
     	function set_date_livraison($user, $date_livraison)
     	{
    +        // phpcs:enable
     		if ($user->rights->expedition->creer)
     		{
     			$sql = "UPDATE ".MAIN_DB_PREFIX."livraison";
    @@ -1047,17 +1073,19 @@ class Livraison extends CommonObject
     
     		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
     	}
    -
     }
     
     
     
     /**
    - *  Classe de gestion des lignes de bons de livraison
    + *  Management class of delivery note lines
      */
     class LivraisonLigne extends CommonObjectLine
     {
    -	var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	// From llx_expeditiondet
     	var $qty;
    @@ -1066,23 +1094,39 @@ class LivraisonLigne extends CommonObjectLine
     	var $price;
     	var $fk_product;
     	var $origin_id;
    -	var $label;       // Label produit
    -	var $description;  // Description produit
    +
    +    /**
    +     * @var string delivery note lines label
    +     */
    +    public $label;
    +
    +	/**
    +	 * @var string product description
    +	 */
    +	public $description;
    +
     	/**
     	 * @deprecated
     	 * @see product_ref
     	 */
    -	var $ref;
    +	public $ref;
     	/**
     	 * @deprecated
     	 * @see product_label;
     	 */
    -	var $libelle;
    +	public $libelle;
     
     	public $product_ref;
     	public $product_label;
     
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='livraisondet';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='livraisondet';
     
     	/**
    @@ -1094,5 +1138,4 @@ class LivraisonLigne extends CommonObjectLine
     	{
     		$this->db=$db;
     	}
    -
     }
    diff --git a/htdocs/loan/calcmens.php b/htdocs/loan/calcmens.php
    index fbe1cecab2d..df6db76e1f2 100644
    --- a/htdocs/loan/calcmens.php
    +++ b/htdocs/loan/calcmens.php
    @@ -50,7 +50,7 @@ $echance++;
     $capital=$cap_rest;
     while ($echance<=$nbterm) {
     
    -	$mens = round($object->calc_mens($capital,$rate,$nbterm-$echance+1),2,PHP_ROUND_HALF_UP);
    +	$mens = round($object->calcMonthlyPayments($capital, $rate, $nbterm-$echance+1), 2, PHP_ROUND_HALF_UP);
     
     	$int = ($capital*($rate/12));
     	$int = round($int,2,PHP_ROUND_HALF_UP);
    @@ -63,4 +63,3 @@ while ($echance<=$nbterm) {
     }
     
     echo json_encode($output);
    -
    diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php
    index 79569f62df3..25651ac842a 100644
    --- a/htdocs/loan/card.php
    +++ b/htdocs/loan/card.php
    @@ -238,7 +238,7 @@ if (empty($reshook))
     
     $form = new Form($db);
     $formproject = new FormProjets($db);
    -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db);
    +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db);
     
     $title = $langs->trans("Loan") . ' - ' . $langs->trans("Card");
     $help_url = 'EN:Module_Loan|FR:Module_Emprunt';
    @@ -286,13 +286,13 @@ if ($action == 'create')
     	// Date Start
     	print "<tr>";
     	print '<td class="fieldrequired">'.$langs->trans("DateStart").'</td><td>';
    -	print $form->select_date($datestart?$datestart:-1,'start','','','','add',1,1,1);
    +	print $form->selectDate($datestart?$datestart:-1,'start','','','','add',1,1);
     	print '</td></tr>';
     
     	// Date End
     	print "<tr>";
     	print '<td class="fieldrequired">'.$langs->trans("DateEnd").'</td><td>';
    -	print $form->select_date($dateend?$dateend:-1,'end','','','','add',1,1,1);
    +	print $form->selectDate($dateend?$dateend:-1,'end','','','','add',1,1);
     	print '</td></tr>';
     
     	// Number of terms
    @@ -501,7 +501,7 @@ if ($id > 0)
     		print "<td>";
     		if ($action == 'edit')
     		{
    -			print $form->select_date($object->datestart, 'start', 0, 0, 0, 'update', 1, 0, 1);
    +			print $form->selectDate($object->datestart, 'start', 0, 0, 0, 'update', 1, 0);
     		}
     		else
     		{
    @@ -514,7 +514,7 @@ if ($id > 0)
     		print "<td>";
     		if ($action == 'edit')
     		{
    -			print $form->select_date($object->dateend, 'end', 0, 0, 0, 'update', 1, 0, 1);
    +			print $form->selectDate($object->dateend, 'end', 0, 0, 0, 'update', 1, 0);
     		}
     		else
     		{
    @@ -805,6 +805,6 @@ if ($id > 0)
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php
    index a4518960839..0e4542b1d20 100644
    --- a/htdocs/loan/class/loan.class.php
    +++ b/htdocs/loan/class/loan.class.php
    @@ -1,6 +1,6 @@
     <?php
     /* Copyright (C) 2014-2018  Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2015       Frederic France      <frederic.france@free.fr>
    + * Copyright (C) 2015-2018  Frédéric France      <frederic.france@netlogic.fr>
      *
      * 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
    @@ -29,16 +29,33 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class Loan extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='loan';
    +
     	public $table='loan';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='loan';
     
     	public $picto = 'bill';
     
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
     	public $datestart;
     	public $dateend;
    -	public $label;
    +
    +    /**
    +     * @var string Loan label
    +     */
    +    public $label;
    +
     	public $capital;
     	public $nbterm;
     	public $rate;
    @@ -49,9 +66,25 @@ class Loan extends CommonObject
     	public $date_creation;
     	public $date_modification;
     	public $date_validation;
    +
    +	/**
    +     * @var int Bank ID
    +     */
     	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_project;
     
     
    @@ -63,7 +96,6 @@ class Loan extends CommonObject
     	function __construct($db)
     	{
     		$this->db = $db;
    -		return 1;
     	}
     
     	/**
    @@ -142,10 +174,10 @@ class Loan extends CommonObject
     		if (isset($this->account_capital)) $this->account_capital = trim($this->account_capital);
     		if (isset($this->account_insurance)) $this->account_insurance = trim($this->account_insurance);
     		if (isset($this->account_interest)) $this->account_interest = trim($this->account_interest);
    -		if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank);
    -		if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif);
    -		if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project);
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
    +		if (isset($this->fk_project)) $this->fk_project = (int) $this->fk_project;
     
     		// Check parameters
     		if (! $newcapital > 0 || empty($this->datestart) || empty($this->dateend))
    @@ -278,7 +310,6 @@ class Loan extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     
    @@ -326,6 +357,7 @@ class Loan extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Tag loan as payed completely
     	 *
    @@ -334,6 +366,7 @@ class Loan extends CommonObject
     	 */
     	function set_paid($user)
     	{
    +        // phpcs:enable
     		$sql = "UPDATE ".MAIN_DB_PREFIX."loan SET";
     		$sql.= " paid = 1";
     		$sql.= " WHERE rowid = ".$this->id;
    @@ -358,6 +391,7 @@ class Loan extends CommonObject
     		return $this->LibStatut($this->paid,$mode,$alreadypaid);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return label for given status
     	 *
    @@ -368,51 +402,47 @@ class Loan extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0,$alreadypaid=-1)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->loadLangs(array("customers","bills"));
     
    -		if ($mode == 0)
    +		if ($mode == 0 || $mode == 1)
     		{
     			if ($statut ==  0) return $langs->trans("Unpaid");
    -			if ($statut ==  1) return $langs->trans("Paid");
    +			elseif ($statut ==  1) return $langs->trans("Paid");
     		}
    -		if ($mode == 1)
    -		{
    -			if ($statut ==  0) return $langs->trans("Unpaid");
    -			if ($statut ==  1) return $langs->trans("Paid");
    -		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut ==  0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1').' '.$langs->trans("Unpaid");
    -			if ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted");
    -			if ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid");
    +			elseif ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted");
    +			elseif ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid");
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut ==  0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1');
    -			if ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3');
    -			if ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6');
    +			elseif ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3');
    +			elseif ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut ==  0 && $alreadypaid <= 0) return img_picto($langs->trans("Unpaid"), 'statut1').' '.$langs->trans("Unpaid");
    -			if ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted");
    -			if ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid");
    +			elseif ($statut ==  0 && $alreadypaid > 0) return img_picto($langs->trans("BillStatusStarted"), 'statut3').' '.$langs->trans("BillStatusStarted");
    +			elseif ($statut ==  1) return img_picto($langs->trans("Paid"), 'statut6').' '.$langs->trans("Paid");
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut ==  0 && $alreadypaid <= 0) return $langs->trans("Unpaid").' '.img_picto($langs->trans("Unpaid"), 'statut1');
    -			if ($statut ==  0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3');
    -			if ($statut ==  1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6');
    +			elseif ($statut ==  0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3');
    +			elseif ($statut ==  1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($statut ==  0 && $alreadypaid <= 0) return $langs->trans("Unpaid").' '.img_picto($langs->trans("Unpaid"), 'statut1');
    -			if ($statut ==  0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3');
    -			if ($statut ==  1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6');
    +			elseif ($statut ==  0 && $alreadypaid > 0) return $langs->trans("BillStatusStarted").' '.img_picto($langs->trans("BillStatusStarted"), 'statut3');
    +			elseif ($statut ==  1) return $langs->trans("Paid").' '.img_picto($langs->trans("Paid"), 'statut6');
     		}
     
    -		return "Error, mode/status not found";
    +		else return "Error, mode/status not found";
     	}
     
     
    @@ -431,9 +461,9 @@ class Loan extends CommonObject
     
     		$tooltip = '<u>' . $langs->trans("ShowLoan") . '</u>';
     		if (! empty($this->ref))
    -			$tooltip .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
    +			$tooltip .= '<br><strong>' . $langs->trans('Ref') . ':</strong> ' . $this->ref;
     		if (! empty($this->label))
    -			$tooltip .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $this->label;
    +			$tooltip .= '<br><strong>' . $langs->trans('Label') . ':</strong> ' . $this->label;
     
     		$linkstart = '<a href="'.DOL_URL_ROOT.'/loan/card.php?id='.$this->id.'" title="'.str_replace('\n', '', dol_escape_htmltag($tooltip, 1)).'" class="classfortooltip">';
     		$linkend = '</a>';
    @@ -445,7 +475,7 @@ class Loan extends CommonObject
     
     		return $result;
     	}
    -	
    +
     	/**
     	 *  Initialise an instance with random values.
     	 *  Used to build previews or test instances.
    @@ -456,9 +486,9 @@ class Loan extends CommonObject
     	function initAsSpecimen()
     	{
     	    global $user, $langs, $conf;
    -	    
    +
     	    $now=dol_now();
    -	    
    +
     	    // Initialise parameters
     	    $this->id = 0;
     	    $this->fk_bank = 1;
    diff --git a/htdocs/loan/class/loanschedule.class.php b/htdocs/loan/class/loanschedule.class.php
    index a430f79366e..7373bfb4ab1 100644
    --- a/htdocs/loan/class/loanschedule.class.php
    +++ b/htdocs/loan/class/loanschedule.class.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2017	Florian HENRY <florian.henry@atm-consulting.fr>
    +/* Copyright (C) 2017       Florian HENRY           <florian.henry@atm-consulting.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -17,8 +18,8 @@
     
     /**
      *      \file       htdocs/loan/class/loanschedule.class.php
    - *		\ingroup    facture
    - *		\brief      File of class to manage schedule of loans
    + *      \ingroup    loan
    + *      \brief      File of class to manage schedule of loans
      */
     
     require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
    @@ -29,36 +30,76 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class LoanSchedule extends CommonObject
     {
    -	public $element='loan_schedule';			//!< Id that identify managed objects
    -	public $table_element='loan_schedule';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='loan_schedule';
     
    -	var $fk_loan;
    -	var $datec='';
    -	var $tms='';
    -	var $datep='';
    -    var $amounts=array();   // Array of amounts
    -    var $amount_capital;    // Total amount of payment
    -	var $amount_insurance;
    -	var $amount_interest;
    -	var $fk_typepayment;
    -	var $num_payment;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    -	var $lines=array();
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='loan_schedule';
    +
    +    /**
    +     * @var int Loan ID
    +     */
    +    public $fk_loan;
    +
    +    /**
    +     * @var string Create date
    +     */
    +    public $datec='';
    +	public $tms='';
    +
    +    /**
    +     * @var string Payment date
    +     */
    +    public $datep='';
    +
    +    public $amounts=array();   // Array of amounts
    +    public $amount_capital;    // Total amount of payment
    +	public $amount_insurance;
    +	public $amount_interest;
    +
    +    /**
    +     * @var int Payment Type ID
    +     */
    +    public $fk_typepayment;
    +
    +    /**
    +     * @var int Payment ID
    +     */
    +    public $num_payment;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_bank;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_user_creat;
    +
    +    /**
    +     * @var int User ID
    +     */
    +    public $fk_user_modif;
    +
    +	public $lines=array();
     
     	/**
     	 * @deprecated
     	 * @see amount, amounts
     	 */
    -	var $total;
    +	public $total;
     
     	/**
     	 *	Constructor
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		$this->db = $db;
     	}
    @@ -70,7 +111,7 @@ class LoanSchedule extends CommonObject
     	 *  @param      User		$user   User making payment
     	 *  @return     int     			<0 if KO, id of payment if OK
     	 */
    -	function create($user)
    +	public function create($user)
     	{
     		global $conf, $langs;
     
    @@ -79,21 +120,21 @@ class LoanSchedule extends CommonObject
             $now=dol_now();
     
             // Validate parameters
    -		if (! $this->datepaid)
    +		if (! $this->datep)
     		{
     			$this->error='ErrorBadValueForParameter';
     			return -1;
     		}
     
     		// Clean parameters
    -		if (isset($this->fk_loan)) 			$this->fk_loan = trim($this->fk_loan);
    +		if (isset($this->fk_loan)) $this->fk_loan = (int) $this->fk_loan;
     		if (isset($this->amount_capital))	$this->amount_capital = trim($this->amount_capital?$this->amount_capital:0);
     		if (isset($this->amount_insurance))	$this->amount_insurance = trim($this->amount_insurance?$this->amount_insurance:0);
     		if (isset($this->amount_interest))	$this->amount_interest = trim($this->amount_interest?$this->amount_interest:0);
    -		if (isset($this->fk_typepayment))	$this->fk_typepayment = trim($this->fk_typepayment);
    -		if (isset($this->fk_bank))			$this->fk_bank = trim($this->fk_bank);
    -		if (isset($this->fk_user_creat))	$this->fk_user_creat = trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif))	$this->fk_user_modif = trim($this->fk_user_modif);
    +		if (isset($this->fk_typepayment)) $this->fk_typepayment = (int) $this->fk_typepayment;
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
     
             $totalamount = $this->amount_capital + $this->amount_insurance + $this->amount_interest;
             $totalamount = price2num($totalamount);
    @@ -112,7 +153,7 @@ class LoanSchedule extends CommonObject
     			$sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,";
     			$sql.= " fk_typepayment, fk_user_creat, fk_bank)";
     			$sql.= " VALUES (".$this->fk_loan.", '".$this->db->idate($now)."',";
    -			$sql.= " '".$this->db->idate($this->datepaid)."',";
    +			$sql.= " '".$this->db->idate($this->datep)."',";
     			$sql.= " ".$this->amount_capital.",";
     			$sql.= " ".$this->amount_insurance.",";
     			$sql.= " ".$this->amount_interest.",";
    @@ -131,7 +172,6 @@ class LoanSchedule extends CommonObject
                     $this->error=$this->db->lasterror();
     				$error++;
     			}
    -
     		}
     
     		if ($totalamount != 0 && ! $error)
    @@ -155,7 +195,7 @@ class LoanSchedule extends CommonObject
     	 *  @param	int		$id         Id object
     	 *  @return int         		<0 if KO, >0 if OK
     	 */
    -	function fetch($id)
    +	public function fetch($id)
     	{
     		global $langs;
     		$sql = "SELECT";
    @@ -183,37 +223,35 @@ class LoanSchedule extends CommonObject
     
     		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
     		$resql=$this->db->query($sql);
    -		if ($resql)
    -	{
    -		if ($this->db->num_rows($resql))
    -		{
    -			$obj = $this->db->fetch_object($resql);
    +		if ($resql) {
    +            if ($this->db->num_rows($resql)) {
    +                $obj = $this->db->fetch_object($resql);
     
    -			$this->id = $obj->rowid;
    -			$this->ref = $obj->rowid;
    +                $this->id = $obj->rowid;
    +                $this->ref = $obj->rowid;
     
    -			$this->fk_loan = $obj->fk_loan;
    -			$this->datec = $this->db->jdate($obj->datec);
    -			$this->tms = $this->db->jdate($obj->tms);
    -			$this->datep = $this->db->jdate($obj->datep);
    -			$this->amount_capital = $obj->amount_capital;
    -			$this->amount_insurance = $obj->amount_insurance;
    -			$this->amount_interest = $obj->amount_interest;
    -			$this->fk_typepayment = $obj->fk_typepayment;
    -			$this->num_payment = $obj->num_payment;
    -			$this->note_private = $obj->note_private;
    -			$this->note_public = $obj->note_public;
    -			$this->fk_bank = $obj->fk_bank;
    -			$this->fk_user_creat = $obj->fk_user_creat;
    -			$this->fk_user_modif = $obj->fk_user_modif;
    +                $this->fk_loan = $obj->fk_loan;
    +                $this->datec = $this->db->jdate($obj->datec);
    +                $this->tms = $this->db->jdate($obj->tms);
    +                $this->datep = $this->db->jdate($obj->datep);
    +                $this->amount_capital = $obj->amount_capital;
    +                $this->amount_insurance = $obj->amount_insurance;
    +                $this->amount_interest = $obj->amount_interest;
    +                $this->fk_typepayment = $obj->fk_typepayment;
    +                $this->num_payment = $obj->num_payment;
    +                $this->note_private = $obj->note_private;
    +                $this->note_public = $obj->note_public;
    +                $this->fk_bank = $obj->fk_bank;
    +                $this->fk_user_creat = $obj->fk_user_creat;
    +                $this->fk_user_modif = $obj->fk_user_modif;
     
    -			$this->type_code = $obj->type_code;
    -			$this->type_libelle = $obj->type_libelle;
    +                $this->type_code = $obj->type_code;
    +                $this->type_libelle = $obj->type_libelle;
     
    -			$this->bank_account   = $obj->fk_account;
    -			$this->bank_line      = $obj->fk_bank;
    -		}
    -		$this->db->free($resql);
    +                $this->bank_account = $obj->fk_account;
    +                $this->bank_line = $obj->fk_bank;
    +            }
    +            $this->db->free($resql);
     
     			return 1;
     		}
    @@ -232,7 +270,7 @@ class LoanSchedule extends CommonObject
     	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
     	 *  @return int         			<0 if KO, >0 if OK
     	 */
    -	function update($user=0, $notrigger=0)
    +	public function update($user=0, $notrigger=0)
     	{
     		global $conf, $langs;
     		$error=0;
    @@ -316,7 +354,7 @@ class LoanSchedule extends CommonObject
     	 *  @param  int		$notrigger		0=launch triggers after, 1=disable triggers
     	 *  @return int						<0 if KO, >0 if OK
     	 */
    -	function delete($user, $notrigger=0)
    +	public function delete($user, $notrigger=0)
     	{
     		global $conf, $langs;
     		$error=0;
    @@ -367,13 +405,20 @@ class LoanSchedule extends CommonObject
     		}
     	}
     
    -	function calc_mens($capital,$rate,$nbterm)
    +	/**
    +	 * Calculate Monthly Payments
    +	 *
    +	 * @param   double  $capital        Capital
    +	 * @param   double  $rate           rate
    +	 * @param   int     $nbterm         nb term
    +	 * @return  double                  mensuality
    +	 */
    +	public function calcMonthlyPayments($capital, $rate, $nbterm)
     	{
     		$result='';
     
    -		if (!empty($capital)&&!empty($rate)&&!empty($nbterm))
    -		{
    -			$result=($capital*($rate/12))/(1-pow((1+($rate/12)),($nbterm*-1)));
    +		if (!empty($capital) && !empty($rate) && !empty($nbterm)) {
    +			$result = ($capital*($rate/12))/(1-pow((1+($rate/12)),($nbterm*-1)));
     		}
     
     		return $result;
    @@ -386,7 +431,7 @@ class LoanSchedule extends CommonObject
     	 *  @param	int		$loanid     Id object
     	 *  @return int         		<0 if KO, >0 if OK
     	 */
    -	function fetchAll($loanid)
    +	public function fetchAll($loanid)
     	{
     		global $langs;
     
    @@ -416,7 +461,7 @@ class LoanSchedule extends CommonObject
     		{
     			while($obj = $this->db->fetch_object($resql))
     			{
    -				$line = New LoanSchedule($this->db);
    +				$line = new LoanSchedule($this->db);
     				$line->id = $obj->rowid;
     				$line->ref = $obj->rowid;
     
    @@ -448,11 +493,11 @@ class LoanSchedule extends CommonObject
     	}
     
     	/**
    -	 *  trans_paiment
    +	 *  transPayment
     	 *
     	 *  @return void
     	 */
    -	function trans_paiment()
    +	private function transPayment()
     	{
     		require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
    @@ -467,7 +512,7 @@ class LoanSchedule extends CommonObject
     
     		if($resql){
     			while($obj = $this->db->fetch_object($resql)){
    -				$lastrecorded = $this->lastpaiment($obj->rowid);
    +				$lastrecorded = $this->lastPayment($obj->rowid);
     				$toinsert = $this->paimenttorecord($obj->rowid, $lastrecorded);
     				if(count($toinsert)>0){
     					foreach ($toinsert as $echid){
    @@ -489,12 +534,12 @@ class LoanSchedule extends CommonObject
     
     
     	/**
    -	 *  trans_paiment
    +	 *  lastpayment
     	 *
     	 *  @param  int    $loanid     Loan id
     	 *  @return int                < 0 if KO, Date > 0 if OK
     	 */
    -	function lastpaiment($loanid)
    +	private function lastPayment($loanid)
     	{
     		$sql = "SELECT p.datep";
     		$sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p ";
    @@ -519,7 +564,7 @@ class LoanSchedule extends CommonObject
     	 *  @param  int        $datemax    Date max
     	 *  @return array                  Array of id
     	 */
    -	function paimenttorecord($loanid, $datemax)
    +	public function paimenttorecord($loanid, $datemax)
     	{
     		$sql = "SELECT p.rowid";
     		$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p ";
    @@ -534,10 +579,8 @@ class LoanSchedule extends CommonObject
     			{
     				$result[] = $obj->rowid;
     			}
    -
     		}
     
     		return $result;
     	}
     }
    -
    diff --git a/htdocs/loan/class/paymentloan.class.php b/htdocs/loan/class/paymentloan.class.php
    index 595aead109e..cb1ec021dda 100644
    --- a/htdocs/loan/class/paymentloan.class.php
    +++ b/htdocs/loan/class/paymentloan.class.php
    @@ -1,6 +1,6 @@
     <?php
     /* Copyright (C) 2014-2018  Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2015       Frederic France      <frederic.france@free.fr>
    + * Copyright (C) 2015-2018  Frederic France      <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,35 +30,78 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class PaymentLoan extends CommonObject
     {
    -	public $element='payment_loan';			//!< Id that identify managed objects
    -	public $table_element='payment_loan';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='payment_loan';
     
    -	var $fk_loan;
    -	var $datec='';
    -	var $tms='';
    -	var $datep='';
    -	var $amounts=array();   // Array of amounts
    -	var $amount_capital;    // Total amount of payment
    -	var $amount_insurance;
    -	var $amount_interest;
    -	var $fk_typepayment;
    -	var $num_payment;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='payment_loan';
    +
    +    /**
    +     * @var int Loan ID
    +     */
    +    public $fk_loan;
    +
    +    /**
    +     * @var string Create date
    +     */
    +    public $datec='';
    +
    +    public $tms='';
    +
    +    /**
    +     * @var string Payment date
    +     */
    +    public $datep='';
    +
    +    public $amounts=array();   // Array of amounts
    +
    +    public $amount_capital;    // Total amount of payment
    +
    +    public $amount_insurance;
    +
    +    public $amount_interest;
    +
    +    /**
    +     * @var int Payment type ID
    +     */
    +    public $fk_typepayment;
    +
    +    /**
    +     * @var int Payment ID
    +     */
    +    public $num_payment;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_bank;
    +
    +    /**
    +     * @var int User ID
    +     */
    +    public $fk_user_creat;
    +
    +    /**
    +     * @var int user ID
    +     */
    +    public $fk_user_modif;
     
     	/**
     	 * @deprecated
     	 * @see amount, amounts
     	 */
    -	var $total;
    +    public $total;
     
     	/**
     	 *	Constructor
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		$this->db = $db;
     	}
    @@ -79,24 +122,24 @@ class PaymentLoan extends CommonObject
     		$now=dol_now();
     
     		// Validate parameters
    -		if (! $this->datepaid)
    +		if (! $this->datep)
     		{
     			$this->error='ErrorBadValueForParameter';
     			return -1;
     		}
     
     		// Clean parameters
    -		if (isset($this->fk_loan)) 			$this->fk_loan = trim($this->fk_loan);
    +		if (isset($this->fk_loan)) $this->fk_loan = (int) $this->fk_loan;
     		if (isset($this->amount_capital))	$this->amount_capital = price2num($this->amount_capital?$this->amount_capital:0);
    -		if (isset($this->amount_insurance))	$this->amount_insurance = price2num($this->amount_insurance?$this->amount_insurance:0);
    +		if (isset($this->amount_insurance)) $this->amount_insurance = price2num($this->amount_insurance?$this->amount_insurance:0);
     		if (isset($this->amount_interest))	$this->amount_interest = price2num($this->amount_interest?$this->amount_interest:0);
    -		if (isset($this->fk_typepayment))	$this->fk_typepayment = trim($this->fk_typepayment);
    -		if (isset($this->num_payment))		$this->num_payment = trim($this->num_payment);
    +		if (isset($this->fk_typepayment)) $this->fk_typepayment = (int) $this->fk_typepayment;
    +		if (isset($this->num_payment)) $this->num_payment = (int) $this->num_payment;
     		if (isset($this->note_private))     $this->note_private = trim($this->note_private);
     		if (isset($this->note_public))      $this->note_public = trim($this->note_public);
    -		if (isset($this->fk_bank))			$this->fk_bank = trim($this->fk_bank);
    -		if (isset($this->fk_user_creat))	$this->fk_user_creat = trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif))	$this->fk_user_modif = trim($this->fk_user_modif);
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
     
     		$totalamount = $this->amount_capital + $this->amount_insurance + $this->amount_interest;
     		$totalamount = price2num($totalamount);
    @@ -112,7 +155,7 @@ class PaymentLoan extends CommonObject
     			$sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_loan (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,";
     			$sql.= " fk_typepayment, num_payment, note_private, note_public, fk_user_creat, fk_bank)";
     			$sql.= " VALUES (".$this->chid.", '".$this->db->idate($now)."',";
    -			$sql.= " '".$this->db->idate($this->datepaid)."',";
    +			$sql.= " '".$this->db->idate($this->datep)."',";
     			$sql.= " ".$this->amount_capital.",";
     			$sql.= " ".$this->amount_insurance.",";
     			$sql.= " ".$this->amount_interest.",";
    @@ -130,7 +173,6 @@ class PaymentLoan extends CommonObject
     				$this->error=$this->db->lasterror();
     				$error++;
     			}
    -
     		}
     
     		if ($totalamount != 0 && ! $error)
    @@ -209,8 +251,8 @@ class PaymentLoan extends CommonObject
     				$this->type_code = $obj->type_code;
     				$this->type_libelle = $obj->type_libelle;
     
    -				$this->bank_account   = $obj->fk_account;
    -				$this->bank_line      = $obj->fk_bank;
    +				$this->bank_account = $obj->fk_account;
    +				$this->bank_line = $obj->fk_bank;
     			}
     			$this->db->free($resql);
     
    @@ -237,20 +279,19 @@ class PaymentLoan extends CommonObject
     		$error=0;
     
     		// Clean parameters
    -		if (isset($this->fk_loan)) $this->fk_loan=trim($this->fk_loan);
    +		if (isset($this->fk_loan)) $this->fk_loan = (int) $this->fk_loan;
     		if (isset($this->amount_capital)) $this->amount_capital=trim($this->amount_capital);
     		if (isset($this->amount_insurance)) $this->amount_insurance=trim($this->amount_insurance);
     		if (isset($this->amount_interest)) $this->amount_interest=trim($this->amount_interest);
    -		if (isset($this->fk_typepayment)) $this->fk_typepayment=trim($this->fk_typepayment);
    -		if (isset($this->num_payment)) $this->num_payment=trim($this->num_payment);
    +		if (isset($this->fk_typepayment)) $this->fk_typepayment = (int) $this->fk_typepayment;
    +		if (isset($this->num_payment)) $this->num_payment = (int) $this->num_payment;
     		if (isset($this->note_private)) $this->note=trim($this->note_private);
     		if (isset($this->note_public)) $this->note=trim($this->note_public);
    -		if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank);
    -		if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif);
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
    -		// Put here code to add control on parameters values
     
     		// Update request
     		$sql = "UPDATE ".MAIN_DB_PREFIX."payment_loan SET";
    @@ -412,7 +453,7 @@ class PaymentLoan extends CommonObject
     
     			// Insert payment into llx_bank
     			$bank_line_id = $acc->addline(
    -				$this->datepaid,
    +				$this->datep,
     				$this->paymenttype,  // Payment mode id or code ("CHQ or VIR for example")
     				$label,
     				$total,
    @@ -472,6 +513,7 @@ class PaymentLoan extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update link between loan's payment and the line generate in llx_bank
     	 *
    @@ -480,6 +522,7 @@ class PaymentLoan extends CommonObject
     	 */
     	function update_fk_bank($id_bank)
     	{
    +        // phpcs:enable
     		$sql = "UPDATE ".MAIN_DB_PREFIX."payment_loan SET fk_bank = ".$id_bank." WHERE rowid = ".$this->id;
     
     		dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG);
    diff --git a/htdocs/loan/createschedule.php b/htdocs/loan/createschedule.php
    index e895edeec62..7cfd54ab998 100644
    --- a/htdocs/loan/createschedule.php
    +++ b/htdocs/loan/createschedule.php
    @@ -51,7 +51,7 @@ if ($action == 'createecheancier') {
     		$echeance->fk_loan = $object->id;
     		$echeance->datec = dol_now();
     		$echeance->tms = dol_now();
    -		$echeance->datepaid = $date;
    +		$echeance->datep = $date;
     		$echeance->amount_capital = $mens-$int;
     		$echeance->amount_insurance = 0;
     		$echeance->amount_interest = $int;
    @@ -61,7 +61,7 @@ if ($action == 'createecheancier') {
     		$echeance->fk_user_modif = $user->id;
     		$result=$echeance->create($user);
     		if ($result<0) {
    -			setEventMessages(null, $echeance->errors,'errors');
    +			setEventMessages($echeance->error, $echeance->errors,'errors');
     		}
     		$i++;
     	}
    @@ -165,7 +165,7 @@ if ($object->nbterm > 0 && count($echeance->lines)==0)
     	$capital = $object->capital;
     	while($i <$object->nbterm+1)
     	{
    -		$mens = price2num($echeance->calc_mens($capital, $object->rate/100, $object->nbterm-$i+1), 'MT');
    +		$mens = price2num($echeance->calcMonthlyPayments($capital, $object->rate/100, $object->nbterm-$i+1), 'MT');
     		$int = ($capital*($object->rate/12))/100;
     		$int = price2num($int, 'MT');
     		$cap_rest = price2num($capital - ($mens-$int), 'MT');
    @@ -210,8 +210,6 @@ print '</br>';
     print '<div align="center"><input class="button" type="submit" value="'.$langs->trans("Save").'"></div>';
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    -
    -
    -
    diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php
    index f9d17c563fa..2c762b624d2 100644
    --- a/htdocs/loan/document.php
    +++ b/htdocs/loan/document.php
    @@ -134,7 +134,7 @@ if ($object->id)
     	print '<div class="underbanner clearboth"></div>';
     
     
    -    // Construit liste des fichiers
    +    // Build file list
         $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
         $totalsize=0;
         foreach($filearray as $key => $file)
    @@ -163,7 +163,6 @@ else
         print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/loan/index.php b/htdocs/loan/index.php
    index a032139c8fa..5b81ebbb023 100644
    --- a/htdocs/loan/index.php
    +++ b/htdocs/loan/index.php
    @@ -104,7 +104,6 @@ if ($resql)
     {
     	$num = $db->num_rows($resql);
     	$i = 0;
    -	$var=true;
     
     	$param='';
     	if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
    @@ -167,7 +166,6 @@ if ($resql)
     		$loan_static->ref = $obj->rowid;
     		$loan_static->label = $obj->label;
     
    -		$var = !$var;
     		print '<tr class="oddeven">';
     
     		// Ref
    @@ -204,6 +202,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php
    index d5b6e673f7c..3a092e4cb84 100644
    --- a/htdocs/loan/info.php
    +++ b/htdocs/loan/info.php
    @@ -113,5 +113,6 @@ print '</td></tr></table>';
     
     print '</div>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php
    index f38ed50e431..2ed8e82f20b 100644
    --- a/htdocs/loan/note.php
    +++ b/htdocs/loan/note.php
    @@ -129,6 +129,7 @@ if ($id > 0)
         dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php
    index e19e33bc31e..919139bd6e3 100644
    --- a/htdocs/loan/payment/card.php
    +++ b/htdocs/loan/payment/card.php
    @@ -292,8 +292,6 @@ if (empty($action) && ! empty($user->rights->loan->delete))
     
     print '</div>';
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php
    index ee83bf17f00..08937c1f389 100644
    --- a/htdocs/loan/payment/payment.php
    +++ b/htdocs/loan/payment/payment.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2014-2018  Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2015       Frederic France      <frederic.france@free.fr>
    +/* Copyright (C) 2014-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2015-2018  Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -93,12 +93,12 @@ if ($action == 'add_payment')
         		// Create a line of payments
         		$payment = new PaymentLoan($db);
         		$payment->chid				= $chid;
    -    		$payment->datepaid			= $datepaid;
    +    		$payment->datep = $datepaid;
                 $payment->label             = $loan->label;
     			$payment->amount_capital	= GETPOST('amount_capital');
     			$payment->amount_insurance	= GETPOST('amount_insurance');
     			$payment->amount_interest	= GETPOST('amount_interest');
    -			$payment->paymenttype		= GETPOST('paymenttype');
    +			$payment->paymenttype = GETPOST('paymenttype', 'int');
         		$payment->num_payment		= GETPOST('num_payment');
         		$payment->note_private      = GETPOST('note_private','none');
         		$payment->note_public       = GETPOST('note_public','none');
    @@ -200,7 +200,7 @@ if ($action == 'create')
     	print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Date").'</td><td colspan="2">';
     	$datepaid = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
     	$datepayment = empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaye):0;
    -	$form->select_date($datepayment, '', '', '', '', "add_payment", 1, 1);
    +	print $form->selectDate($datepayment, '', '', '', '', "add_payment", 1, 1);
     	print "</td>";
     	print '</tr>';
     
    diff --git a/htdocs/mailmanspip/class/mailmanspip.class.php b/htdocs/mailmanspip/class/mailmanspip.class.php
    index f7ae2608da5..2e6cae459c1 100644
    --- a/htdocs/mailmanspip/class/mailmanspip.class.php
    +++ b/htdocs/mailmanspip/class/mailmanspip.class.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
    - * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
    - * Copyright (C) 2004      Benoit Mortier       <benoit.mortier@opensides.be>
    - * Copyright (C) 2009      Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2012      Marcos García        <marcosgdf@gmail.com>
    +/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
    + * Copyright (C) 2004-2013  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2004       Sebastien Di Cintio     <sdicintio@ressource-toi.org>
    + * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
    + * Copyright (C) 2009       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -38,13 +39,25 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
      */
     class MailmanSpip
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    var $mladded_ok;
    -    var $mladded_ko;
    -    var $mlremoved_ok;
    -    var $mlremoved_ko;
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    /**
    +     * @var string[]	Array of error strings
    +     */
    +    public $errors = array();
    +
    +    public $mladded_ok;
    +    public $mladded_ko;
    +    public $mlremoved_ok;
    +    public $mlremoved_ko;
     
     
         /**
    @@ -163,6 +176,7 @@ class MailmanSpip
             return $result;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Fonction qui donne les droits redacteurs dans spip
          *
    @@ -171,6 +185,7 @@ class MailmanSpip
          */
         function add_to_spip($object)
         {
    +        // phpcs:enable
             dol_syslog(get_class($this)."::add_to_spip");
     
             if ($this->isSpipEnabled())
    @@ -205,6 +220,7 @@ class MailmanSpip
             return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Fonction qui enleve les droits redacteurs dans spip
          *
    @@ -213,6 +229,7 @@ class MailmanSpip
          */
         function del_to_spip($object)
         {
    +        // phpcs:enable
             dol_syslog(get_class($this)."::del_to_spip");
     
             if ($this->isSpipEnabled())
    @@ -244,6 +261,7 @@ class MailmanSpip
             return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Fonction qui dit si cet utilisateur est un redacteur existant dans spip
          *
    @@ -252,6 +270,7 @@ class MailmanSpip
          */
         function is_in_spip($object)
         {
    +        // phpcs:enable
             if ($this->isSpipEnabled())
             {
                 if ($this->checkSpipConfig())
    @@ -294,6 +313,7 @@ class MailmanSpip
             return -1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Subscribe an email to all mailing-lists
          *
    @@ -303,6 +323,7 @@ class MailmanSpip
          */
         function add_to_mailman($object,$listes='')
         {
    +        // phpcs:enable
             global $conf,$langs,$user;
     
             dol_syslog(get_class($this)."::add_to_mailman");
    @@ -365,6 +386,7 @@ class MailmanSpip
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Unsubscribe an email from all mailing-lists
          *  Used when a user is resiliated
    @@ -375,6 +397,7 @@ class MailmanSpip
          */
         function del_to_mailman($object,$listes='')
         {
    +        // phpcs:enable
             global $conf,$langs,$user;
     
             dol_syslog(get_class($this)."::del_to_mailman");
    @@ -436,5 +459,4 @@ class MailmanSpip
     	        }
             }
         }
    -
     }
    diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
    index 826f83356c4..7fbb0cbb07b 100644
    --- a/htdocs/main.inc.php
    +++ b/htdocs/main.inc.php
    @@ -68,6 +68,22 @@ if (function_exists('get_magic_quotes_gpc'))	// magic_quotes_* deprecated in PHP
     	}
     }
     
    +// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +/**
    + * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
    + *
    + * @param       string      $val        Value
    + * @param       string      $type       1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test)
    + * @return      int                     >0 if there is an injection, 0 if none
    + * @deprecated                          use testSqlAndScriptInject
    + * @see testSqlAndScriptInject($val, $type)
    + */
    +function test_sql_and_script_inject($val, $type)
    +{
    +    // phpcs:enable
    +    return testSqlAndScriptInject($val, $type);
    +}
    +
     /**
      * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
      *
    @@ -75,7 +91,7 @@ if (function_exists('get_magic_quotes_gpc'))	// magic_quotes_* deprecated in PHP
      * @param		string		$type		1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test)
      * @return		int						>0 if there is an injection, 0 if none
      */
    -function test_sql_and_script_inject($val, $type)
    +function testSqlAndScriptInject($val, $type)
     {
     	$inj = 0;
     	// For SQL Injection (only GET are used to be included into bad escaped SQL requests)
    @@ -158,7 +174,7 @@ function analyseVarsForSqlAndScriptsInjection(&$var, $type)
     	}
     	else
     	{
    -		return (test_sql_and_script_inject($var, $type) <= 0);
    +		return (testSqlAndScriptInject($var, $type) <= 0);
     	}
     }
     
    @@ -256,8 +272,6 @@ if (isset($_SERVER["HTTP_USER_AGENT"]))
     	$conf->browser->os=$tmp['browseros'];
     	$conf->browser->version=$tmp['browserversion'];
     	$conf->browser->layout=$tmp['layout'];     // 'classic', 'phone', 'tablet'
    -	$conf->browser->phone=$tmp['phone'];	   // TODO deprecated, use ->layout
    -	$conf->browser->tablet=$tmp['tablet'];	   // TODO deprecated, use ->layout
     	//var_dump($conf->browser);
     
     	if ($conf->browser->layout == 'phone') $conf->dol_no_mouse_hover=1;
    @@ -486,17 +500,6 @@ if (! defined('NOLOGIN'))
     				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadValueForCode");
     				$test=false;
     
    -				// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -				$user->trigger_mesg='ErrorBadValueForCode - login='.GETPOST("username","alpha",2);
    -				// Call of triggers
    -				include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -				$interface=new Interfaces($db);
    -				$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
    -				if ($result < 0) {
    -					$error++;
    -				}
    -				// End Call of triggers
    -
     				// Hooks on failed login
     				$action='';
     				$hookmanager->initHooks(array('login'));
    @@ -565,17 +568,6 @@ if (! defined('NOLOGIN'))
     				// We set a generic message if not defined inside function checkLoginPassEntity or subfunctions
     				if (empty($_SESSION["dol_loginmesg"])) $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
     
    -				// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -				$user->trigger_mesg=$langs->trans("ErrorBadLoginPassword").' - login='.GETPOST("username","alpha",2);
    -				// Call of triggers
    -				include_once DOL_DOCUMENT_ROOT.'/core/class/interfaces.class.php';
    -				$interface=new Interfaces($db);
    -				$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf,GETPOST("username","alpha",2));
    -				if ($result < 0) {
    -					$error++;
    -				}
    -				// End Call of triggers
    -
     				// Hooks on failed login
     				$action='';
     				$hookmanager->initHooks(array('login'));
    @@ -612,27 +604,12 @@ if (! defined('NOLOGIN'))
     				$langs->loadLangs(array('main', 'errors'));
     
     				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
    -
    -				// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -				$user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login;
     			}
     			if ($resultFetchUser < 0)
     			{
     				$_SESSION["dol_loginmesg"]=$user->error;
    -
    -				// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -				$user->trigger_mesg=$user->error;
     			}
     
    -			// Call triggers
    -			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -			$interface=new Interfaces($db);
    -			$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
    -			if ($result < 0) {
    -				$error++;
    -			}
    -			// End call triggers
    -
     			// Hooks on failed login
     			$action='';
     			$hookmanager->initHooks(array('login'));
    @@ -671,28 +648,12 @@ if (! defined('NOLOGIN'))
     				$langs->loadLangs(array('main', 'errors'));
     
     				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
    -
    -				// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -				$user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login;
     			}
     			if ($resultFetchUser < 0)
     			{
     				$_SESSION["dol_loginmesg"]=$user->error;
    -
    -				// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -				$user->trigger_mesg=$user->error;
     			}
     
    -			// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -			// Call triggers
    -			include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -			$interface=new Interfaces($db);
    -			$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
    -			if ($result < 0) {
    -				$error++;
    -			}
    -			// End call triggers
    -
     			// Hooks on failed login
     			$action='';
     			$hookmanager->initHooks(array('login'));
    @@ -780,17 +741,6 @@ if (! defined('NOLOGIN'))
     
     		$loginfo = 'TZ='.$_SESSION["dol_tz"].';TZString='.$_SESSION["dol_tz_string"].';Screen='.$_SESSION["dol_screenwidth"].'x'.$_SESSION["dol_screenheight"];
     
    -		// TODO @deprecated Remove this. Hook must be used, not this trigger.
    -		$user->trigger_mesg = $loginfo;
    -		// Call triggers
    -		include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -		$interface=new Interfaces($db);
    -		$result=$interface->run_triggers('USER_LOGIN',$user,$user,$langs,$conf);
    -		if ($result < 0) {
    -			$error++;
    -		}
    -		// End call triggers
    -
     		// Hooks on successfull login
     		$action='';
     		$hookmanager->initHooks(array('login'));
    @@ -802,7 +752,7 @@ if (! defined('NOLOGIN'))
     		{
     			$db->rollback();
     			session_destroy();
    -			dol_print_error($db,'Error in some hooks afterLogin (or old trigger USER_LOGIN)');
    +			dol_print_error($db,'Error in some hooks afterLogin');
     			exit;
     		}
     		else
    @@ -900,7 +850,6 @@ if (! empty($conf->dol_use_jmobile) && in_array($conf->theme,array('bureau2crea'
     	$conf->theme='eldy';
     	$conf->css  =  "/theme/".$conf->theme."/style.css.php";
     }
    -//var_dump($conf->browser->phone);
     
     if (! defined('NOREQUIRETRAN'))
     {
    @@ -988,7 +937,7 @@ else
     	define('ROWS_9',8);
     }
     
    -$heightforframes=48;
    +$heightforframes=50;
     
     // Init menu manager
     if (! defined('NOREQUIREMENU'))
    @@ -1170,12 +1119,15 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
     		$ext='layout='.$conf->browser->layout.'&version='.urlencode(DOL_VERSION);
     
     		print "<head>\n";
    +
     		if (GETPOST('dol_basehref','alpha')) print '<base href="'.dol_escape_htmltag(GETPOST('dol_basehref','alpha')).'">'."\n";
    +
     		// Displays meta
     		print '<meta charset="UTF-8">'."\n";
     		print '<meta name="robots" content="noindex'.($disablenofollow?'':',nofollow').'">'."\n";	// Do not index
     		print '<meta name="viewport" content="width=device-width, initial-scale=1.0">'."\n";		// Scale for mobile device
     		print '<meta name="author" content="Dolibarr Development Team">'."\n";
    +
     		// Favicon
     		$favicon=dol_buildpath('/theme/'.$conf->theme.'/img/favicon.ico',1);
     		if (! empty($conf->global->MAIN_FAVICON_URL)) $favicon=$conf->global->MAIN_FAVICON_URL;
    @@ -1184,6 +1136,9 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
     		//if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="copyright" title="GNU General Public License" href="http://www.gnu.org/copyleft/gpl.html#SEC1">'."\n";
     		//if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) print '<link rel="author" title="Dolibarr Development Team" href="https://www.dolibarr.org">'."\n";
     
    +		// Auto refresh page
    +		if (GETPOST('autorefresh','int') > 0) print '<meta http-equiv="refresh" content="'.GETPOST('autorefresh','int').'">';
    +
     		// Displays title
     		$appli=constant('DOL_APPLICATION_TITLE');
     		if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
    @@ -1357,7 +1312,11 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
                 	$tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?constant('REQUIRE_JQUERY_MULTISELECT'):$conf->global->MAIN_USE_JQUERY_MULTISELECT;
                 	print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/'.$tmpplugin.'/dist/js/'.$tmpplugin.'.full.min.js'.($ext?'?'.$ext:'').'"></script>'."\n";	// We include full because we need the support of containerCssClass
                 }
    -        }
    +            if (! defined('DISABLE_MULTISELECT'))     // jQuery plugin "mutiselect" to select with checkboxes
    +            {
    +            	print '<script type="text/javascript" src="'.DOL_URL_ROOT.'/includes/jquery/plugins/multiselect/jquery.multi-select.js'.($ext?'?'.$ext:'').'"></script>'."\n";
    +            }
    +		}
     
             if (! $disablejs && ! empty($conf->use_javascript_ajax))
             {
    @@ -1453,7 +1412,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
      *  @param		string	$morequerystring	Query string to add to the link "print" to get same parameters (use only if autodetect fails)
      *  @param      string	$helppagename    	Name of wiki page for help ('' by default).
      * 				     		                Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage
    - * 									                   For other external page: http://server/url
    + * 						                    For other external page: http://server/url
      *  @return		void
      */
     function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $helppagename='')
    @@ -1568,7 +1527,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
     		}
     
     		// Link to print main content area
    -		if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && empty($conf->browser->phone))
    +		if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $conf->browser->layout != 'phone')
     		{
     			$qs=dol_escape_htmltag($_SERVER["QUERY_STRING"]);
     
    @@ -1653,7 +1612,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a
      *  @param  array	$menu_array_before 	       	Table of menu entries to show before entries of menu handler. This param is deprectaed and must be provided to ''.
      *  @param  string	$helppagename    	       	Name of wiki page for help ('' by default).
      * 				     		                   	Syntax is: For a wiki page: EN:EnglishPage|FR:FrenchPage|ES:SpanishPage
    - * 									         		       For other external page: http://server/url
    + * 									         	For other external page: http://server/url
      *  @param  string	$notused             		Deprecated. Used in past to add content into left menu. Hooks can be used now.
      *  @param  array	$menu_array_after           Table of menu entries to show after entries of menu handler
      *  @param  int		$leftmenuwithoutmainarea    Must be set to 1. 0 by default for backward compatibility with old modules.
    @@ -1732,7 +1691,7 @@ function left_menu($menu_array_before, $helppagename='', $notused='', $menu_arra
     		// Define $bookmarks
     		if (! empty($conf->bookmark->enabled) && $user->rights->bookmark->lire)
     		{
    -			include_once (DOL_DOCUMENT_ROOT.'/bookmarks/bookmarks.lib.php');
    +			include_once DOL_DOCUMENT_ROOT.'/bookmarks/bookmarks.lib.php';
     			$langs->load("bookmarks");
     
     			$bookmarks=printBookmarksList($db, $langs);
    @@ -1793,9 +1752,8 @@ function left_menu($menu_array_before, $helppagename='', $notused='', $menu_arra
     			$bugbaseurl.= '?title=';
     			$bugbaseurl.= urlencode("Bug: ");
     			$bugbaseurl.= '&body=';
    -			// TODO use .github/ISSUE_TEMPLATE.md to generate?
    -			$bugbaseurl .= urlencode("# Bug\n");
    -			$bugbaseurl .= urlencode("\n");
    +			$bugbaseurl.= urlencode("# Bug\n");
    +			$bugbaseurl.= urlencode("\n");
     			$bugbaseurl.= urlencode("## Environment\n");
     			$bugbaseurl.= urlencode("- **Version**: " . DOL_VERSION . "\n");
     			$bugbaseurl.= urlencode("- **OS**: " . php_uname('s') . "\n");
    @@ -2071,4 +2029,3 @@ if (! function_exists("llxFooter"))
     		print "</html>\n";
     	}
     }
    -
    diff --git a/htdocs/margin/admin/margin.php b/htdocs/margin/admin/margin.php
    index d37dfe0c83b..b2c74506990 100644
    --- a/htdocs/margin/admin/margin.php
    +++ b/htdocs/margin/admin/margin.php
    @@ -26,13 +26,10 @@ include '../../main.inc.php';
     
     require_once DOL_DOCUMENT_ROOT.'/margin/lib/margins.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
    -require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
    +require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
     
    -$langs->load("admin");
    -$langs->load("bills");
    -$langs->load("margins");
    -$langs->load("stocks");
    +$langs->loadLangs(array("admin", "bills", "margins", "stocks"));
     
     if (! $user->admin) accessforbidden();
     
    @@ -129,11 +126,9 @@ print '<td colspan="2" align="center">'.$langs->trans("Value").'</td>'."\n";
     print '<td align="left">'.$langs->trans("Description").'</td>'."\n";
     print '</tr>';
     
    -$var=true;
     $form = new Form($db);
     
     // GLOBAL DISCOUNT MANAGEMENT
    -
     print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     print "<input type=\"hidden\" name=\"action\" value=\"typemarges\">";
    @@ -165,7 +160,6 @@ print '</tr>';
     print '</form>';
     
     // DISPLAY MARGIN RATES
    -
     print '<tr class="oddeven">';
     print '<td>'.$langs->trans("DisplayMarginRates").'</td>';
     print '<td colspan="2" align="center">';
    @@ -189,7 +183,6 @@ print '<td>'.$langs->trans('MarginRate').' = '.$langs->trans('Margin').' / '.$la
     print '</tr>';
     
     // DISPLAY MARK RATES
    -
     print '<tr class="oddeven">';
     print '<td>'.$langs->trans("DisplayMarkRates").'</td>';
     print '<td colspan="2" align="center">';
    @@ -259,7 +252,6 @@ print '</tr>';
     print '</form>';
     
     // INTERNAL CONTACT TYPE USED AS COMMERCIAL AGENT
    -
     print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     print "<input type=\"hidden\" name=\"action\" value=\"contact\">";
    @@ -283,5 +275,6 @@ dol_fiche_end();
     
     print '<br>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/margin/agentMargins.php b/htdocs/margin/agentMargins.php
    index 2e80fe5ced2..5c808051a06 100644
    --- a/htdocs/margin/agentMargins.php
    +++ b/htdocs/margin/agentMargins.php
    @@ -110,11 +110,11 @@ print '</td></tr>';
     // Start date
     print '<td>'.$langs->trans('DateStart').' ('.$langs->trans("DateValidation").')</td>';
     print '<td>';
    -$form->select_date($startdate,'startdate','','',1,"sel",1,1);
    +print $form->selectDate($startdate, 'startdate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td>'.$langs->trans('DateEnd').' ('.$langs->trans("DateValidation").')</td>';
     print '<td>';
    -$form->select_date($enddate,'enddate','','',1,"sel",1,1);
    +print $form->selectDate($enddate, 'enddate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td style="text-align: center;">';
     print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Refresh')).'" />';
    @@ -208,7 +208,6 @@ if ($result)
     
     	if ($num > 0)
     	{
    -		$var=true;
     
     		while ($i < $num /*&& $i < $conf->liste_limit*/)
     		{
    @@ -229,8 +228,6 @@ if ($result)
     				$markRate = ($pv != 0)?(100 * $marge / $pv):'' ;
     			}
     
    -
    -
     			print '<tr class="oddeven">';
     			if ($agentid > 0) {
     				$companystatic->id=$objp->socid;
    @@ -271,6 +268,6 @@ $(document).ready(function() {
     });
     </script>'."\n";
     
    +// End of page
     llxFooter();
     $db->close();
    -
    diff --git a/htdocs/margin/checkMargins.php b/htdocs/margin/checkMargins.php
    index 0612c143497..06527f42b91 100644
    --- a/htdocs/margin/checkMargins.php
    +++ b/htdocs/margin/checkMargins.php
    @@ -165,11 +165,11 @@ print '<table class="border" width="100%">';
     
     print '<tr><td class="titlefield">' . $langs->trans('DateStart') . ' (' . $langs->trans("DateValidation") . ')</td>';
     print '<td>';
    -$form->select_date($startdate, 'startdate', '', '', 1, "sel", 1, 1);
    +print $form->selectDate($startdate, 'startdate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td>' . $langs->trans('DateEnd') . ' (' . $langs->trans("DateValidation") . ')</td>';
     print '<td>';
    -$form->select_date($enddate, 'enddate', '', '', 1, "sel", 1, 1);
    +print $form->selectDate($enddate, 'enddate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td style="text-align: center;">';
     print '<input type="submit" class="button" value="' . dol_escape_htmltag($langs->trans('Refresh')) . '" name="button_search" />';
    @@ -321,5 +321,6 @@ print '</form>';
     
     $db->free($result);
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php
    index 45b604d1919..675fe527a47 100644
    --- a/htdocs/margin/customerMargins.php
    +++ b/htdocs/margin/customerMargins.php
    @@ -159,11 +159,11 @@ print '</tr>';
     // Start date
     print '<td>'.$langs->trans('DateStart').' ('.$langs->trans("DateValidation").')</td>';
     print '<td>';
    -$form->select_date($startdate,'startdate','','',1,"sel",1,1);
    +print $form->selectDate($startdate, 'startdate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td>'.$langs->trans('DateEnd').' ('.$langs->trans("DateValidation").')</td>';
     print '<td>';
    -$form->select_date($enddate,'enddate','','',1,"sel",1,1);
    +print $form->selectDate($enddate, 'enddate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td style="text-align: center;">';
     print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Refresh')).'" />';
    @@ -383,5 +383,6 @@ $(document).ready(function() {
     </script>
     ';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/margin/productMargins.php b/htdocs/margin/productMargins.php
    index d827f5d985e..23c9de6c321 100644
    --- a/htdocs/margin/productMargins.php
    +++ b/htdocs/margin/productMargins.php
    @@ -117,7 +117,6 @@ else {
     	print '<td class="maxwidthonsmartphone" colspan="4">';
     	print $form->select_produits('','id','',20,0,1,2,'',1, array(), 0, 'All');
     	print '</td></tr>';
    -
     }
     
     // Categories
    @@ -134,11 +133,11 @@ print '</tr>';
     print '<tr>';
     print '<td class="titlefield">'.$langs->trans('DateStart').' ('.$langs->trans("DateValidation").')</td>';
     print '<td>';
    -$form->select_date($startdate,'startdate','','',1,"sel",1,1);
    +print $form->selectDate($startdate, 'startdate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td>'.$langs->trans('DateEnd').' ('.$langs->trans("DateValidation").')</td>';
     print '<td>';
    -$form->select_date($enddate,'enddate','','',1,"sel",1,1);
    +print $form->selectDate($enddate, 'enddate', '', '', 1, "sel", 1, 1);
     print '</td>';
     print '<td style="text-align: center;">';
     print '<input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans('Refresh')).'" />';
    @@ -316,7 +315,6 @@ if ($result)
     			$cumul_achat += $objp->buying_price;
     			$cumul_vente += $objp->selling_price;
     		}
    -
     	}
     
     	// affichage totaux marges
    @@ -367,5 +365,6 @@ $(document).ready(function() {
     </script>
     ';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/margin/tabs/productMargins.php b/htdocs/margin/tabs/productMargins.php
    index e6c51e2217d..5659be448de 100644
    --- a/htdocs/margin/tabs/productMargins.php
    +++ b/htdocs/margin/tabs/productMargins.php
    @@ -26,10 +26,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
    -$langs->load("companies");
    -$langs->load("bills");
    -$langs->load("products");
    -$langs->load("margins");
    +$langs->loadLangs(array("companies", "bills", "products", "margins"));
     
     $id = GETPOST('id', 'int');
     $ref = GETPOST('ref', 'alpha');
    @@ -273,5 +270,6 @@ print '
         </script>
     ';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php
    index eb61e4ec41f..8ce4b7a0c0b 100644
    --- a/htdocs/margin/tabs/thirdpartyMargins.php
    +++ b/htdocs/margin/tabs/thirdpartyMargins.php
    @@ -26,10 +26,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     
    -$langs->load("companies");
    -$langs->load("bills");
    -$langs->load("products");
    -$langs->load("margins");
    +$langs->loadLangs(array("companies", "bills", "products", "margins"));
     
     // Security check
     $socid = GETPOST('socid','int');
    @@ -282,5 +279,6 @@ print '
         </script>
     ';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php
    index 52c4c9780c7..56ff709da8a 100644
    --- a/htdocs/master.inc.php
    +++ b/htdocs/master.inc.php
    @@ -80,7 +80,7 @@ if (! empty($dolibarr_main_document_root_alt))
     	{
     		if (preg_match('/^http(s)?:/',$value))
     		{
    -			// TODO: Make this a warning rather than an error since the correct value can be derived in most cases
    +			// Show error message
     			$correct_value = str_replace($dolibarr_main_url_root, '', $value);
     			print '<b>Error:</b><br>'."\n";
     			print 'Wrong <b>$dolibarr_main_url_root_alt</b> value in <b>conf.php</b> file.<br>'."\n";
    diff --git a/htdocs/modulebuilder/admin/setup.php b/htdocs/modulebuilder/admin/setup.php
    new file mode 100644
    index 00000000000..6ca9bfe2a1e
    --- /dev/null
    +++ b/htdocs/modulebuilder/admin/setup.php
    @@ -0,0 +1,165 @@
    +<?php
    +/* Copyright (C) 2018 Nicolas ZABOURI   <info@inovea-conseil.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *  \file       htdocs/modulebuilder/admin/setup.php
    + *  \ingroup    modulebuilder
    + *  \brief      Page setup for modulebuilder module
    + */
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
    +
    +global $conf,$langs,$user, $db;
    +$langs->loadLangs(array("admin", "other", "modulebuilder"));
    +
    +if (!$user->admin || empty($conf->modulebuilder->enabled))
    +    accessforbidden();
    +
    +$action = GETPOST('action', 'alpha');
    +$backtopage = GETPOST('backtopage', 'alpha');
    +
    +/*
    + * Actions
    + */
    +if($action=="update"){
    +   $res1=dolibarr_set_const($db, 'MODULEBUILDER_SPECIFIC_README', GETPOST('MODULEBUILDER_SPECIFIC_README'), 'chaine', 0, '', $conf->entity);
    +   if ($res1 < 0)
    +    {
    +        setEventMessages('ErrorFailedToSaveDate', null, 'errors');
    +        $db->rollback();
    +    }
    +    else
    +    {
    +        setEventMessages('RecordModifiedSuccessfully', null, 'mesgs');
    +        $db->commit();
    +    }
    +}
    +
    +if (preg_match('/set_(.*)/', $action, $reg)) {
    +    $code = $reg[1];
    +    $values = GETPOST($code);
    +    if (is_array($values))
    +        $values = implode(',', $values);
    +
    +    if (dolibarr_set_const($db, $code, $values, 'chaine', 0, '', $conf->entity) > 0) {
    +        header("Location: " . $_SERVER["PHP_SELF"]);
    +        exit;
    +    } else {
    +        dol_print_error($db);
    +    }
    +}
    +
    +if (preg_match('/del_(.*)/', $action, $reg)) {
    +    $code = $reg[1];
    +    if (dolibarr_del_const($db, $code, 0) > 0) {
    +        Header("Location: " . $_SERVER["PHP_SELF"]);
    +        exit;
    +    } else {
    +        dol_print_error($db);
    +    }
    +}
    +
    +
    +/*
    + * 	View
    + */
    +
    +$form = new Form($db);
    +
    +llxHeader('', $langs->trans("ModulebuilderSetup"));
    +
    +$linkback = '';
    +if (GETPOST('withtab', 'alpha')) {
    +    $linkback = '<a href="' . ($backtopage ? $backtopage : DOL_URL_ROOT . '/admin/modules.php') . '">' . $langs->trans("BackToModuleList") . '</a>';
    +}
    +
    +print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    +print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +print '<input type="hidden" name="action" value="update">';
    +
    +print load_fiche_titre($langs->trans("ModuleSetup") . ' ' . $langs->trans('Modulebuilder'), $linkback);
    +
    +if (GETPOST('withtab', 'alpha')) {
    +    dol_fiche_head($head, 'modulebuilder', '', -1);
    +}
    +
    +print '<span class="opacitymedium">' . $langs->trans("ModuleBuilderDesc") . "</span><br>\n";
    +
    +print '<br>';
    +
    +print '<table class="noborder" width="100%">';
    +
    +print '<tr class="liste_titre">';
    +print '<td>' . $langs->trans("Key") . '</td>';
    +print '<td>' . $langs->trans("Value") . '</td>';
    +print "</tr>\n";
    +
    +
    +if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
    +{
    +	// What is use cas of this 2 options ?
    +
    +	print '<tr class="oddeven">';
    +	print '<td>' . $langs->trans("UseAboutPage") . '</td>';
    +	print '<td align="center">';
    +	if ($conf->use_javascript_ajax) {
    +	    print ajax_constantonoff('MODULEBUILDER_USE_ABOUT');
    +	} else {
    +	    if (empty($conf->global->MODULEBUILDER_USE_ABOUT)) {
    +	        print '<a href="' . $_SERVER['PHP_SELF'] . '?action=set_MODULEBUILDER_USE_ABOUT">' . img_picto($langs->trans("Disabled"), 'off') . '</a>';
    +	    } else {
    +	        print '<a href="' . $_SERVER['PHP_SELF'] . '?action=del_MODULEBUILDER_USE_ABOUT">' . img_picto($langs->trans("Enabled"), 'on') . '</a>';
    +	    }
    +	}
    +	print '</td></tr>';
    +
    +	print '<tr class="oddeven">';
    +	print '<td>' . $langs->trans("UseDocFolder") . '</td>';
    +	print '<td align="center">';
    +	if ($conf->use_javascript_ajax) {
    +	    print ajax_constantonoff('MODULEBUILDER_USE_DOCFOLDER');
    +	} else {
    +	    if (empty($conf->global->MODULEBUILDER_USE_DOCFOLDER)) {
    +	        print '<a href="' . $_SERVER['PHP_SELF'] . '?action=set_MODULEBUILDER_USE_DOCFOLDER">' . img_picto($langs->trans("Disabled"), 'off') . '</a>';
    +	    } else {
    +	        print '<a href="' . $_SERVER['PHP_SELF'] . '?action=del_MODULEBUILDER_USE_DOCFOLDER">' . img_picto($langs->trans("Enabled"), 'on') . '</a>';
    +	    }
    +	}
    +	print '</td></tr>';
    +}
    +
    +print '<tr class="oddeven">';
    +print '<td class="tdtop">' . $langs->trans("UseSpecificReadme") . '</td>';
    +print '<td>';
    +print '<textarea class="centpercent" rows="20" name="MODULEBUILDER_SPECIFIC_README">'.$conf->global->MODULEBUILDER_SPECIFIC_README.'</textarea>';
    +print '</td>';
    +print '</tr>';
    +print '</table>';
    +
    +print '<center><input type="submit" class="button" value="'.$langs->trans("Save").'" name="Button"></center>';
    +
    +if (GETPOST('withtab', 'alpha')) {
    +    dol_fiche_end();
    +}
    +
    +print '<br>';
    +
    +print '</form>';
    +
    +// End of page
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
    index f6646813843..b533c369cbd 100644
    --- a/htdocs/modulebuilder/index.php
    +++ b/htdocs/modulebuilder/index.php
    @@ -121,6 +121,15 @@ if ($dirins && $action == 'initmodule' && $modulename)
     			}
     		}
     
    +		if (!empty($conf->global->MODULEBUILDER_USE_ABOUT))
    +		{
    +			dol_delete_file($destdir.'/admin/about.php');
    +		}
    +		if (!empty($conf->global->MODULEBUILDER_USE_DOCFOLDER))
    +		{
    +			dol_delete_dir($destdir.'/doc/');
    +		}
    +
     		// Delete some files related to object (because to previous dolCopyDir has copied everything)
     		dol_delete_file($destdir.'/myobject_card.php');
     		dol_delete_file($destdir.'/myobject_note.php');
    @@ -165,6 +174,12 @@ if ($dirins && $action == 'initmodule' && $modulename)
     				setEventMessages($langs->trans("ErrorFailToMakeReplacementInto", $phpfileval['fullname']), null, 'errors');
     			}
     		}
    +
    +		if (!empty($conf->global->MODULEBUILDER_SPECIFIC_README))
    +		{
    +			dol_delete_file($destdir.'/README.md');
    +			file_put_contents($destdir.'/README.md', $conf->global->MODULEBUILDER_SPECIFIC_README);
    +		}
     	}
     
     	if (! $error)
    @@ -1139,9 +1154,16 @@ elseif (! empty($module))
     		$head2[$h][2] = 'buildpackage';
     		$h++;
     
    +		// Link to enable / disable
     		print $modulestatusinfo;
     		print ' '.$linktoenabledisable;
    -		print '<br><br>';
    +		print '<br>';
    +
    +		if (realpath($dirread.'/'.$modulelowercase) != $dirread.'/'.$modulelowercase)
    +		{
    +			print $langs->trans("RealPathOfModule").' : <strong>'.realpath($dirread.'/'.$modulelowercase).'</strong><br>';
    +		}
    +		print '<br>';
     
     		if ($tab == 'description')
     		{
    @@ -1170,7 +1192,7 @@ elseif (! empty($module))
     				print '<br>';
     				print '<br>';
     
    -				print_fiche_titre($langs->trans("DescriptorFile"));
    +				print load_fiche_titre($langs->trans("DescriptorFile"));
     
     				if (! empty($moduleobj))
     				{
    @@ -1234,7 +1256,7 @@ elseif (! empty($module))
     					print '<br><br>';
     
     					// Readme file
    -					print_fiche_titre($langs->trans("ReadmeFile"));
    +					print load_fiche_titre($langs->trans("ReadmeFile"));
     
     					print '<div class="underbanner clearboth"></div>';
     					print '<div class="fichecenter">';
    @@ -1244,7 +1266,7 @@ elseif (! empty($module))
     					print '<br><br>';
     
     					// ChangeLog
    -					print_fiche_titre($langs->trans("ChangeLog"));
    +					print load_fiche_titre($langs->trans("ChangeLog"));
     
     					print '<div class="underbanner clearboth"></div>';
     					print '<div class="fichecenter">';
    @@ -1629,7 +1651,7 @@ elseif (! empty($module))
     						}
     						else
     						{
    -							$result = @include_once($dirread.'/'.$pathtoclass);
    +							$result = @include_once $dirread.'/'.$pathtoclass;
     						}
     						if (class_exists($tabobj))
     						{
    @@ -1669,24 +1691,24 @@ elseif (! empty($module))
     							print '<div class="div-table-responsive">';
     							print '<table class="noborder">';
     							print '<tr class="liste_titre">';
    -							print '<td>'.$langs->trans("Property");
    -							print ' (<a href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("Example").'</a>)';
    -							print '</td>';
    -							print '<td>';
    +							print '<th class="liste_titre">'.$langs->trans("Property");
    +							print ' (<a class="" href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("SeeExamples").'</a>)';
    +							print '</th>';
    +							print '<th>';
     							print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey"));
    -							print '</td>';
    -							print '<td>'.$langs->trans("Type").'</td>';
    -							print '<td>'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).'</td>';
    -							print '<td class="center">'.$form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")).'</td>';
    -							print '<td class="center">'.$langs->trans("DefaultValue").'</td>';
    -							print '<td class="center">'.$langs->trans("DatabaseIndex").'</td>';
    -							print '<td class="right">'.$langs->trans("Position").'</td>';
    -							print '<td class="center">'.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).'</td>';
    -							print '<td class="center">'.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).'</td>';
    -							print '<td class="center">'.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).'</td>';
    -							print '<td class="center">'.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).'</td>';
    -							print '<td>'.$langs->trans("Comment").'</td>';
    -							print '<td></td>';
    +							print '</th>';
    +							print '<th>'.$langs->trans("Type").'</td>';
    +							print '<th>'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).'</th>';
    +							print '<th class="center">'.$form->textwithpicto($langs->trans("NotNull"), $langs->trans("NotNullDesc")).'</th>';
    +							print '<th class="center">'.$langs->trans("DefaultValue").'</th>';
    +							print '<th class="center">'.$langs->trans("DatabaseIndex").'</th>';
    +							print '<th class="right">'.$langs->trans("Position").'</th>';
    +							print '<th class="center">'.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).'</th>';
    +							print '<th class="center">'.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).'</th>';
    +							print '<th class="center">'.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).'</th>';
    +							print '<th class="center">'.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).'</th>';
    +							print '<th>'.$langs->trans("Comment").'</th>';
    +							print '<th></th>';
     							print '</tr>';
     
     							// We must use $reflectorpropdefault['fields'] to get list of fields because $tmpobjet->fields may have been
    @@ -2476,8 +2498,6 @@ elseif (! empty($module))
     
     dol_fiche_end(); // End modules
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/modulebuilder/template/admin/about.php b/htdocs/modulebuilder/template/admin/about.php
    index b72917daff0..e580c6c7457 100644
    --- a/htdocs/modulebuilder/template/admin/about.php
    +++ b/htdocs/modulebuilder/template/admin/about.php
    @@ -25,15 +25,15 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     // Libraries
    diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php
    index fd2c509233b..6e0be4d0011 100644
    --- a/htdocs/modulebuilder/template/admin/setup.php
    +++ b/htdocs/modulebuilder/template/admin/setup.php
    @@ -25,15 +25,15 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     global $langs, $user;
    @@ -85,7 +85,7 @@ $head = mymoduleAdminPrepareHead();
     dol_fiche_head($head, 'settings', '', -1, "mymodule@mymodule");
     
     // Setup page goes here
    -echo $langs->trans("MyModuleSetupPage");
    +echo $langs->trans("MyModuleSetupPage").'<br><br>';
     
     
     if ($action == 'edit')
    @@ -99,13 +99,10 @@ if ($action == 'edit')
     
     	foreach($arrayofparameters as $key => $val)
     	{
    -		if (isset($val['enabled']) && empty($val['enabled'])) continue;
    -
     		print '<tr class="oddeven"><td>';
     		print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip'));
     		print '</td><td><input name="'.$key.'"  class="flat '.(empty($val['css'])?'minwidth200':$val['css']).'" value="' . $conf->global->$key . '"></td></tr>';
     	}
    -
     	print '</table>';
     
     	print '<br><div class="center">';
    @@ -117,21 +114,28 @@ if ($action == 'edit')
     }
     else
     {
    -	print '<table class="noborder" width="100%">';
    -	print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
    -
    -	foreach($arrayofparameters as $key => $val)
    +	if (! empty($arrayofparameters))
     	{
    -		print '<tr class="oddeven"><td>';
    -		print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip'));
    -		print '</td><td>' . $conf->global->$key . '</td></tr>';
    +		print '<table class="noborder" width="100%">';
    +		print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("Parameter").'</td><td>'.$langs->trans("Value").'</td></tr>';
    +
    +		foreach($arrayofparameters as $key => $val)
    +		{
    +			print '<tr class="oddeven"><td>';
    +			print $form->textwithpicto($langs->trans($key),$langs->trans($key.'Tooltip'));
    +			print '</td><td>' . $conf->global->$key . '</td></tr>';
    +		}
    +
    +		print '</table>';
    +
    +		print '<div class="tabsAction">';
    +		print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
    +		print '</div>';
    +	}
    +	else
    +	{
    +		print '<br>'.$langs->trans("NothingToSetup");
     	}
    -
    -	print '</table>';
    -
    -	print '<div class="tabsAction">';
    -	print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit">'.$langs->trans("Modify").'</a>';
    -	print '</div>';
     }
     
     
    @@ -140,3 +144,4 @@ dol_fiche_end();
     
     llxFooter();
     $db->close();
    +
    diff --git a/htdocs/modulebuilder/template/class/actions_mymodule.class.php b/htdocs/modulebuilder/template/class/actions_mymodule.class.php
    index 789e4e469f9..64076e07359 100644
    --- a/htdocs/modulebuilder/template/class/actions_mymodule.class.php
    +++ b/htdocs/modulebuilder/template/class/actions_mymodule.class.php
    @@ -32,10 +32,12 @@ class ActionsMyModule
          * @var DoliDB Database handler.
          */
         public $db;
    +
         /**
    -     * @var string Error
    +     * @var string Error code (or message)
          */
         public $error = '';
    +
         /**
          * @var array Errors
          */
    @@ -135,7 +137,6 @@ class ActionsMyModule
     	        foreach($parameters['toselect'] as $objectid)
     	        {
     	            // Do action on each object id
    -
     	        }
     	    }
     
    @@ -240,5 +241,4 @@ class ActionsMyModule
     	}
     
     	/* Add here any other hooked methods... */
    -
     }
    diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php
    index 5b77c477429..ab559a26612 100644
    --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php
    +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php
    @@ -41,7 +41,7 @@ class MyModuleApi extends DolibarrApi
          * @var array   $FIELDS     Mandatory fields, checked when create and update object
          */
         static $FIELDS = array(
    -        'name'
    +        'name',
         );
     
     
    @@ -109,7 +109,8 @@ class MyModuleApi extends DolibarrApi
          *
          * @url	GET /myobjects/
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -119,6 +120,7 @@ class MyModuleApi extends DolibarrApi
             $restictonsocid = 0;	// Set to 1 if there is a field socid in table of object
     
             // If the internal user must only see his customers, force searching by him
    +        $search_sale = 0;
             if ($restictonsocid && ! DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id;
     
             $sql = "SELECT t.rowid";
    @@ -128,7 +130,7 @@ class MyModuleApi extends DolibarrApi
             if ($restictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
             $sql.= " WHERE 1 = 1";
     
    -		// Example of use $mode
    +        // Example of use $mode
             //if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
             //if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
     
    @@ -197,8 +199,8 @@ class MyModuleApi extends DolibarrApi
         function post($request_data = null)
         {
             if(! DolibarrApiAccess::$user->rights->myobject->create) {
    -			throw new RestException(401);
    -		}
    +            throw new RestException(401);
    +        }
             // Check mandatory fields
             $result = $this->_validate($request_data);
     
    @@ -223,8 +225,8 @@ class MyModuleApi extends DolibarrApi
         function put($id, $request_data = null)
         {
             if(! DolibarrApiAccess::$user->rights->myobject->create) {
    -			throw new RestException(401);
    -		}
    +            throw new RestException(401);
    +        }
     
             $result = $this->myobject->fetch($id);
             if( ! $result ) {
    @@ -263,9 +265,9 @@ class MyModuleApi extends DolibarrApi
                 throw new RestException(404, 'MyObject not found');
             }
     
    -		if( ! DolibarrApi::_checkAccessToResource('myobject',$this->myobject->id)) {
    -			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    -		}
    +        if( ! DolibarrApi::_checkAccessToResource('myobject',$this->myobject->id)) {
    +            throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +        }
     
     		if( !$this->myobject->delete(DolibarrApiAccess::$user, 0))
             {
    @@ -278,7 +280,6 @@ class MyModuleApi extends DolibarrApi
                     'message' => 'MyObject deleted'
                 )
             );
    -
         }
     
     
    diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
    index 12f31439985..f5f3f582fbc 100644
    --- a/htdocs/modulebuilder/template/class/myobject.class.php
    +++ b/htdocs/modulebuilder/template/class/myobject.class.php
    @@ -36,18 +36,22 @@ class MyObject extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'myobject';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'mymodule_myobject';
    +
     	/**
     	 * @var int  Does myobject support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 0;
    +
     	/**
     	 * @var int  Does myobject support extrafields ? 0=No, 1=Yes
     	 */
     	public $isextrafieldmanaged = 1;
    +
     	/**
     	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
     	 */
    @@ -84,12 +88,12 @@ class MyObject extends CommonObject
     	    'label'         =>array('type'=>'varchar(255)', 'label'=>'Label',            'enabled'=>1, 'visible'=>1,  'position'=>30,  'searchall'=>1, 'css'=>'minwidth200', 'help'=>'Help text', 'showoncombobox'=>1),
     	    'amount'        =>array('type'=>'double(24,8)', 'label'=>'Amount',           'enabled'=>1, 'visible'=>1,  'default'=>'null', 'position'=>40,  'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text'),
     		'fk_soc' 		=>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=>1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty'),
    -		'description'   =>array('type'=>'text',			'label'=>'Descrption',		 'enabled'=>1, 'visible'=>0,  'position'=>60),
    +		'description'   =>array('type'=>'text',			'label'=>'Description',		 'enabled'=>1, 'visible'=>0,  'position'=>60),
     		'note_public'   =>array('type'=>'html',			'label'=>'NotePublic',		 'enabled'=>1, 'visible'=>0,  'position'=>61),
     		'note_private'  =>array('type'=>'html',			'label'=>'NotePrivate',		 'enabled'=>1, 'visible'=>0,  'position'=>62),
     		'date_creation' =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>500),
     	    'tms'           =>array('type'=>'timestamp',    'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>501),
    -		//'date_valid'    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
    +		//'date_validation'    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
     		'fk_user_creat' =>array('type'=>'integer',      'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>510, 'foreignkey'=>'llx_user.rowid'),
     		'fk_user_modif' =>array('type'=>'integer',      'label'=>'UserModif',        'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511),
     		//'fk_user_valid' =>array('type'=>'integer',      'label'=>'UserValidation',        'enabled'=>1, 'visible'=>-1, 'position'=>512),
    @@ -97,16 +101,46 @@ class MyObject extends CommonObject
     	    'status'        =>array('type'=>'integer',      'label'=>'Status',           'enabled'=>1, 'visible'=>1,  'notnull'=>1, 'default'=>0, 'index'=>1,  'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')),
     	);
     
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    -	public $label;
    +
    +	/**
    +     * @var string label
    +     */
    +    public $label;
    +
     	public $amount;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	public $date_creation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
     	public $import_key;
     	// END MODULEBUILDER PROPERTIES
     
    @@ -118,18 +152,22 @@ class MyObject extends CommonObject
     	 * @var int    Name of subtable line
     	 */
     	//public $table_element_line = 'myobjectdet';
    +
     	/**
     	 * @var int    Field with ID of parent key if this field has a parent
     	 */
     	//public $fk_element = 'fk_myobject';
    +
     	/**
     	 * @var int    Name of subtable class that manage subtable lines
     	 */
     	//public $class_element_line = 'MyObjectline';
    +
     	/**
     	 * @var array  Array of child tables (child tables to delete before deleting a record)
     	 */
     	//protected $childtables=array('myobjectdet');
    +
     	/**
     	 * @var MyObjectLine[]     Array of subtable lines
     	 */
    @@ -144,7 +182,7 @@ class MyObject extends CommonObject
     	 */
     	public function __construct(DoliDB $db)
     	{
    -		global $conf, $user;
    +		global $conf, $langs, $user;
     
     		$this->db = $db;
     
    @@ -159,6 +197,9 @@ class MyObject extends CommonObject
     				unset($this->fields[$key]);
     			}
     		}
    +
    +		// Translate some data
    +		$this->fields['status']['arrayofkeyval']=array(0=>$langs->trans('Draft'), 1=>$langs->trans('Active'), -1=>$langs->trans('Cancel'));
     	}
     
     	/**
    @@ -182,7 +223,7 @@ class MyObject extends CommonObject
     	 */
     	public function createFromClone(User $user, $fromid)
     	{
    -		global $hookmanager, $langs;
    +		global $langs, $hookmanager, $extrafields;
     	    $error = 0;
     
     	    dol_syslog(__METHOD__, LOG_DEBUG);
    @@ -202,6 +243,20 @@ class MyObject extends CommonObject
     	    $object->ref = "copy_of_".$object->ref;
     	    $object->title = $langs->trans("CopyOf")." ".$object->title;
     	    // ...
    +	    // Clear extrafields that are unique
    +	    if (is_array($object->array_options) && count($object->array_options) > 0)
    +	    {
    +	    	$extrafields->fetch_name_optionals_label($this->element);
    +	    	foreach($object->array_options as $key => $option)
    +	    	{
    +	    		$shortkey = preg_replace('/options_/', '', $key);
    +	    		if (! empty($extrafields->attributes[$this->element]['unique'][$shortkey]))
    +	    		{
    +	    			//var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
    +	    			unset($object->array_options[$key]);
    +	    		}
    +	    	}
    +	    }
     
     	    // Create clone
     		$object->context['createfromclone'] = 'createfromclone';
    @@ -339,7 +394,7 @@ class MyObject extends CommonObject
     		$result .= $linkend;
     		//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
     
    -		global $action;
    +		global $action,$hookmanager;
     		$hookmanager->initHooks(array('myobjectdao'));
     		$parameters=array('id'=>$this->id, 'getnomurl'=>$result);
     		$reshook=$hookmanager->executeHooks('getNomUrl',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    @@ -360,6 +415,7 @@ class MyObject extends CommonObject
     		return $this->LibStatut($this->status, $mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -369,6 +425,7 @@ class MyObject extends CommonObject
     	 */
     	function LibStatut($status, $mode=0)
     	{
    +		// phpcs:enable
     		if (empty($this->labelstatus))
     		{
     			global $langs;
    @@ -381,34 +438,34 @@ class MyObject extends CommonObject
     		{
     			return $this->labelstatus[$status];
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $this->labelstatus[$status];
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($this->labelstatus[$status],'statut4').' '.$this->labelstatus[$status];
    -			if ($status == 0) return img_picto($this->labelstatus[$status],'statut5').' '.$this->labelstatus[$status];
    +			elseif ($status == 0) return img_picto($this->labelstatus[$status],'statut5').' '.$this->labelstatus[$status];
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($this->labelstatus[$status],'statut4');
    -			if ($status == 0) return img_picto($this->labelstatus[$status],'statut5');
    +			elseif ($status == 0) return img_picto($this->labelstatus[$status],'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($this->labelstatus[$status],'statut4').' '.$this->labelstatus[$status];
    -			if ($status == 0) return img_picto($this->labelstatus[$status],'statut5').' '.$this->labelstatus[$status];
    +			elseif ($status == 0) return img_picto($this->labelstatus[$status],'statut5').' '.$this->labelstatus[$status];
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut4');
    -			if ($status == 0) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut5');
    +			elseif ($status == 0) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 1) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut4');
    -			if ($status == 0) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut5');
    +			elseif ($status == 0) return $this->labelstatus[$status].' '.img_picto($this->labelstatus[$status],'statut5');
     		}
     	}
     
    @@ -458,7 +515,6 @@ class MyObject extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -522,4 +578,4 @@ class MyObjectLine
     	// @var mixed Sample line property 2
     	public $prop2;
     }
    -*/
    \ No newline at end of file
    +*/
    diff --git a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php
    index cd8612cb7d1..545e53d350a 100644
    --- a/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php
    +++ b/htdocs/modulebuilder/template/core/modules/mailings/mailinglist_mymodule_myobject.modules.php
    @@ -27,7 +27,11 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets
     	var $enabled=0;
     	var $require_module=array();
     	var $picto='mymodule@mymodule';
    -	var $db;
    +
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     
     	/**
    @@ -88,6 +92,7 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  This is the main function that returns the array of emails
     	 *
    @@ -97,6 +102,7 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets
     	 */
     	function add_to_target($mailing_id,$filtersarray=array())
     	{
    +        // phpcs:enable
     		$target = array();
     		$cibles = array();
     		$j = 0;
    @@ -195,6 +201,4 @@ class mailing_mailinglist_mymodule_myobject extends MailingTargets
     		if ($a < 0) return -1;
     		return $a;
     	}
    -
     }
    -
    diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
    index aac3f6b2c5f..e81b75c1815 100644
    --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
    +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018	   Nicolas ZABOURI 	<info@inovea-conseil.com>
      * Copyright (C) ---Put here your own copyright and developer email---
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -27,15 +28,11 @@
     include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
     
     
    -// The class name should start with a lower case mod for Dolibarr to pick it up
    -// so we ignore the Squiz.Classes.ValidClassName.NotCamelCaps rule.
    -// @codingStandardsIgnoreStart
     /**
      *  Description and activation class for module MyModule
      */
     class modMyModule extends DolibarrModules
     {
    -	// @codingStandardsIgnoreEnd
     	/**
     	 * Constructor. Define names, constants, directories, boxes, permissions
     	 *
    @@ -58,12 +55,12 @@ class modMyModule extends DolibarrModules
     		$this->family = "other";
     		// Module position in the family on 2 digits ('01', '10', '20', ...)
     		$this->module_position = '90';
    -		// Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
    +		// Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
     		//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
     
    -		// Module label (no space allowed), used if translation string 'ModuleMyModuleName' not found (MyModue is name of module).
    +		// Module label (no space allowed), used if translation string 'ModuleMyModuleName' not found (MyModule is name of module).
     		$this->name = preg_replace('/^mod/i','',get_class($this));
    -		// Module description, used if translation string 'ModuleMyModuleDesc' not found (MyModue is name of module).
    +		// Module description, used if translation string 'ModuleMyModuleDesc' not found (MyModule is name of module).
     		$this->description = "MyModuleDescription";
     		// Used only if file README.md and README-LL.md not found.
     		$this->descriptionlong = "MyModuleDescription (Long)";
    @@ -73,6 +70,9 @@ class modMyModule extends DolibarrModules
     
     		// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
     		$this->version = '1.0';
    +
    +        //Url to the file with your last numberversion of this module
    +        //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
     		// Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
     		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
     		// Name of image file used for this module.
    @@ -85,19 +85,19 @@ class modMyModule extends DolibarrModules
     		// for specific path of parts (eg: /mymodule/core/modules/barcode)
     		// for specific css file (eg: /mymodule/css/mymodule.css.php)
     		$this->module_parts = array(
    -		                        	'triggers' => 1,                                 	// Set this to 1 if module has its own trigger directory (core/triggers)
    -									'login' => 0,                                    	// Set this to 1 if module has its own login method file (core/login)
    -									'substitutions' => 1,                            	// Set this to 1 if module has its own substitution function file (core/substitutions)
    -									'menus' => 0,                                    	// Set this to 1 if module has its own menus handler directory (core/menus)
    -									'theme' => 0,                                    	// Set this to 1 if module has its own theme directory (theme)
    -		                        	'tpl' => 0,                                      	// Set this to 1 if module overwrite template dir (core/tpl)
    -									'barcode' => 0,                                  	// Set this to 1 if module has its own barcode directory (core/modules/barcode)
    -									'models' => 0,                                   	// Set this to 1 if module has its own models directory (core/modules/xxx)
    -									'css' => array('/mymodule/css/mymodule.css.php'),	// Set this to relative path of css file if module has its own css file
    -	 								'js' => array('/mymodule/js/mymodule.js.php'),          // Set this to relative path of js file if module must load a js on all pages
    -									'hooks' => array('data'=>array('hookcontext1','hookcontext2'), 'entity'=>'0'), 	// Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
    -									'moduleforexternal' => 0							// Set this to 1 if feature of module are opened to external users
    -		                        );
    +		    'triggers' => 1,                                 	// Set this to 1 if module has its own trigger directory (core/triggers)
    +			'login' => 0,                                    	// Set this to 1 if module has its own login method file (core/login)
    +			'substitutions' => 1,                            	// Set this to 1 if module has its own substitution function file (core/substitutions)
    +			'menus' => 0,                                    	// Set this to 1 if module has its own menus handler directory (core/menus)
    +			'theme' => 0,                                    	// Set this to 1 if module has its own theme directory (theme)
    +		    'tpl' => 0,                                      	// Set this to 1 if module overwrite template dir (core/tpl)
    +			'barcode' => 0,                                  	// Set this to 1 if module has its own barcode directory (core/modules/barcode)
    +			'models' => 0,                                   	// Set this to 1 if module has its own models directory (core/modules/xxx)
    +			'css' => array('/mymodule/css/mymodule.css.php'),	// Set this to relative path of css file if module has its own css file
    +	 		'js' => array('/mymodule/js/mymodule.js.php'),          // Set this to relative path of js file if module must load a js on all pages
    +			'hooks' => array('data'=>array('hookcontext1','hookcontext2'), 'entity'=>'0'), 	// Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
    +			'moduleforexternal' => 0							// Set this to 1 if feature of module are opened to external users
    +		);
     
     		// Data directories to create when module is enabled.
     		// Example: this->dirs = array("/mymodule/temp","/mymodule/subdir");
    @@ -112,7 +112,7 @@ class modMyModule extends DolibarrModules
     		$this->requiredby = array();	// List of module class names to disable if this one is disabled
     		$this->conflictwith = array();	// List of module class names as string this module is in conflict with
     		$this->langfiles = array("mymodule@mymodule");
    -		$this->phpmin = array(5,3);					// Minimum version of PHP required by module
    +		$this->phpmin = array(5,4);					// Minimum version of PHP required by module
     		$this->need_dolibarr_version = array(4,0);	// Minimum version of Dolibarr required by module
     		$this->warnings_activation = array();                     // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
     		$this->warnings_activation_ext = array();                 // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    @@ -346,5 +346,4 @@ class modMyModule extends DolibarrModules
     
     		return $this->_remove($sql, $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 b325f2f7443..1935054893b 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
    @@ -113,11 +113,6 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers
     		    //case 'USER_SETINGROUP':
     		    //case 'USER_REMOVEFROMGROUP':
     
    -		    //case 'USER_LOGIN':
    -		    //case 'USER_LOGIN_FAILED':
    -		    //case 'USER_LOGOUT':
    -		    //case 'USER_UPDATE_SESSION':      // Warning: To increase performances, this action is triggered only if constant MAIN_ACTIVATE_UPDATESESSIONTRIGGER is set to 1.
    -
     		    // Actions
     		    //case 'ACTION_MODIFY':
     		    //case 'ACTION_CREATE':
    diff --git a/htdocs/modulebuilder/template/css/mymodule.css.php b/htdocs/modulebuilder/template/css/mymodule.css.php
    index 5787fa4f64c..486d860e7f5 100644
    --- a/htdocs/modulebuilder/template/css/mymodule.css.php
    +++ b/htdocs/modulebuilder/template/css/mymodule.css.php
    @@ -35,15 +35,15 @@ if (! defined('NOREQUIREAJAX'))   define('NOREQUIREAJAX','1');
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/../main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/../main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/../main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/../main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    diff --git a/htdocs/modulebuilder/template/doc/user/Makefile b/htdocs/modulebuilder/template/doc/user/Makefile
    deleted file mode 100644
    index 5c33e8bf0a3..00000000000
    --- a/htdocs/modulebuilder/template/doc/user/Makefile
    +++ /dev/null
    @@ -1,225 +0,0 @@
    -# Makefile for Sphinx documentation
    -#
    -
    -# You can set these variables from the command line.
    -SPHINXOPTS    =
    -SPHINXBUILD   = sphinx-build
    -PAPER         =
    -BUILDDIR      = build
    -
    -# Internal variables.
    -PAPEROPT_a4     = -D latex_paper_size=a4
    -PAPEROPT_letter = -D latex_paper_size=letter
    -ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
    -# the i18n builder cannot share the environment and doctrees with the others
    -I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
    -
    -.PHONY: help
    -help:
    -	@echo "Please use \`make <target>' where <target> is one of"
    -	@echo "  html       to make standalone HTML files"
    -	@echo "  dirhtml    to make HTML files named index.html in directories"
    -	@echo "  singlehtml to make a single large HTML file"
    -	@echo "  pickle     to make pickle files"
    -	@echo "  json       to make JSON files"
    -	@echo "  htmlhelp   to make HTML files and a HTML help project"
    -	@echo "  qthelp     to make HTML files and a qthelp project"
    -	@echo "  applehelp  to make an Apple Help Book"
    -	@echo "  devhelp    to make HTML files and a Devhelp project"
    -	@echo "  epub       to make an epub"
    -	@echo "  epub3      to make an epub3"
    -	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
    -	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
    -	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
    -	@echo "  text       to make text files"
    -	@echo "  man        to make manual pages"
    -	@echo "  texinfo    to make Texinfo files"
    -	@echo "  info       to make Texinfo files and run them through makeinfo"
    -	@echo "  gettext    to make PO message catalogs"
    -	@echo "  changes    to make an overview of all changed/added/deprecated items"
    -	@echo "  xml        to make Docutils-native XML files"
    -	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
    -	@echo "  linkcheck  to check all external links for integrity"
    -	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
    -	@echo "  coverage   to run coverage check of the documentation (if enabled)"
    -	@echo "  dummy      to check syntax errors of document sources"
    -
    -.PHONY: clean
    -clean:
    -	rm -rf $(BUILDDIR)/*
    -
    -.PHONY: html
    -html:
    -	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
    -	@echo
    -	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
    -
    -.PHONY: dirhtml
    -dirhtml:
    -	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
    -	@echo
    -	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
    -
    -.PHONY: singlehtml
    -singlehtml:
    -	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
    -	@echo
    -	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
    -
    -.PHONY: pickle
    -pickle:
    -	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
    -	@echo
    -	@echo "Build finished; now you can process the pickle files."
    -
    -.PHONY: json
    -json:
    -	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
    -	@echo
    -	@echo "Build finished; now you can process the JSON files."
    -
    -.PHONY: htmlhelp
    -htmlhelp:
    -	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
    -	@echo
    -	@echo "Build finished; now you can run HTML Help Workshop with the" \
    -	      ".hhp project file in $(BUILDDIR)/htmlhelp."
    -
    -.PHONY: qthelp
    -qthelp:
    -	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
    -	@echo
    -	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
    -	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
    -	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Mymodule.qhcp"
    -	@echo "To view the help file:"
    -	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Mymodule.qhc"
    -
    -.PHONY: applehelp
    -applehelp:
    -	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
    -	@echo
    -	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
    -	@echo "N.B. You won't be able to view it unless you put it in" \
    -	      "~/Library/Documentation/Help or install it in your application" \
    -	      "bundle."
    -
    -.PHONY: devhelp
    -devhelp:
    -	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
    -	@echo
    -	@echo "Build finished."
    -	@echo "To view the help file:"
    -	@echo "# mkdir -p $$HOME/.local/share/devhelp/Mymodule"
    -	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Mymodule"
    -	@echo "# devhelp"
    -
    -.PHONY: epub
    -epub:
    -	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
    -	@echo
    -	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
    -
    -.PHONY: epub3
    -epub3:
    -	$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
    -	@echo
    -	@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
    -
    -.PHONY: latex
    -latex:
    -	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
    -	@echo
    -	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
    -	@echo "Run \`make' in that directory to run these through (pdf)latex" \
    -	      "(use \`make latexpdf' here to do that automatically)."
    -
    -.PHONY: latexpdf
    -latexpdf:
    -	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
    -	@echo "Running LaTeX files through pdflatex..."
    -	$(MAKE) -C $(BUILDDIR)/latex all-pdf
    -	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
    -
    -.PHONY: latexpdfja
    -latexpdfja:
    -	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
    -	@echo "Running LaTeX files through platex and dvipdfmx..."
    -	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
    -	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
    -
    -.PHONY: text
    -text:
    -	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
    -	@echo
    -	@echo "Build finished. The text files are in $(BUILDDIR)/text."
    -
    -.PHONY: man
    -man:
    -	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
    -	@echo
    -	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
    -
    -.PHONY: texinfo
    -texinfo:
    -	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
    -	@echo
    -	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
    -	@echo "Run \`make' in that directory to run these through makeinfo" \
    -	      "(use \`make info' here to do that automatically)."
    -
    -.PHONY: info
    -info:
    -	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
    -	@echo "Running Texinfo files through makeinfo..."
    -	make -C $(BUILDDIR)/texinfo info
    -	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
    -
    -.PHONY: gettext
    -gettext:
    -	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
    -	@echo
    -	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
    -
    -.PHONY: changes
    -changes:
    -	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
    -	@echo
    -	@echo "The overview file is in $(BUILDDIR)/changes."
    -
    -.PHONY: linkcheck
    -linkcheck:
    -	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
    -	@echo
    -	@echo "Link check complete; look for any errors in the above output " \
    -	      "or in $(BUILDDIR)/linkcheck/output.txt."
    -
    -.PHONY: doctest
    -doctest:
    -	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
    -	@echo "Testing of doctests in the sources finished, look at the " \
    -	      "results in $(BUILDDIR)/doctest/output.txt."
    -
    -.PHONY: coverage
    -coverage:
    -	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
    -	@echo "Testing of coverage in the sources finished, look at the " \
    -	      "results in $(BUILDDIR)/coverage/python.txt."
    -
    -.PHONY: xml
    -xml:
    -	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
    -	@echo
    -	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
    -
    -.PHONY: pseudoxml
    -pseudoxml:
    -	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
    -	@echo
    -	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
    -
    -.PHONY: dummy
    -dummy:
    -	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
    -	@echo
    -	@echo "Build finished. Dummy builder generates no files."
    diff --git a/htdocs/modulebuilder/template/doc/user/make.bat b/htdocs/modulebuilder/template/doc/user/make.bat
    deleted file mode 100644
    index 35018adf3ba..00000000000
    --- a/htdocs/modulebuilder/template/doc/user/make.bat
    +++ /dev/null
    @@ -1,281 +0,0 @@
    -@ECHO OFF
    -
    -REM Command file for Sphinx documentation
    -
    -if "%SPHINXBUILD%" == "" (
    -	set SPHINXBUILD=sphinx-build
    -)
    -set BUILDDIR=build
    -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
    -set I18NSPHINXOPTS=%SPHINXOPTS% source
    -if NOT "%PAPER%" == "" (
    -	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
    -	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
    -)
    -
    -if "%1" == "" goto help
    -
    -if "%1" == "help" (
    -	:help
    -	echo.Please use `make ^<target^>` where ^<target^> is one of
    -	echo.  html       to make standalone HTML files
    -	echo.  dirhtml    to make HTML files named index.html in directories
    -	echo.  singlehtml to make a single large HTML file
    -	echo.  pickle     to make pickle files
    -	echo.  json       to make JSON files
    -	echo.  htmlhelp   to make HTML files and a HTML help project
    -	echo.  qthelp     to make HTML files and a qthelp project
    -	echo.  devhelp    to make HTML files and a Devhelp project
    -	echo.  epub       to make an epub
    -	echo.  epub3      to make an epub3
    -	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
    -	echo.  text       to make text files
    -	echo.  man        to make manual pages
    -	echo.  texinfo    to make Texinfo files
    -	echo.  gettext    to make PO message catalogs
    -	echo.  changes    to make an overview over all changed/added/deprecated items
    -	echo.  xml        to make Docutils-native XML files
    -	echo.  pseudoxml  to make pseudoxml-XML files for display purposes
    -	echo.  linkcheck  to check all external links for integrity
    -	echo.  doctest    to run all doctests embedded in the documentation if enabled
    -	echo.  coverage   to run coverage check of the documentation if enabled
    -	echo.  dummy      to check syntax errors of document sources
    -	goto end
    -)
    -
    -if "%1" == "clean" (
    -	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
    -	del /q /s %BUILDDIR%\*
    -	goto end
    -)
    -
    -
    -REM Check if sphinx-build is available and fallback to Python version if any
    -%SPHINXBUILD% 1>NUL 2>NUL
    -if errorlevel 9009 goto sphinx_python
    -goto sphinx_ok
    -
    -:sphinx_python
    -
    -set SPHINXBUILD=python -m sphinx.__init__
    -%SPHINXBUILD% 2> nul
    -if errorlevel 9009 (
    -	echo.
    -	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
    -	echo.installed, then set the SPHINXBUILD environment variable to point
    -	echo.to the full path of the 'sphinx-build' executable. Alternatively you
    -	echo.may add the Sphinx directory to PATH.
    -	echo.
    -	echo.If you don't have Sphinx installed, grab it from
    -	echo.http://sphinx-doc.org/
    -	exit /b 1
    -)
    -
    -:sphinx_ok
    -
    -
    -if "%1" == "html" (
    -	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
    -	goto end
    -)
    -
    -if "%1" == "dirhtml" (
    -	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
    -	goto end
    -)
    -
    -if "%1" == "singlehtml" (
    -	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
    -	goto end
    -)
    -
    -if "%1" == "pickle" (
    -	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished; now you can process the pickle files.
    -	goto end
    -)
    -
    -if "%1" == "json" (
    -	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished; now you can process the JSON files.
    -	goto end
    -)
    -
    -if "%1" == "htmlhelp" (
    -	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished; now you can run HTML Help Workshop with the ^
    -.hhp project file in %BUILDDIR%/htmlhelp.
    -	goto end
    -)
    -
    -if "%1" == "qthelp" (
    -	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished; now you can run "qcollectiongenerator" with the ^
    -.qhcp project file in %BUILDDIR%/qthelp, like this:
    -	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Mymodule.qhcp
    -	echo.To view the help file:
    -	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Mymodule.ghc
    -	goto end
    -)
    -
    -if "%1" == "devhelp" (
    -	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished.
    -	goto end
    -)
    -
    -if "%1" == "epub" (
    -	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The epub file is in %BUILDDIR%/epub.
    -	goto end
    -)
    -
    -if "%1" == "epub3" (
    -	%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
    -	goto end
    -)
    -
    -if "%1" == "latex" (
    -	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
    -	goto end
    -)
    -
    -if "%1" == "latexpdf" (
    -	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
    -	cd %BUILDDIR%/latex
    -	make all-pdf
    -	cd %~dp0
    -	echo.
    -	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
    -	goto end
    -)
    -
    -if "%1" == "latexpdfja" (
    -	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
    -	cd %BUILDDIR%/latex
    -	make all-pdf-ja
    -	cd %~dp0
    -	echo.
    -	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
    -	goto end
    -)
    -
    -if "%1" == "text" (
    -	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The text files are in %BUILDDIR%/text.
    -	goto end
    -)
    -
    -if "%1" == "man" (
    -	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The manual pages are in %BUILDDIR%/man.
    -	goto end
    -)
    -
    -if "%1" == "texinfo" (
    -	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
    -	goto end
    -)
    -
    -if "%1" == "gettext" (
    -	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
    -	goto end
    -)
    -
    -if "%1" == "changes" (
    -	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.The overview file is in %BUILDDIR%/changes.
    -	goto end
    -)
    -
    -if "%1" == "linkcheck" (
    -	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Link check complete; look for any errors in the above output ^
    -or in %BUILDDIR%/linkcheck/output.txt.
    -	goto end
    -)
    -
    -if "%1" == "doctest" (
    -	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Testing of doctests in the sources finished, look at the ^
    -results in %BUILDDIR%/doctest/output.txt.
    -	goto end
    -)
    -
    -if "%1" == "coverage" (
    -	%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Testing of coverage in the sources finished, look at the ^
    -results in %BUILDDIR%/coverage/python.txt.
    -	goto end
    -)
    -
    -if "%1" == "xml" (
    -	%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The XML files are in %BUILDDIR%/xml.
    -	goto end
    -)
    -
    -if "%1" == "pseudoxml" (
    -	%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
    -	goto end
    -)
    -
    -if "%1" == "dummy" (
    -	%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
    -	if errorlevel 1 exit /b 1
    -	echo.
    -	echo.Build finished. Dummy builder generates no files.
    -	goto end
    -)
    -
    -:end
    diff --git a/htdocs/modulebuilder/template/doc/user/source/conf.py b/htdocs/modulebuilder/template/doc/user/source/conf.py
    deleted file mode 100644
    index 130bd5a12e5..00000000000
    --- a/htdocs/modulebuilder/template/doc/user/source/conf.py
    +++ /dev/null
    @@ -1,428 +0,0 @@
    -#!/usr/bin/env python3
    -# -*- coding: utf-8 -*-
    -#
    -# My Module documentation build configuration file, created by
    -# sphinx-quickstart on Mon Sep 26 17:54:17 2016.
    -#
    -# This file is execfile()d with the current directory set to its
    -# containing dir.
    -#
    -# Note that not all possible configuration values are present in this
    -# autogenerated file.
    -#
    -# All configuration values have a default; values that are commented out
    -# serve to show the default.
    -
    -# If extensions (or modules to document with autodoc) are in another directory,
    -# add these directories to sys.path here. If the directory is relative to the
    -# documentation root, use os.path.abspath to make it absolute, like shown here.
    -#
    -# import os
    -# import sys
    -# sys.path.insert(0, os.path.abspath('.'))
    -
    -# -- General configuration ------------------------------------------------
    -
    -# If your documentation needs a minimal Sphinx version, state it here.
    -#
    -# needs_sphinx = '1.0'
    -
    -# Add any Sphinx extension module names here, as strings. They can be
    -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
    -# ones.
    -extensions = [
    -    'sphinx.ext.todo',
    -    'sphinx.ext.imgmath',
    -    'sphinx.ext.githubpages',
    -]
    -
    -# Add any paths that contain templates here, relative to this directory.
    -templates_path = ['_templates']
    -
    -# The suffix(es) of source filenames.
    -# You can specify multiple suffix as a list of string:
    -#
    -# source_suffix = ['.rst', '.md']
    -source_suffix = '.rst'
    -
    -# The encoding of source files.
    -#
    -# source_encoding = 'utf-8-sig'
    -
    -# The master toctree document.
    -master_doc = 'index'
    -
    -# General information about the project.
    -project = 'My Module'
    -copyright = '2016, Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>'
    -author = 'Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>'
    -
    -# The version info for the project you're documenting, acts as replacement for
    -# |version| and |release|, also used in various other places throughout the
    -# built documents.
    -#
    -# The short X.Y version.
    -version = 'development'
    -# The full version, including alpha/beta/rc tags.
    -release = 'development'
    -
    -# The language for content autogenerated by Sphinx. Refer to documentation
    -# for a list of supported languages.
    -#
    -# This is also used if you do content translation via gettext catalogs.
    -# Usually you set "language" from the command line for these cases.
    -language = None
    -
    -# There are two options for replacing |today|: either, you set today to some
    -# non-false value, then it is used:
    -#
    -# today = ''
    -#
    -# Else, today_fmt is used as the format for a strftime call.
    -#
    -# today_fmt = '%B %d, %Y'
    -
    -# List of patterns, relative to source directory, that match files and
    -# directories to ignore when looking for source files.
    -# This patterns also effect to html_static_path and html_extra_path
    -exclude_patterns = []
    -
    -# The reST default role (used for this markup: `text`) to use for all
    -# documents.
    -#
    -# default_role = None
    -
    -# If true, '()' will be appended to :func: etc. cross-reference text.
    -#
    -# add_function_parentheses = True
    -
    -# If true, the current module name will be prepended to all description
    -# unit titles (such as .. function::).
    -#
    -# add_module_names = True
    -
    -# If true, sectionauthor and moduleauthor directives will be shown in the
    -# output. They are ignored by default.
    -#
    -# show_authors = False
    -
    -# The name of the Pygments (syntax highlighting) style to use.
    -pygments_style = 'sphinx'
    -
    -# A list of ignored prefixes for module index sorting.
    -# modindex_common_prefix = []
    -
    -# If true, keep warnings as "system message" paragraphs in the built documents.
    -# keep_warnings = False
    -
    -# If true, `todo` and `todoList` produce output, else they produce nothing.
    -todo_include_todos = True
    -
    -
    -# -- Options for HTML output ----------------------------------------------
    -
    -# The theme to use for HTML and HTML Help pages.  See the documentation for
    -# a list of builtin themes.
    -#
    -html_theme = 'alabaster'
    -
    -# Theme options are theme-specific and customize the look and feel of a theme
    -# further.  For a list of options available for each theme, see the
    -# documentation.
    -#
    -# html_theme_options = {}
    -
    -# Add any paths that contain custom themes here, relative to this directory.
    -# html_theme_path = []
    -
    -# The name for this set of Sphinx documents.
    -# "<project> v<release> documentation" by default.
    -#
    -# html_title = 'My Module vdevelopment'
    -
    -# A shorter title for the navigation bar.  Default is the same as html_title.
    -#
    -# html_short_title = None
    -
    -# The name of an image file (relative to this directory) to place at the top
    -# of the sidebar.
    -#
    -# html_logo = None
    -
    -# The name of an image file (relative to this directory) to use as a favicon of
    -# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
    -# pixels large.
    -#
    -# html_favicon = None
    -
    -# Add any paths that contain custom static files (such as style sheets) here,
    -# relative to this directory. They are copied after the builtin static files,
    -# so a file named "default.css" will overwrite the builtin "default.css".
    -html_static_path = ['_static']
    -
    -# Add any extra paths that contain custom files (such as robots.txt or
    -# .htaccess) here, relative to this directory. These files are copied
    -# directly to the root of the documentation.
    -#
    -# html_extra_path = []
    -
    -# If not None, a 'Last updated on:' timestamp is inserted at every page
    -# bottom, using the given strftime format.
    -# The empty string is equivalent to '%b %d, %Y'.
    -#
    -# html_last_updated_fmt = None
    -
    -# If true, SmartyPants will be used to convert quotes and dashes to
    -# typographically correct entities.
    -#
    -# html_use_smartypants = True
    -
    -# Custom sidebar templates, maps document names to template names.
    -#
    -# html_sidebars = {}
    -
    -# Additional templates that should be rendered to pages, maps page names to
    -# template names.
    -#
    -# html_additional_pages = {}
    -
    -# If false, no module index is generated.
    -#
    -# html_domain_indices = True
    -
    -# If false, no index is generated.
    -#
    -# html_use_index = True
    -
    -# If true, the index is split into individual pages for each letter.
    -#
    -# html_split_index = False
    -
    -# If true, links to the reST sources are added to the pages.
    -#
    -# html_show_sourcelink = True
    -
    -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
    -#
    -# html_show_sphinx = True
    -
    -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
    -#
    -# html_show_copyright = True
    -
    -# If true, an OpenSearch description file will be output, and all pages will
    -# contain a <link> tag referring to it.  The value of this option must be the
    -# base URL from which the finished HTML is served.
    -#
    -# html_use_opensearch = ''
    -
    -# This is the file name suffix for HTML files (e.g. ".xhtml").
    -# html_file_suffix = None
    -
    -# Language to be used for generating the HTML full-text search index.
    -# Sphinx supports the following languages:
    -#   'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
    -#   'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'
    -#
    -# html_search_language = 'en'
    -
    -# A dictionary with options for the search language support, empty by default.
    -# 'ja' uses this config value.
    -# 'zh' user can custom change `jieba` dictionary path.
    -#
    -# html_search_options = {'type': 'default'}
    -
    -# The name of a javascript file (relative to the configuration directory) that
    -# implements a search results scorer. If empty, the default will be used.
    -#
    -# html_search_scorer = 'scorer.js'
    -
    -# Output file base name for HTML help builder.
    -htmlhelp_basename = 'Mymoduledoc'
    -
    -# -- Options for LaTeX output ---------------------------------------------
    -
    -latex_elements = {
    -     # The paper size ('letterpaper' or 'a4paper').
    -     #
    -     # 'papersize': 'letterpaper',
    -
    -     # The font size ('10pt', '11pt' or '12pt').
    -     #
    -     # 'pointsize': '10pt',
    -
    -     # Additional stuff for the LaTeX preamble.
    -     #
    -     # 'preamble': '',
    -
    -     # Latex figure (float) alignment
    -     #
    -     # 'figure_align': 'htbp',
    -}
    -
    -# Grouping the document tree into LaTeX files. List of tuples
    -# (source start file, target name, title,
    -#  author, documentclass [howto, manual, or own class]).
    -latex_documents = [
    -    (master_doc, 'Mymodule.tex', 'My Module Documentation',
    -     'Raphaël Doursenaud \\textless{}rdoursenaud@gpcsolutions.fr\\textgreater{}', 'manual'),
    -]
    -
    -# The name of an image file (relative to this directory) to place at the top of
    -# the title page.
    -#
    -# latex_logo = None
    -
    -# For "manual" documents, if this is true, then toplevel headings are parts,
    -# not chapters.
    -#
    -# latex_use_parts = False
    -
    -# If true, show page references after internal links.
    -#
    -# latex_show_pagerefs = False
    -
    -# If true, show URL addresses after external links.
    -#
    -# latex_show_urls = False
    -
    -# Documents to append as an appendix to all manuals.
    -#
    -# latex_appendices = []
    -
    -# It false, will not define \strong, \code, 	itleref, \crossref ... but only
    -# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
    -# packages.
    -#
    -# latex_keep_old_macro_names = True
    -
    -# If false, no module index is generated.
    -#
    -# latex_domain_indices = True
    -
    -
    -# -- Options for manual page output ---------------------------------------
    -
    -# One entry per manual page. List of tuples
    -# (source start file, name, description, authors, manual section).
    -man_pages = [
    -    (master_doc, 'mymodule', 'My Module Documentation',
    -     [author], 1)
    -]
    -
    -# If true, show URL addresses after external links.
    -#
    -# man_show_urls = False
    -
    -
    -# -- Options for Texinfo output -------------------------------------------
    -
    -# Grouping the document tree into Texinfo files. List of tuples
    -# (source start file, target name, title, author,
    -#  dir menu entry, description, category)
    -texinfo_documents = [
    -    (master_doc, 'Mymodule', 'My Module Documentation',
    -     author, 'Mymodule', 'One line description of project.',
    -     'Miscellaneous'),
    -]
    -
    -# Documents to append as an appendix to all manuals.
    -#
    -# texinfo_appendices = []
    -
    -# If false, no module index is generated.
    -#
    -# texinfo_domain_indices = True
    -
    -# How to display URL addresses: 'footnote', 'no', or 'inline'.
    -#
    -# texinfo_show_urls = 'footnote'
    -
    -# If true, do not generate a @detailmenu in the "Top" node's menu.
    -#
    -# texinfo_no_detailmenu = False
    -
    -
    -# -- Options for Epub output ----------------------------------------------
    -
    -# Bibliographic Dublin Core info.
    -epub_title = project
    -epub_author = author
    -epub_publisher = author
    -epub_copyright = copyright
    -
    -# The basename for the epub file. It defaults to the project name.
    -# epub_basename = project
    -
    -# The HTML theme for the epub output. Since the default themes are not
    -# optimized for small screen space, using the same theme for HTML and epub
    -# output is usually not wise. This defaults to 'epub', a theme designed to save
    -# visual space.
    -#
    -# epub_theme = 'epub'
    -
    -# The language of the text. It defaults to the language option
    -# or 'en' if the language is not set.
    -#
    -# epub_language = ''
    -
    -# The scheme of the identifier. Typical schemes are ISBN or URL.
    -# epub_scheme = ''
    -
    -# The unique identifier of the text. This can be a ISBN number
    -# or the project homepage.
    -#
    -# epub_identifier = ''
    -
    -# A unique identification for the text.
    -#
    -# epub_uid = ''
    -
    -# A tuple containing the cover image and cover page html template filenames.
    -#
    -# epub_cover = ()
    -
    -# A sequence of (type, uri, title) tuples for the guide element of content.opf.
    -#
    -# epub_guide = ()
    -
    -# HTML files that should be inserted before the pages created by sphinx.
    -# The format is a list of tuples containing the path and title.
    -#
    -# epub_pre_files = []
    -
    -# HTML files that should be inserted after the pages created by sphinx.
    -# The format is a list of tuples containing the path and title.
    -#
    -# epub_post_files = []
    -
    -# A list of files that should not be packed into the epub file.
    -epub_exclude_files = ['search.html']
    -
    -# The depth of the table of contents in toc.ncx.
    -#
    -# epub_tocdepth = 3
    -
    -# Allow duplicate toc entries.
    -#
    -# epub_tocdup = True
    -
    -# Choose between 'default' and 'includehidden'.
    -#
    -# epub_tocscope = 'default'
    -
    -# Fix unsupported image types using the Pillow.
    -#
    -# epub_fix_images = False
    -
    -# Scale large images.
    -#
    -# epub_max_image_width = 0
    -
    -# How to display URL addresses: 'footnote', 'no', or 'inline'.
    -#
    -# epub_show_urls = 'inline'
    -
    -# If false, no index is generated.
    -#
    -# epub_use_index = True
    diff --git a/htdocs/modulebuilder/template/doc/user/source/index.rst b/htdocs/modulebuilder/template/doc/user/source/index.rst
    deleted file mode 100644
    index 48f2a6e49d8..00000000000
    --- a/htdocs/modulebuilder/template/doc/user/source/index.rst
    +++ /dev/null
    @@ -1,22 +0,0 @@
    -.. My Module documentation master file, created by
    -   sphinx-quickstart on Mon Sep 26 17:54:17 2016.
    -   You can adapt this file completely to your liking, but it should at least
    -   contain the root `toctree` directive.
    -
    -Welcome to My Module's documentation!
    -=====================================
    -
    -Contents:
    -
    -.. toctree::
    -   :maxdepth: 2
    -
    -
    -
    -Indices and tables
    -==================
    -
    -* :ref:`genindex`
    -* :ref:`modindex`
    -* :ref:`search`
    -
    diff --git a/htdocs/modulebuilder/template/js/mymodule.js.php b/htdocs/modulebuilder/template/js/mymodule.js.php
    index 07f44756615..6a3447625a5 100644
    --- a/htdocs/modulebuilder/template/js/mymodule.js.php
    +++ b/htdocs/modulebuilder/template/js/mymodule.js.php
    @@ -38,15 +38,15 @@ if (!defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX','1');
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/../main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/../main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/../main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/../main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     // Define js type
    diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php
    index bf56d00ede0..b2b9356217e 100644
    --- a/htdocs/modulebuilder/template/mymoduleindex.php
    +++ b/htdocs/modulebuilder/template/mymoduleindex.php
    @@ -27,16 +27,16 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
    @@ -233,6 +233,6 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read)
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/modulebuilder/template/myobject_agenda.php b/htdocs/modulebuilder/template/myobject_agenda.php
    index 3322fb527d3..9c6c9265592 100644
    --- a/htdocs/modulebuilder/template/myobject_agenda.php
    +++ b/htdocs/modulebuilder/template/myobject_agenda.php
    @@ -25,16 +25,16 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
    @@ -256,7 +256,6 @@ if ($object->id > 0)
         }
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php
    index 6c6324e6e8d..26643bd7c33 100644
    --- a/htdocs/modulebuilder/template/myobject_card.php
    +++ b/htdocs/modulebuilder/template/myobject_card.php
    @@ -45,20 +45,20 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     dol_include_once('/mymodule/class/myobject.class.php');
     dol_include_once('/mymodule/lib/mymodule_myobject.lib.php');
     
    @@ -88,19 +88,18 @@ $search_all=trim(GETPOST("search_all",'alpha'));
     $search=array();
     foreach($object->fields as $key => $val)
     {
    -    if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
    +	if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
     }
     
     if (empty($action) && empty($id) && empty($ref)) $action='view';
     
    -// Security check - Protection if external user
    -//if ($user->societe_id > 0) access_forbidden();
    -//if ($user->societe_id > 0) $socid = $user->societe_id;
    -//$result = restrictedArea($user, 'mymodule', $id);
    -
     // Load object
     include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php';  // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
     
    +// Security check - Protection if external user
    +//if ($user->societe_id > 0) access_forbidden();
    +//if ($user->societe_id > 0) $socid = $user->societe_id;
    +//$result = restrictedArea($user, 'mymodule', $object->id);
     
     
     /*
    @@ -126,6 +125,9 @@ if (empty($reshook))
     	// Actions cancel, add, update, delete or clone
     	include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
     
    +	// Actions when linking object each other
    +	include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';		// Must be include, not include_once
    +
     	// Actions when printing a doc from card
     	include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
     
    @@ -271,12 +273,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	    $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
     	}
     
    -	if (! $formconfirm) {
    -	    $parameters = array('lineid' => $lineid);
    -	    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -	    if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -	    elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    @@ -317,9 +318,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	        if (! empty($object->fk_project)) {
     	            $proj = new Project($db);
     	            $proj->fetch($object->fk_project);
    -	            $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
    -	            $morehtmlref.=$proj->ref;
    -	            $morehtmlref.='</a>';
    +	            $morehtmlref.=$proj->getNomUrl();
     	        } else {
     	            $morehtmlref.='';
     	        }
    @@ -411,7 +410,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     
     	// Select mail models is same action as presend
     	if (GETPOST('modelselected')) {
    -	    $action = 'presend';
    +		$action = 'presend';
     	}
     
     	if ($action != 'presend')
    @@ -464,7 +463,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	 */
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php
    index dfdc16d69d9..4e2b19e3afc 100644
    --- a/htdocs/modulebuilder/template/myobject_document.php
    +++ b/htdocs/modulebuilder/template/myobject_document.php
    @@ -25,16 +25,16 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    @@ -113,7 +113,7 @@ if ($object->id)
     	dol_fiche_head($head, 'document', $langs->trans("MyObject"), -1, 'myobject@mymodule');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -161,6 +161,6 @@ else
     	accessforbidden('',0,0);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php
    index 1d06e2eaac7..ece26aba6cb 100644
    --- a/htdocs/modulebuilder/template/myobject_list.php
    +++ b/htdocs/modulebuilder/template/myobject_list.php
    @@ -43,19 +43,19 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
    -require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     dol_include_once('/mymodule/class/myobject.class.php');
    @@ -336,7 +336,7 @@ $arrayofmassactions =  array(
     	//'builddoc'=>$langs->trans("PDFMerge"),
     );
     if ($user->rights->mymodule->delete) $arrayofmassactions['predelete']=$langs->trans("Delete");
    -if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
    +if (GETPOST('nomassaction','int') || in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
     $massactionbutton=$form->selectMassAction('', $arrayofmassactions);
     
     print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
    @@ -352,7 +352,7 @@ print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
     $newcardbutton='';
     //if ($user->rights->mymodule->creer)
     //{
    -	$newcardbutton='<a class="butActionNew" href="card.php?action=create"><span class="valignmiddle">'.$langs->trans('New').'</span>';
    +	$newcardbutton='<a class="butActionNew" href="card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']).'"><span class="valignmiddle">'.$langs->trans('New').'</span>';
     	$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
     	$newcardbutton.= '</a>';
     //}
    @@ -563,7 +563,7 @@ if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nb
     	$hidegeneratedfilelistifempty=1;
     	if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty=0;
     
    -	require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     	$formfile = new FormFile($db);
     
     	// Show list of available documents
    diff --git a/htdocs/modulebuilder/template/myobject_note.php b/htdocs/modulebuilder/template/myobject_note.php
    index 1a26d9abeb4..876c5e105a6 100644
    --- a/htdocs/modulebuilder/template/myobject_note.php
    +++ b/htdocs/modulebuilder/template/myobject_note.php
    @@ -25,16 +25,16 @@
     // Load Dolibarr environment
     $res=0;
     // Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    +if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
     // Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/main.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/main.inc.php";
     // Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    +if (! $res && file_exists("../main.inc.php")) $res=@include "../main.inc.php";
    +if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
    +if (! $res && file_exists("../../../main.inc.php")) $res=@include "../../../main.inc.php";
     if (! $res) die("Include of main fails");
     
     dol_include_once('/mymodule/class/myobject.class.php');
    @@ -159,6 +159,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/modulebuilder/template/scripts/myobject.php b/htdocs/modulebuilder/template/scripts/myobject.php
    index 0aad12e2e35..67bcdea1d74 100755
    --- a/htdocs/modulebuilder/template/scripts/myobject.php
    +++ b/htdocs/modulebuilder/template/scripts/myobject.php
    @@ -47,12 +47,12 @@ $res=0;
     // Try master.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
     $tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
     while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/master.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/master.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/master.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/master.inc.php");
    +if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/master.inc.php")) $res=@include substr($tmp, 0, ($i+1))."/master.inc.php";
    +if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/master.inc.php")) $res=@include dirname(substr($tmp, 0, ($i+1)))."/master.inc.php";
     // Try master.inc.php using relative path
    -if (! $res && file_exists("../master.inc.php")) $res=@include("../master.inc.php");
    -if (! $res && file_exists("../../master.inc.php")) $res=@include("../../master.inc.php");
    -if (! $res && file_exists("../../../master.inc.php")) $res=@include("../../../master.inc.php");
    +if (! $res && file_exists("../master.inc.php")) $res=@include "../master.inc.php";
    +if (! $res && file_exists("../../master.inc.php")) $res=@include "../../master.inc.php";
    +if (! $res && file_exists("../../../master.inc.php")) $res=@include "../../../master.inc.php";
     if (! $res) die("Include of master fails");
     // After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file).
     // $user is created but empty.
    diff --git a/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php b/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php
    index a70cc9bee8d..8adf184e24f 100644
    --- a/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php
    +++ b/htdocs/modulebuilder/template/test/phpunit/MyModuleFunctionalTest.php
    @@ -99,6 +99,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Global test setup
    +     * @return void
     	 */
     	public static function setUpBeforeClass()
     	{
    @@ -106,6 +107,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Unit test setup
    +     * @return void
     	 */
     	public function setUp()
     	{
    @@ -115,6 +117,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Verify pre conditions
    +     * @return void
     	 */
     	protected function assertPreConditions()
     	{
    @@ -122,6 +125,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Handle Dolibarr authentication
    +     * @return void
     	 */
     	private function authenticate()
     	{
    @@ -142,6 +146,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Test enabling developer mode
    +     * @return bool
     	 */
     	public function testEnableDeveloperMode()
     	{
    @@ -161,6 +166,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test enabling the module
     	 *
     	 * @depends testEnableDeveloperMode
    +     * @return bool
     	 */
     	public function testModuleEnabled()
     	{
    @@ -186,6 +192,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test access to the configuration page
     	 *
     	 * @depends testModuleEnabled
    +     * @return bool
     	 */
     	public function testConfigurationPage()
     	{
    @@ -198,6 +205,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test access to the about page
     	 *
     	 * @depends testConfigurationPage
    +     * @return bool
     	 */
     	public function testAboutPage()
     	{
    @@ -210,6 +218,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test about page is rendering Markdown
     	 *
     	 * @depends testAboutPage
    +     * @return bool
     	 */
     	public function testAboutPageRendersMarkdownReadme()
     	{
    @@ -226,6 +235,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test box is properly declared
     	 *
     	 * @depends testModuleEnabled
    +     * @return bool
     	 */
     	public function testBoxDeclared()
     	{
    @@ -238,6 +248,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test trigger is properly enabled
     	 *
     	 * @depends testModuleEnabled
    +     * @return bool
     	 */
     	public function testTriggerDeclared()
     	{
    @@ -254,6 +265,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     	 * Test trigger is properly declared
     	 *
     	 * @depends testTriggerDeclared
    +     * @return bool
     	 */
     	public function testTriggerEnabled()
     	{
    @@ -268,6 +280,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Verify post conditions
    +     * @return void
     	 */
     	protected function assertPostConditions()
     	{
    @@ -275,6 +288,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Unit test teardown
    +     * @return void
     	 */
     	public function tearDown()
     	{
    @@ -282,6 +296,7 @@ class MyModuleFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
     
     	/**
     	 * Global test teardown
    +     * @return void
     	 */
     	public static function tearDownAfterClass()
     	{
    diff --git a/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php b/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php
    index f2ea5b9934b..b62e2231313 100644
    --- a/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php
    +++ b/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php
    @@ -32,6 +32,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     {
     	/**
     	 * Global test setup
    +     * @return void
     	 */
     	public static function setUpBeforeClass()
     	{
    @@ -40,6 +41,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     
     	/**
     	 * Unit test setup
    +     * @return void
     	 */
     	protected function setUp()
     	{
    @@ -48,6 +50,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     
     	/**
     	 * Verify pre conditions
    +     * @return void
     	 */
     	protected function assertPreConditions()
     	{
    @@ -56,6 +59,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     
     	/**
     	 * A sample test
    +     * @return bool
     	 */
     	public function testSomething()
     	{
    @@ -66,6 +70,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     
     	/**
     	 * Verify post conditions
    +     * @return void
     	 */
     	protected function assertPostConditions()
     	{
    @@ -74,6 +79,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     
     	/**
     	 * Unit test teardown
    +     * @return void
     	 */
     	protected function tearDown()
     	{
    @@ -82,6 +88,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     
     	/**
     	 * Global test teardown
    +     * @return void
     	 */
     	public static function tearDownAfterClass()
     	{
    @@ -92,6 +99,7 @@ class MyObjectTest extends \PHPUnit_Framework_TestCase
     	 * Unsuccessful test
     	 *
     	 * @param  Exception $e    Exception
    +     * @return void
     	 * @throws Exception
     	 */
     	protected function onNotSuccessfulTest(Exception $e)
    diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php
    index 2881e23a21b..549f0fd411a 100644
    --- a/htdocs/multicurrency/class/multicurrency.class.php
    +++ b/htdocs/multicurrency/class/multicurrency.class.php
    @@ -20,15 +20,14 @@
      */
     
     /**
    - * \file    dev/skeletons/skeleton_class.class.php
    - * \ingroup mymodule othermodule1 othermodule2
    - * \brief   This file is an example for a CRUD class file (Create/Read/Update/Delete)
    - *          Put some comments here
    + * \file    htdocs/multicurrency/class/multicurrency.class.php
    + * \ingroup multicurrency
    + * \brief   This file is a CRUD class file (Create/Read/Update/Delete) for multicurrency
      */
     
     // Put here all includes required by your class file
    -require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
    -require_once DOL_DOCUMENT_ROOT ."/core/class/commonobjectline.class.php";
    +require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
    +require_once DOL_DOCUMENT_ROOT .'/core/class/commonobjectline.class.php';
     
     /**
      * Class Currency
    @@ -42,10 +41,12 @@ class MultiCurrency extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'multicurrency';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'multicurrency';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
    @@ -60,26 +61,32 @@ class MultiCurrency extends CommonObject
     	 * @var mixed Sample property 1
     	 */
     	public $id;
    +
     	/**
     	 * @var mixed Sample property 1
     	 */
     	public $code;
    +
     	/**
     	 * @var mixed Sample property 2
     	 */
     	public $name;
    +
     	/**
    -	 * @var mixed Sample property 2
    +	 * @var int Entity
     	 */
     	public $entity;
    +
     	/**
     	 * @var mixed Sample property 2
     	 */
     	public $date_create;
    +
     	/**
     	 * @var mixed Sample property 2
     	 */
     	public $fk_user;
    +
     	/**
     	 * @var mixed Sample property 2
     	 */
    @@ -93,7 +100,7 @@ class MultiCurrency extends CommonObject
     	public function __construct(DoliDB $db)
     	{
     		$this->db = &$db;
    -		
    +
     		return 1;
     	}
     
    @@ -108,21 +115,21 @@ class MultiCurrency extends CommonObject
     	public function create(User $user, $trigger = true)
     	{
     		global $conf,$langs;
    -		
    +
     		dol_syslog('Currency::create', LOG_DEBUG);
     
     		$error = 0;
    -		
    +
     		if (self::checkCodeAlreadyExists($this->code))
     		{
     			$error++;
     			$this->errors[] = $langs->trans('multicurrency_code_already_added');
     			return -1;
     		}
    -		
    +
     		if (empty($this->entity) || $this->entity <= 0) $this->entity = $conf->entity;
     		$now=date('Y-m-d H:i:s');
    -		
    +
     		// Insert request
     		$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '(';
     		$sql .= ' code,';
    @@ -152,7 +159,7 @@ class MultiCurrency extends CommonObject
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     			$this->date_create = $now;
     			$this->fk_user = $user->id;
    -			
    +
     			if ($trigger) {
     				$result=$this->call_trigger('CURRENCY_CREATE', $user);
     				if ($result < 0) $error++;
    @@ -181,7 +188,7 @@ class MultiCurrency extends CommonObject
     	public function fetch($id, $code = null)
     	{
     		dol_syslog('Currency::fetch', LOG_DEBUG);
    -		
    +
     		global $conf;
     
     		$sql = 'SELECT';
    @@ -192,7 +199,7 @@ class MultiCurrency extends CommonObject
     
     		dol_syslog(__METHOD__,LOG_DEBUG);
     		$resql = $this->db->query($sql);
    -		
    +
     		if ($resql) {
     			$numrows = $this->db->num_rows($resql);
     			if ($numrows) {
    @@ -204,7 +211,7 @@ class MultiCurrency extends CommonObject
     				$this->entity = $obj->entity;
     				$this->date_create = $obj->date_create;
     				$this->fk_user = $obj->fk_user;
    -				
    +
     				$this->fetchAllCurrencyRate();
     				$this->getRate();
     			}
    @@ -234,7 +241,7 @@ class MultiCurrency extends CommonObject
     		$sql.= ' FROM ' . MAIN_DB_PREFIX . $this->table_element_line. ' as cr';
     		$sql.= ' WHERE cr.fk_multicurrency = '.$this->id;
     		$sql.= ' ORDER BY cr.date_sync DESC';
    -		
    +
     		$this->rates = array();
     
     		dol_syslog(__METHOD__,LOG_DEBUG);
    @@ -245,7 +252,7 @@ class MultiCurrency extends CommonObject
     			while ($obj = $this->db->fetch_object($resql)) {
     				$rate = new CurrencyRate($this->db);
     				$rate->fetch($obj->rowid);
    -				
    +
     				$this->rates[] = $rate;
     			}
     			$this->db->free($resql);
    @@ -272,19 +279,19 @@ class MultiCurrency extends CommonObject
     		$error = 0;
     
     		dol_syslog('Currency::update', LOG_DEBUG);
    -		
    +
     		// Clean parameters
     		$this->name = trim($this->name);
     		$this->code = trim($this->code);
    -		
    +
     		// Check parameters
     		if (empty($this->code)) {
     			$error++;
     			dol_syslog('Currency::update $this->code can not be empty', LOG_ERR);
    -			
    +
     			return -1;
     		}
    -		
    +
     		// Update request
     		$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET';
     		$sql .= ' name=\''.$this->db->escape($this->name).'\'';
    @@ -328,7 +335,7 @@ class MultiCurrency extends CommonObject
     	public function delete($trigger = true)
     	{
     		global $user;
    -		
    +
     		dol_syslog('Currency::delete', LOG_DEBUG);
     
     		$error = 0;
    @@ -347,7 +354,7 @@ class MultiCurrency extends CommonObject
     				$this->errors[] = 'Error ' . $this->db->lasterror();
     				dol_syslog('Currency::delete  ' . join(',', $this->errors), LOG_ERR);
     			}
    -			
    +
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
     			$sql .= ' WHERE rowid=' . $this->id;
     
    @@ -371,7 +378,7 @@ class MultiCurrency extends CommonObject
     			return 1;
     		}
     	}
    -	
    +
     	/**
     	 * Delete rates in database
     	 *
    @@ -386,137 +393,136 @@ class MultiCurrency extends CommonObject
     				return false;
     			}
     		}
    -		
    +
     		return true;
     	}
    -	
    +
     	/**
    -	 * Delete rate in database 
    -	 * 
    +	 * Delete rate in database
    +	 *
     	 * @param double	$rate	rate value
    -	 * 
    +	 *
     	 * @return int -1 if KO, 1 if OK
     	 */
    -	 public function addRate($rate)
    -	 {
    +	public function addRate($rate)
    +	{
     	 	$currencyRate = new CurrencyRate($this->db);
     		$currencyRate->rate = $rate;
    -		
    -		if ($currencyRate->create($this->id) > 0) 
    +
    +		if ($currencyRate->create($this->id) > 0)
     		{
     			$this->rate = $currencyRate;
     			return 1;
     		}
    -		else 
    +		else
     		{
     			$this->rate = null;
     			return -1;
     		}
     	 }
    -	 
    -	 /**
    -	  * Try get label of code in llx_currency then add rate
    -	  * 
    -	  * @param	string	$code	currency code
    -	  * @param	double	$rate	new rate
    -	  * 
    -	  * @return int -1 if KO, 1 if OK, 2 if label found and OK
    -	  */
    +
    +	/**
    +	 * Try get label of code in llx_currency then add rate.
    +	 *
    +	 * @param	string	$code	currency code
    +	 * @param	double	$rate	new rate
    +	 *
    +	 * @return int -1 if KO, 1 if OK, 2 if label found and OK
    +	 */
     	function addRateFromDolibarr($code, $rate)
     	{
     	 	global $db, $user;
    -		
    +
     		$currency = new MultiCurrency($db);
     		$currency->code = $code;
     		$currency->name = $code;
    -		
    +
     	 	$sql = 'SELECT label FROM '.MAIN_DB_PREFIX.'c_currencies WHERE code_iso = \''.$db->escape($code).'\'';
    -	 	
    +
     	 	dol_syslog(__METHOD__,LOG_DEBUG);
     		$resql = $db->query($sql);
     		if ($resql && ($line = $db->fetch_object($resql)))
     		{
     			$currency->name = $line->label;
     		}
    -		
    +
     		if ($currency->create($user) > 0)
     		{
     			$currency->addRate($rate);
    -			
    +
     			if (!empty($line)) return 2;
     			else return 1;
     		}
    -		
    -		return -1;	
    +
    +		return -1;
     	}
    -	 
    +
     	 /**
     	 * Add new entry into llx_multicurrency_rate to historise
    -	 * 
    +	 *
     	 * @param double	$rate	rate value
    -	  * 
    +	  *
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	 public function updateRate($rate)
    -	 {
    +	public function updateRate($rate)
    +	{
     	 	return $this->addRate($rate);
     	 }
    -	
    +
     	/**
    -	 * Fetch CurrencyRate object in $this->rate 
    -	 * 
    +	 * Fetch CurrencyRate object in $this->rate
    +	 *
     	 * @return int <0 if KO, 0 if not found, >0 if OK
     	 */
    -	 public function getRate()
    -	 {
    +	public function getRate()
    +	{
     	 	$sql = 'SELECT cr.rowid';
     		$sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as cr';
     		$sql.= ' WHERE cr.fk_multicurrency = '.$this->id;
     		$sql.= ' AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM '.MAIN_DB_PREFIX.$this->table_element_line.' AS cr2 WHERE cr2.fk_multicurrency = '.$this->id.')';
    -		
    +
     		dol_syslog(__METHOD__,LOG_DEBUG);
     		$resql = $this->db->query($sql);
     		if ($resql && ($obj = $this->db->fetch_object($resql))) {
     			$this->rate = new CurrencyRate($this->db);
     			return $this->rate->fetch($obj->rowid);
     		}
    -		
     	 }
    -	 
    +
     	 /**
    -	 * Get id of currency from code 
    +	 * Get id of currency from code
     	 *
     	 * @param DoliDB	$db		object db
     	 * @param string	$code	code value search
    -	 * 
    +	 *
     	 * @return 0 if not found, >0 if OK
     	 */
    -	 public static function getIdFromCode(&$db, $code)
    -	 {
    +	public static function getIdFromCode(&$db, $code)
    +	{
     	 	global $conf;
    -		
    +
     	 	$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'multicurrency WHERE code = \''.$db->escape($code).'\' AND entity = '.$conf->entity;
    -	 	
    +
     	 	dol_syslog(__METHOD__,LOG_DEBUG);
     		$resql = $db->query($sql);
     		if ($resql && $obj = $db->fetch_object($resql)) return $obj->rowid;
     		else return 0;
     	 }
    -	 
    +
     	 /**
    -	 * Get id and rate of currency from code 
    -	 * 
    +	 * Get id and rate of currency from code
    +	 *
     	 * @param DoliDB	$db		object db
     	 * @param string	$code	code value search
     	 * @param date		$date_document	date from document (propal, order, invoice, ...)
    -	 * 
    +	 *
     	 * @return 	array	[0] => id currency
     	 *					[1] => rate
     	 */
    -	 public static function getIdAndTxFromCode(&$db, $code, $date_document='')
    -	 {
    +	public static function getIdAndTxFromCode(&$db, $code, $date_document='')
    +	{
     		global $conf;
    -		
    +
     	 	$sql1 = 'SELECT m.rowid, mc.rate FROM '.MAIN_DB_PREFIX.'multicurrency m';
     		$sql1.= ' LEFT JOIN '.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)';
     		$sql1.= ' WHERE m.code = \''.$db->escape($code).'\'';
    @@ -524,10 +530,10 @@ class MultiCurrency extends CommonObject
     		$sql2= '';
     		if (!empty($conf->global->MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE) && !empty($date_document)) $sql2.= ' AND DATE_FORMAT(mc.date_sync, "%Y-%m-%d") = "'.date('Y-m-d', $date_document).'"';
     		$sql3.= ' ORDER BY mc.date_sync DESC LIMIT 1';
    -		
    +
     		dol_syslog(__METHOD__,LOG_DEBUG);
     		$resql = $db->query($sql1.$sql2.$sql3);
    -		
    +
     		if ($resql && $obj = $db->fetch_object($resql)) return array($obj->rowid, $obj->rate);
     		else
     		{
    @@ -536,67 +542,67 @@ class MultiCurrency extends CommonObject
     				$resql = $db->query($sql1.$sql3);
     				if ($resql && $obj = $db->fetch_object($resql)) return array($obj->rowid, $obj->rate);
     			}
    -			
    +
     			return array(0, 1);
     		}
    -	 }  
    -	 
    +	 }
    +
     	 /**
     	  * Get the conversion of amount with invoice rate
    -	  * 
    +	  *
     	  * @param	int		$fk_facture		id of facture
     	  * @param	double	$amount			amount to convert
     	  * @param	string	$way			dolibarr mean the amount is in dolibarr currency
     	  * @param	string	$table			facture or facture_fourn
    -	  * 
     	  * @return	double					amount converted
     	  */
     	  public static function getAmountConversionFromInvoiceRate($fk_facture, $amount, $way='dolibarr', $table='facture')
     	  {
     		 global $db;
    -		 
    +
     		 $multicurrency_tx = self::getInvoiceRate($fk_facture, $table);
    -		 
    -		 if ($multicurrency_tx) 
    +
    +		 if ($multicurrency_tx)
     		 {
     		 	if ($way == 'dolibarr') return $amount * $multicurrency_tx;
     			else return $amount / $multicurrency_tx;
     		 }
     		 else return $amount;
     	  }
    -	  
    -	  /**
    -	   *  Get current invoite rate
    -	   * 
    -	   *  @param	int 	$fk_facture 	id of facture
    -	   *  @param 	string 	$table 			facture or facture_fourn
    -	   */
    -	   public static function getInvoiceRate($fk_facture, $table='facture')
    -	   {
    -		 global $db;
    -		 
    -		 $sql = 'SELECT multicurrency_tx FROM '.MAIN_DB_PREFIX.$table.' WHERE rowid = '.$fk_facture;
    -		 
    -		 dol_syslog(__METHOD__,LOG_DEBUG);
    -		 $resql = $db->query($sql);
    -		 if ($resql && ($line = $db->fetch_object($resql)))
    -		 {
    -		 	return $line->multicurrency_tx;
    -		 }
    -		 
    -		 return false;
    -	   }
    +
    +	/**
    +	 *  Get current invoite rate
    +	 *
    +	 *  @param	int 	$fk_facture 	id of facture
    +	 *  @param 	string 	$table 			facture or facture_fourn
    +     *  @return bool
    +	 */
    +	public static function getInvoiceRate($fk_facture, $table='facture')
    +	{
    +		global $db;
    +
    +		$sql = 'SELECT multicurrency_tx FROM '.MAIN_DB_PREFIX.$table.' WHERE rowid = '.$fk_facture;
    +
    +		dol_syslog(__METHOD__,LOG_DEBUG);
    +		$resql = $db->query($sql);
    +		if ($resql && ($line = $db->fetch_object($resql)))
    +		{
    +			return $line->multicurrency_tx;
    +		}
    +
    +		return false;
    +	}
     
     	/**
     	 * With free account we can't set source then recalcul all rates to force another source
    -	 * 
    -	 * @param	stdClass	$TRate	Object containing all currencies rates	
    +	 *
    +	 * @param   stdClass	$TRate	Object containing all currencies rates
     	 * @return	-1 if KO, 0 if nothing, 1 if OK
     	 */
    -	public static function  recalculRates(&$TRate)
    +	public static function recalculRates(&$TRate)
     	{
     		global $conf;
    -		
    +
     		if (!empty($conf->global->MULTICURRENCY_ALTERNATE_SOURCE))
     		{
     			$alternate_source = 'USD'.$conf->global->MULTICURRENCY_ALTERNATE_SOURCE;
    @@ -607,25 +613,26 @@ class MultiCurrency extends CommonObject
     				{
     					$rate *= $coef;
     				}
    -				
    +
     				return 1;
     			}
    -			
    +
     			return -1; // Alternate souce not found
     		}
    -		
    +
     		return 0; // Nothing to do
     	}
    -	
    +
     	/**
     	 *  Sync rates from api
    -	 * 
    +	 *
     	 *  @param 	array 	$response 	array of reponse from api to sync dolibarr rates
    +     * @return void
     	 */
     	public static function syncRates($response)
     	{
     		global $db,$conf;
    -		
    +
     		$ch = curl_init('http://apilayer.net/api/live?access_key='.$key.'');
                     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                     $response = curl_exec($ch);
    @@ -634,11 +641,11 @@ class MultiCurrency extends CommonObject
     
                     if ($response->success)
                     {
    -		
    +
     			$TRate = $response->quotes;
     			$timestamp = $response->timestamp;
     
    -			if (self::recalculRates($TRate) >= 0) 
    +			if (self::recalculRates($TRate) >= 0)
     			{
     				foreach ($TRate as $currency_code => $rate)
     				{
    @@ -648,11 +655,11 @@ class MultiCurrency extends CommonObject
     					{
     						$obj->updateRate($rate);
     					}
    -					else 
    +					else
     					{
     						self::addRateFromDolibarr($code, $rate);
     					}
    -				}	
    +				}
     			}
     		}
     		else
    @@ -660,21 +667,21 @@ class MultiCurrency extends CommonObject
     			setEventMessages($langs->trans('multicurrency_syncronize_error', $response->error->info), null, 'errors');
     		}
     	}
    -	
    +
     	/**
     	 * Check in database if the current code already exists
    -	 * 
    +	 *
     	 * @param	string	$code 	current code to search
     	 * @return	boolean         True if exists, false if not exists
     	 */
    -	 public static function checkCodeAlreadyExists($code)
    -	 {
    +	public static function checkCodeAlreadyExists($code)
    +	{
     	 	global $db;
    -		
    +
     	 	$currency = new MultiCurrency($db);
     		if ($currency->fetch('', $code) > 0) return true;
     		else return false;
    -	 }
    +	}
     }
     
     /**
    @@ -686,31 +693,37 @@ class CurrencyRate extends CommonObjectLine
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'multicurrency_rate';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'multicurrency_rate';
    +
     	/**
     	 * @var int ID
     	 */
     	public $id;
    +
     	/**
     	 * @var double Rate
     	 */
     	public $rate;
    +
     	/**
     	 * @var date Date synchronisation
     	 */
     	public $date_sync;
    +
     	/**
     	 * @var int Id of currency
     	 */
     	public $fk_multicurrency;
    +
     	/**
     	 * @var int Id of entity
     	 */
     	public $entity;
    -	
    +
     	/**
     	 * Constructor
     	 *
    @@ -719,10 +732,10 @@ class CurrencyRate extends CommonObjectLine
     	public function __construct(DoliDB $db)
     	{
     		$this->db = &$db;
    -		
    +
     		return 1;
     	}
    -	
    +
     	/**
     	 * Create object into database
     	 *
    @@ -734,14 +747,14 @@ class CurrencyRate extends CommonObjectLine
     	public function create($fk_multicurrency, $trigger = true)
     	{
     		global $conf, $user;
    -		
    +
     		dol_syslog('CurrencyRate::create', LOG_DEBUG);
     
     		$error = 0;
     		$this->rate = price2num($this->rate);
     		if (empty($this->entity) || $this->entity <= 0) $this->entity = $conf->entity;
     		$now=date('Y-m-d H:i:s');
    -		
    +
     		// Insert request
     		$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '(';
     		$sql .= ' rate,';
    @@ -769,7 +782,7 @@ class CurrencyRate extends CommonObjectLine
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     			$this->fk_multicurrency = $fk_multicurrency;
     			$this->date_sync = $now;
    -			
    +
     			if ($trigger) {
     				$result=$this->call_trigger('CURRENCYRATE_CREATE', $user);
     				if ($result < 0) $error++;
    @@ -829,7 +842,7 @@ class CurrencyRate extends CommonObjectLine
     			return - 1;
     		}
     	}
    -	
    +
     	/**
     	 * Update object into database
     	 *
    @@ -840,13 +853,13 @@ class CurrencyRate extends CommonObjectLine
     	public function update($trigger = true)
     	{
     		global $user;
    -		
    +
     		$error = 0;
     
     		dol_syslog('CurrencyRate::update', LOG_DEBUG);
    -		
    +
     		$this->rate = price2num($this->rate);
    -		
    +
     		// Update request
     		$sql = 'UPDATE ' . MAIN_DB_PREFIX . $this->table_element . ' SET';
     		$sql .= ' rate='.$this->rate;
    @@ -878,7 +891,7 @@ class CurrencyRate extends CommonObjectLine
     			return 1;
     		}
     	}
    -	
    +
     	/**
     	 * Delete object in database
     	 *
    @@ -889,7 +902,7 @@ class CurrencyRate extends CommonObjectLine
     	public function delete($trigger = true)
     	{
     		global $user;
    -		
    +
     		dol_syslog('CurrencyRate::delete', LOG_DEBUG);
     
     		$error = 0;
    @@ -925,5 +938,4 @@ class CurrencyRate extends CommonObjectLine
     			return 1;
     		}
     	}
    -	
     }
    diff --git a/htdocs/opensurvey/card.php b/htdocs/opensurvey/card.php
    index fda06d67012..2a2b3f85ae4 100644
    --- a/htdocs/opensurvey/card.php
    +++ b/htdocs/opensurvey/card.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2013-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2014      Marcos García		<marcosgdf@gmail.com>
    +/* Copyright (C) 2013-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2014       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -22,12 +23,12 @@
      *	\brief      Page to edit survey
      */
     
    -require_once('../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php");
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php";
     
     
     // Security check
    @@ -306,7 +307,7 @@ print '</td></tr>';
     
     // Expire date
     print '<tr><td>'.$langs->trans('ExpireDate').'</td><td colspan="2">';
    -if ($action == 'edit') print $form->select_date($expiredate?$expiredate:$object->date_fin,'expire',0,0,0,'',1,0,1);
    +if ($action == 'edit') print $form->selectDate($expiredate?$expiredate:$object->date_fin, 'expire', 0, 0, 0, '', 1, 0);
     else
     {
         print dol_print_date($object->date_fin,'day');
    @@ -430,6 +431,6 @@ if ($object->allow_comments) {
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php
    index a2b6096d77c..2e6789b3f89 100644
    --- a/htdocs/opensurvey/class/opensurveysondage.class.php
    +++ b/htdocs/opensurvey/class/opensurveysondage.class.php
    @@ -24,9 +24,9 @@
      */
     
     // Put here all includes required by your class file
    -require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
    -//require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    -//require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    +require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
    +//require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
    +//require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
     
     
     /**
    @@ -34,8 +34,16 @@ require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
      */
     class Opensurveysondage extends CommonObject
     {
    -	public $element='opensurvey_sondage';			//!< Id that identify managed objects
    -	public $table_element='opensurvey_sondage';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='opensurvey_sondage';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='opensurvey_sondage';
    +
         public $picto = 'opensurvey';
     
     	public $id_sondage;
    @@ -44,6 +52,10 @@ class Opensurveysondage extends CommonObject
     	 * @see description
     	 */
     	public $commentaires;
    +
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
     
     	public $mail_admin;
    @@ -99,7 +111,6 @@ class Opensurveysondage extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -459,6 +470,7 @@ class Opensurveysondage extends CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return array of lines
     	 *
    @@ -466,6 +478,7 @@ class Opensurveysondage extends CommonObject
     	 */
     	function fetch_lines()
     	{
    +        // phpcs:enable
     		$ret=array();
     
     		$sql = "SELECT id_users, nom as name, reponses FROM ".MAIN_DB_PREFIX."opensurvey_user_studs";
    @@ -614,6 +627,7 @@ class Opensurveysondage extends CommonObject
     	    return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return label of status
     	 *
    @@ -623,6 +637,7 @@ class Opensurveysondage extends CommonObject
     	 */
     	function LibStatut($status,$mode)
     	{
    +        // phpcs:enable
     	    global $langs, $conf;
     
     	    //print 'x'.$status.'-'.$billed;
    @@ -663,5 +678,4 @@ class Opensurveysondage extends CommonObject
     	        if ($status==self::STATUS_CLOSED) return '<span class="hideonsmartphone">'.$langs->trans('Closed').' </span>'.img_picto($langs->trans('Closed'),'statut6');
     	    }
     	}
    -
     }
    diff --git a/htdocs/opensurvey/css/style.css b/htdocs/opensurvey/css/style.css
    index 7e359bd134e..e790d2d59f8 100644
    --- a/htdocs/opensurvey/css/style.css
    +++ b/htdocs/opensurvey/css/style.css
    @@ -104,10 +104,10 @@ borghesi@unistra.fr
     Ce logiciel est régi par la licence CeCILL-B soumise au droit français et
     respectant les principes de diffusion des logiciels libres. Vous pouvez
     utiliser, modifier et/ou redistribuer ce programme sous les conditions
    -de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA 
    +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA
     sur le site "http://www.cecill.info".
     
    -Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 
    +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
     pris connaissance de la licence CeCILL-B, et que vous en avez accepté les
     termes. Vous pouvez trouver une copie de la licence dans le fichier LICENCE.
     
    @@ -120,10 +120,10 @@ Creation : Feb 2008
     borghesi@unistra.fr
     
     This software is governed by the CeCILL-B license under French law and
    -abiding by the rules of distribution of free software. You can  use, 
    +abiding by the rules of distribution of free software. You can  use,
     modify and/ or redistribute the software under the terms of the CeCILL-B
     license as circulated by CEA, CNRS and INRIA at the following URL
    -"http://www.cecill.info". 
    +"http://www.cecill.info".
     
     The fact that you are presently reading this means that you have had
     knowledge of the CeCILL-B license and that you accept its terms. You can
    @@ -133,12 +133,12 @@ find a copy of this license in the file LICENSE.
     */
     
     /*
    -Le fichier style.css est le fichier de style de studs. Il se trouve à la racine 
    +Le fichier style.css est le fichier de style de studs. Il se trouve à la racine
     du répertoire studs. Il contient toutes les mises en forme des fichiers PHP
     de Studs.
     */
     /*bandeau de titre*/
    -div.bandeau{ 
    +div.bandeau{
     	line-height:35px;
     	text-align:center;
     	background-color: #0b419b;
    @@ -146,7 +146,7 @@ div.bandeau{
     	vertical-align:middle;
     	font-size:35px;
     	font-family:arial, sans-serif;
    -	padding:8px; 
    +	padding:8px;
     	height:35px;
     	position:static;
     	top:6px;
    @@ -154,30 +154,30 @@ div.bandeau{
     	right:6px;
     
     }
    -div.logo{ 
    +div.logo{
     	height:64px;
     	float:right;
     	top:8px;
     	right:8px;
     	margin-left: 0;
    -	margin-right:0; 
    +	margin-right:0;
     	margin-bottom:auto;
     }
     /*Sous bandeau avec bouton de navigation*/
    -div.bandeautitre{ 
    +div.bandeautitre{
     	height:17px;
     	font-size:14px;
     	font-weight:bold;
     	text-align:center;
     	vertical-align:middle;
     	font-family:arial, sans-serif;
    - 	padding:3px; 
    + 	padding:3px;
     	position:static;
     	top:57px;
     	left:6px;
     	right:6px;
    -} 
    -div.sousbandeau{ 
    +}
    +div.sousbandeau{
     	height:17px;
     	background-color: #DDDDDD;
     	font-size:11px;
    @@ -191,15 +191,15 @@ div.sousbandeau{
     	right:6px;
     }
     /*bandeau de pied*/
    -div.surbandeaupied{ 
    +div.surbandeaupied{
     	background-color: #0077DD;
     	position:absolute;
     	bottom:30px;
     	left:6px;
    -	right:6px; 
    +	right:6px;
     	height:6px;
     }
    -div.bandeaupied{ 
    +div.bandeaupied{
     	text-align:center;
     	background-color: #0b419b;
     	color:white;
    @@ -209,29 +209,29 @@ div.bandeaupied{
     	position:fixed;
     	bottom:6px;
     	left:6px;
    -	right:6px; 
    +	right:6px;
     	margin:2px;
     }
    -div.surbandeaupiedmobile{ 
    +div.surbandeaupiedmobile{
     	background-color: #0077DD;
    -	position:static; 
    +	position:static;
     	bottom:32px;
     	left:6px;
    -	right:6px; 
    +	right:6px;
     	height:6px;
     }
    -div.bandeaupiedmobile{ 
    +div.bandeaupiedmobile{
     	text-align:center;
     	background-color: #0b419b;
     	color:white;
     	font-size:11px;
     	font-family:arial, sans-serif;
    -	padding:6px; 
    -	position:static; 
    +	padding:6px;
    +	position:static;
     }
     /*les boutons se trouvant dans le sousbandeau*/
     div.sousbandeau a, div.sousbandeau span.sousbandeaulangue a {
    - 	background-color: #0b419b; 
    + 	background-color: #0b419b;
     	height:16px;
     	padding: 2px 6px 2px 6px;
     	vertical-align:middle;
    @@ -249,7 +249,7 @@ span.sousbandeaulangue {
     	float:right;
     }
     /*corps de la page index.php*/
    -div.corps{ 
    +div.corps{
     	font-size:12px;
     	font-family:arial, sans-serif;
     	position:static;
    @@ -257,10 +257,10 @@ div.corps{
     }
     div.corps  table{
     	font-family:arial, sans-serif;
    -	font-size:12px;	
    +	font-size:12px;
     	font-weight:bold;
     }
    -div.corpscentre{ 
    +div.corpscentre{
     	font-size:12px;
     	font-family:arial, sans-serif;
     	text-align:center;
    @@ -285,7 +285,7 @@ div.jourschoisis {
     div.bodydate {
     	padding:10px;
     	font-family:arial, sans-serif;
    -	font-size:12px;	
    +	font-size:12px;
     	text-align:center;
     	position:static;
     	top:330px;
    @@ -294,7 +294,7 @@ div.bodydate {
     }
     div.bodydate table{
     	font-family:arial, sans-serif;
    -	font-size:12px;	
    +	font-size:12px;
     	font-weight:bold;
     }
     /*cadre de commentaires*/
    @@ -302,7 +302,7 @@ div.presentationdate {
     	width:100%;
     	font-family:arial, sans-serif;
     	text-align:center;
    -	font-size:12px;	
    +	font-size:12px;
     	border-top:1px solid;
     	border-bottom:1px solid;
     	border-left: none;
    @@ -321,14 +321,14 @@ div.presentationdatefin {
         border: 1px solid;
         margin-top: 10px;
     	margin-left: 30%;
    -    margin-right: 30%; 
    +    margin-right: 30%;
     	position:static;
     }
     /*cadre principal de studs.php*/
     div.cadre {
    -	padding:10px; 
    +	padding:10px;
     	font-family:arial, sans-serif;
    -	font-size:12px;	
    +	font-size:12px;
     	position:static;
     	top:235px;
     	text-align:center;
    @@ -350,54 +350,54 @@ div.cadre td {
     }
     /*case de tableau OK dans affichage de sondage*/
     div.cadre td.ok {
    -	background-color: #66FF99; 
    -	font-size:12px;	
    +	background-color: #66FF99;
    +	font-size:12px;
     	text-align:center;
     }
     /*Case de tableau NON dans affichage de sondage*/
     div.cadre td.non {
    -	background-color: #FF7777; 
    +	background-color: #FF7777;
     	min-width: 60px;
     }
     /*Case de tableau VIDE dans affichage de sondage*/
     div.cadre td.vide {
    -	background-color: #DDDDDD; 
    +	background-color: #DDDDDD;
     	text-align:center;
     }
     /*Case de tableau contenant les noms dans affichage de sondage*/
     div.cadre td.nom {
    -	background-color: #DDDDDD; 
    -	font-size:12px;	 
    +	background-color: #DDDDDD;
    +	font-size:12px;
     	text-align:center;
     }
     div.cadre td.casevide {
    -	background-color: white; 
    +	background-color: white;
     	text-align:center;
     }
     /*les cases contenant les sommes de chaque colonne dans l'affichage de calendrier*/
     div.cadre td.somme {
     	font-weight:  bold;
    -	font-size:14px; 
    +	font-size:14px;
     }
     
     /*Case de tableau SUJET dans affichage de sondage*/
     div.cadre td.sujet, div.cadre td.jour, div.cadre td.heure {
     	border: 2px;
    -	background-color: #DDDDDD; 
    +	background-color: #DDDDDD;
     	font-size:14px;
     	padding:1px 5px;
     }
     
     div.cadre td.annee {
     	border: 2px;
    -	background-color: #969696; 
    +	background-color: #969696;
     	font-weight: bold;
     	font-size:14px;
     	padding:1px 5px;
     }
     div.cadre td.mois {
     	border: 2px;
    -	background-color: #C0C0C0; 
    +	background-color: #C0C0C0;
     	font-weight: bold;
     	font-size:14px;
     	padding:1px 5px;
    @@ -421,7 +421,7 @@ div.calendrier td.joursemaine {
     	font-family:arial, sans-serif;
     	font-size:14px;
     	border: 2px;
    -	background-color: white; 
    +	background-color: white;
     }
     div.calendrier td.jourwe {
     	width:65px;
    @@ -429,7 +429,7 @@ div.calendrier td.jourwe {
     	font-family:arial, sans-serif;
     	font-size:14px;
     	border: 2px;
    -	background-color: #C0C0C0; 
    +	background-color: #C0C0C0;
     }
     /*jour avant le premier jour du mois dans calendrier*/
     div.calendrier td.avant {
    @@ -438,21 +438,21 @@ div.calendrier td.avant {
     	border: 2px;
     	font-family:arial, sans-serif;
     	font-size:13px;
    -	background-color: #DDDDDD; 
    +	background-color: #DDDDDD;
     }
     /*jour libre dans calendrier*/
     div.calendrier td.libre {
     	width:65px;
     	text-align: center;
     	border: 2px;
    -	background-color: #66FF99; 
    +	background-color: #66FF99;
     }
     /*jour deja selectionné dans calendrier*/
     div.calendrier td.choisi {
     	width:65px;
     	text-align: center;
     	border: 2px;
    -	background-color: #0077DD; 
    +	background-color: #0077DD;
     }
     /* Le paragraphe de fin */
     p.affichageresultats{
    diff --git a/htdocs/opensurvey/exportcsv.php b/htdocs/opensurvey/exportcsv.php
    index 90fd56cd4d1..b36a5256059 100644
    --- a/htdocs/opensurvey/exportcsv.php
    +++ b/htdocs/opensurvey/exportcsv.php
    @@ -23,10 +23,10 @@
      */
     
     
    -require_once('../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php");
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
     
     $action=GETPOST('action','aZ09');
     $numsondage = '';
    diff --git a/htdocs/opensurvey/fonctions.php b/htdocs/opensurvey/fonctions.php
    index 84b33297fbb..3df5b37c88f 100644
    --- a/htdocs/opensurvey/fonctions.php
    +++ b/htdocs/opensurvey/fonctions.php
    @@ -29,7 +29,8 @@
      * @param Opensurveysondage $object Current viewing poll
      * @return array Tabs for the opensurvey section
      */
    -function opensurvey_prepare_head(Opensurveysondage $object) {
    +function opensurvey_prepare_head(Opensurveysondage $object)
    +{
     
     	global $langs, $conf;
     
    @@ -78,7 +79,7 @@ function llxHeaderSurvey($title, $head="", $disablejs=0, $disablehead=0, $arrayo
     	// Print logo
     	if ($mysoc->logo) {
     		if (file_exists($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) {
    -			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file=thumbs/'.urlencode($mysoc->logo_small);
    +			$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
     		}
     	}
     
    diff --git a/htdocs/opensurvey/index.php b/htdocs/opensurvey/index.php
    index 663d4ad704a..4c60a807445 100644
    --- a/htdocs/opensurvey/index.php
    +++ b/htdocs/opensurvey/index.php
    @@ -21,9 +21,9 @@
      *	\brief      Home page of opensurvey area
      */
     
    -require_once('../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
     
     // Security check
     if (!$user->rights->opensurvey->read) accessforbidden();
    @@ -78,8 +78,6 @@ print '</table>';
     
     print '</div></div></div>';
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php
    index 0471abcddb9..ecb26047e52 100644
    --- a/htdocs/opensurvey/list.php
    +++ b/htdocs/opensurvey/list.php
    @@ -22,10 +22,10 @@
      *	\brief      Page to list surveys
      */
     
    -require_once('../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php");
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
     
     // Security check
     if (!$user->rights->opensurvey->read) accessforbidden();
    @@ -296,6 +296,6 @@ print '</table>'."\n";
     print '</div>';
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/opensurvey/results.php b/htdocs/opensurvey/results.php
    index cd6e6ed3225..f3fd135f16d 100644
    --- a/htdocs/opensurvey/results.php
    +++ b/htdocs/opensurvey/results.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2013-2015 Laurent Destailleur <eldy@users.sourceforge.net>
    - * Copyright (C) 2014      Marcos García       <marcosgdf@gmail.com>
    +/* Copyright (C) 2013-2015  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2014       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -22,12 +23,11 @@
      *	\brief      Page to preview votes of a survey
      */
     
    -$res=0;
    -require_once('../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php");
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php";
     
     
     // Security check
    @@ -459,7 +459,7 @@ print '</td></tr>';
     
     // Expire date
     print '<tr><td>'.$langs->trans('ExpireDate').'</td><td colspan="2">';
    -if ($action == 'edit') print $form->select_date($expiredate?$expiredate:$object->date_fin,'expire',0,0,0,'',1,0,1);
    +if ($action == 'edit') print $form->selectDate($expiredate?$expiredate:$object->date_fin, 'expire', 0, 0, 0, '', 1, 0);
     else print dol_print_date($object->date_fin,'day');
     print '</td></tr>';
     
    @@ -492,7 +492,6 @@ if ($action != 'edit')
     				});
     		    </script>';
     	print ' <a href="'.$url.'" target="_blank">'.$langs->trans("Link").'</a>';
    -
     }
     
     print '</td></tr>';
    diff --git a/htdocs/opensurvey/wizard/choix_autre.php b/htdocs/opensurvey/wizard/choix_autre.php
    index a415d6b4987..366842513c8 100644
    --- a/htdocs/opensurvey/wizard/choix_autre.php
    +++ b/htdocs/opensurvey/wizard/choix_autre.php
    @@ -22,10 +22,10 @@
      *	\brief      Page to create a new survey (choice selection)
      */
     
    -require_once('../../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php");
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php";
     
     // Security check
     if (!$user->rights->opensurvey->write) accessforbidden();
    @@ -161,6 +161,6 @@ print '<a name=bas></a>'."\n";
     print '<br><br><br>'."\n";
     print '</div>'."\n";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/opensurvey/wizard/choix_date.php b/htdocs/opensurvey/wizard/choix_date.php
    index 7dd0168c77a..5aa478d9450 100644
    --- a/htdocs/opensurvey/wizard/choix_date.php
    +++ b/htdocs/opensurvey/wizard/choix_date.php
    @@ -22,10 +22,10 @@
      *	\brief      Page to create a new survey (date selection)
      */
     
    -require_once('../../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php");
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php";
     
     // Security check
     if (!$user->rights->opensurvey->write) accessforbidden();
    @@ -564,6 +564,6 @@ print '</form>'."\n";
     print '<br><br><br><br>'."\n";
     print '</div></div>'."\n";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/opensurvey/wizard/create_survey.php b/htdocs/opensurvey/wizard/create_survey.php
    index 0dfc2505ce3..8664e616c55 100644
    --- a/htdocs/opensurvey/wizard/create_survey.php
    +++ b/htdocs/opensurvey/wizard/create_survey.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2013-2014 Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2014      Marcos García       <marcosgdf@gmail.com>
      * Copyright (C) 2015-2016 Alexandre Spangaro  <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -23,11 +24,11 @@
      *	\brief      Page to create a new survey
      */
     
    -require_once('../../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php");
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/doleditor.class.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php";
     
     // Security check
     if (!$user->rights->opensurvey->write) accessforbidden();
    @@ -156,7 +157,7 @@ print '</tr>'."\n";
     
     print '<tr><td class="fieldrequired">'.  $langs->trans("ExpireDate")  .'</td><td>';
     
    -print $form->select_date($champdatefin?$champdatefin:-1,'champdatefin','','','',"add",1,0,1);
    +print $form->selectDate($champdatefin?$champdatefin:-1, 'champdatefin', '', '', '', "add", 1, 0);
     
     print '</tr>'."\n";
     print '</table>'."\n";
    @@ -204,6 +205,6 @@ else
     print '<br><br><br>'."\n";
     print '</form>'."\n";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/opensurvey/wizard/index.php b/htdocs/opensurvey/wizard/index.php
    index 4d03b7d2d8f..f15284e2e83 100644
    --- a/htdocs/opensurvey/wizard/index.php
    +++ b/htdocs/opensurvey/wizard/index.php
    @@ -57,6 +57,6 @@ print '<div style="clear:both;"></div>';
     print '</div>';
     print '</div></form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/paybox/admin/paybox.php b/htdocs/paybox/admin/paybox.php
    index bee538bf9d5..11329042da4 100644
    --- a/htdocs/paybox/admin/paybox.php
    +++ b/htdocs/paybox/admin/paybox.php
    @@ -71,6 +71,9 @@ if ($action == 'setvalue' && $user->admin)
     	if (! $result > 0) $error++;
     	$result=dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN_UNIQUE",GETPOST('PAYMENT_SECURITY_TOKEN_UNIQUE','alpha'),'chaine',0,'',$conf->entity);
     	if (! $result > 0) $error++;
    +        $result=dolibarr_set_const($db, "PAYBOX_HMAC_KEY", dol_encode(GETPOST('PAYBOX_HMAC_KEY','alpha')),'chaine',0,'',$conf->entity);
    +	if (! $result > 0) $error++;
    +        
     
         if (! $error)
       	{
    @@ -145,6 +148,12 @@ print '<input size="32" type="text" name="PAYBOX_PBX_IDENTIFIANT" value="'.$conf
     print '<br>'.$langs->trans("Example").': 2 ('.$langs->trans("Test").')';
     print '</td></tr>';
     
    +print '<tr class="oddeven"><td>';
    +print '<span class="fieldrequired">'.$langs->trans("PAYBOX_HMAC_KEY").'</span></td><td>';
    +print '<input size="100" type="text" name="PAYBOX_HMAC_KEY" value="'.dol_decode($conf->global->PAYBOX_HMAC_KEY).'">';
    +print '<br>'.$langs->trans("Example").': 2 ('.$langs->trans("Test").')';
    +print '</td></tr>';
    +
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("UsageParameter").'</td>';
     print '<td>'.$langs->trans("Value").'</td>';
    @@ -250,5 +259,6 @@ print '<br><br>';
     
     include DOL_DOCUMENT_ROOT.'/core/tpl/onlinepaymentlinks.tpl.php';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/paybox/lib/paybox.lib.php b/htdocs/paybox/lib/paybox.lib.php
    index a4106488f53..a904c372099 100644
    --- a/htdocs/paybox/lib/paybox.lib.php
    +++ b/htdocs/paybox/lib/paybox.lib.php
    @@ -92,16 +92,41 @@ function print_paybox_redirect($PRICE,$CURRENCY,$EMAIL,$urlok,$urlko,$TAG)
         $IBS_REFUSE=$urlko;
         $IBS_BKGD="#FFFFFF";
         $IBS_WAIT="2000";
    -	$IBS_LANG="GBR"; 	// By default GBR=english (FRA, GBR, ESP, ITA et DEU...)
    -	if (preg_match('/^FR/i',$langs->defaultlang)) $IBS_LANG="FRA";
    -	if (preg_match('/^ES/i',$langs->defaultlang)) $IBS_LANG="ESP";
    -	if (preg_match('/^IT/i',$langs->defaultlang)) $IBS_LANG="ITA";
    -	if (preg_match('/^DE/i',$langs->defaultlang)) $IBS_LANG="DEU";
    -	if (preg_match('/^NL/i',$langs->defaultlang)) $IBS_LANG="NLD";
    -	if (preg_match('/^SE/i',$langs->defaultlang)) $IBS_LANG="SWE";
    -	$IBS_OUTPUT='E';
    -	$PBX_SOURCE='HTML';
    -	$PBX_TYPEPAIEMENT='CARTE';
    +    $IBS_LANG="GBR"; 	// By default GBR=english (FRA, GBR, ESP, ITA et DEU...)
    +    if (preg_match('/^FR/i',$langs->defaultlang)) $IBS_LANG="FRA";
    +    if (preg_match('/^ES/i',$langs->defaultlang)) $IBS_LANG="ESP";
    +    if (preg_match('/^IT/i',$langs->defaultlang)) $IBS_LANG="ITA";
    +    if (preg_match('/^DE/i',$langs->defaultlang)) $IBS_LANG="DEU";
    +    if (preg_match('/^NL/i',$langs->defaultlang)) $IBS_LANG="NLD";
    +    if (preg_match('/^SE/i',$langs->defaultlang)) $IBS_LANG="SWE";
    +    $IBS_OUTPUT='E';
    +    $PBX_SOURCE='HTML';
    +    $PBX_TYPEPAIEMENT='CARTE';
    +    
    +    $msg = "PBX_IDENTIFIANT=".$PBX_IDENTIFIANT.
    +           "&PBX_MODE=".$IBS_MODE.
    +           "&PBX_SITE=".$IBS_SITE.
    +           "&PBX_RANG=".$IBS_RANG.
    +           "&PBX_TOTAL=".$IBS_TOTAL.
    +           "&PBX_DEVISE=".$IBS_DEVISE.
    +           "&PBX_CMD=".$IBS_CMD.
    +           "&PBX_PORTEUR=".$IBS_PORTEUR.
    +           "&PBX_RETOUR=".$IBS_RETOUR.
    +           "&PBX_EFFECTUE=".$IBS_EFFECTUE.
    +           "&PBX_ANNULE=".$IBS_ANNULE.
    +           "&PBX_REFUSE=".$IBS_REFUSE.
    +           "&PBX_TXT=".$IBS_TXT.
    +           "&PBX_BKGD=".$IBS_BKGD.
    +           "&PBX_WAIT=".$IBS_WAIT.
    +           "&PBX_LANGUE=".$IBS_LANG.
    +           "&PBX_OUTPUT=".$IBS_OUTPUT.
    +           "&PBX_SOURCE=".$PBX_SOURCE.
    +           "&PBX_TYPEPAIEMENT=".$PBX_TYPEPAIEMENT;
    +    
    +    $binKey = pack("H*", dol_decode($conf->global->PAYBOX_HMAC_KEY));
    +            
    +    $hmac = strtoupper(hash_hmac('sha512', $msg, $binKey));
    +           
     
         dol_syslog("Soumission Paybox", LOG_DEBUG);
         dol_syslog("IBS_MODE: $IBS_MODE", LOG_DEBUG);
    @@ -157,7 +182,7 @@ function print_paybox_redirect($PRICE,$CURRENCY,$EMAIL,$urlok,$urlko,$TAG)
         print '<input type="hidden" name="PBX_OUTPUT" value="'.$IBS_OUTPUT.'">'."\n";
         print '<input type="hidden" name="PBX_SOURCE" value="'.$PBX_SOURCE.'">'."\n";
         print '<input type="hidden" name="PBX_TYPEPAIEMENT" value="'.$PBX_TYPEPAIEMENT.'">'."\n";
    -
    +    print '<input type="hidden" name="PBX_HMAC" value="'.$hmac.'">'."\n";
         print '</form>'."\n";
     
     
    diff --git a/htdocs/paypal/admin/paypal.php b/htdocs/paypal/admin/paypal.php
    index f15667ced51..c4fb21c99e5 100644
    --- a/htdocs/paypal/admin/paypal.php
    +++ b/htdocs/paypal/admin/paypal.php
    @@ -326,5 +326,6 @@ $token='';
     
     include DOL_DOCUMENT_ROOT.'/core/tpl/onlinepaymentlinks.tpl.php';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php
    index 4855799c508..e99acdedf5d 100644
    --- a/htdocs/paypal/lib/paypal.lib.php
    +++ b/htdocs/paypal/lib/paypal.lib.php
    @@ -287,7 +287,6 @@ function print_paypal_redirect($paymentAmount,$currencyCodeType,$paymentType,$re
     
             return $mesg;
         }
    -
     }
     
     /**
    @@ -401,7 +400,7 @@ function callSetExpressCheckout($paymentAmount, $currencyCodeType, $paymentType,
     	    $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT;		// This is to use external domain name found into config file
     	    //$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
     
    -	    $urllogo=$urlwithroot."/viewimage.php?modulepart=mycompany&file=".$mysoc->logo;
    +	    $urllogo=$urlwithroot."/viewimage.php?modulepart=mycompany&file=".urlencode('logos/'.$mysoc->logo);
     	    $nvpstr = $nvpstr . "&LOGOIMG=" . urlencode($urllogo);
         }
         if (! empty($conf->global->PAYPAL_BRANDNAME))
    diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php
    index 96b9cad3849..c4b2bb12111 100644
    --- a/htdocs/printing/admin/printing.php
    +++ b/htdocs/printing/admin/printing.php
    @@ -109,12 +109,12 @@ if ($action == 'setvalue' && $user->admin)
     
     $form = new Form($db);
     
    -llxHeader('',$langs->trans("PrintingSetup"));
    +llxHeader('', $langs->trans("PrintingSetup"));
     
     $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
     print load_fiche_titre($langs->trans("PrintingSetup"),$linkback,'title_setup');
     
    -$head=printingadmin_prepare_head($mode);
    +$head = printingAdminPrepareHead($mode);
     
     if ($mode == 'setup' && $user->admin)
     {
    @@ -127,7 +127,6 @@ if ($mode == 'setup' && $user->admin)
         print $langs->trans("PrintingDriverDesc".$driver)."<br><br>\n";
     
         print '<table class="noborder" width="100%">'."\n";
    -    $var=true;
         print '<tr class="liste_titre">';
         print '<th>'.$langs->trans("Parameters").'</th>';
         print '<th>'.$langs->trans("Value").'</th>';
    @@ -135,8 +134,7 @@ if ($mode == 'setup' && $user->admin)
         print "</tr>\n";
         $submit_enabled=0;
     
    -    if (! empty($driver))
    -    {
    +    if (! empty($driver)) {
             require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
             $classname = 'printing_'.$driver;
             $langs->load($driver);
    @@ -146,7 +144,6 @@ if ($mode == 'setup' && $user->admin)
             $submit_enabled=0;
             foreach ($printer->conf as $key)
             {
    -
                 switch ($key['type']) {
                     case "text":
                     case "password":
    @@ -248,7 +245,6 @@ if ($mode == 'config' && $user->admin)
     
         print '<table class="noborder" width="100%">'."\n";
     
    -    $var=true;
         print '<tr class="liste_titre">';
         print '<th>'.$langs->trans("Description").'</th>';
         print '<th class="center">'.$langs->trans("Active").'</th>';
    @@ -307,7 +303,7 @@ if ($mode == 'test' && $user->admin)
             $langs->load($driver);
             $printer = new $classname($db);
             //print '<pre>'.print_r($printer, true).'</pre>';
    -        if (count($printer->getlist_available_printers())) {
    +        if (count($printer->getlistAvailablePrinters())) {
                 if ($printer->listAvailablePrinters()==0) {
                     print $printer->resprint;
                 } else {
    @@ -317,7 +313,6 @@ if ($mode == 'test' && $user->admin)
             else {
                 print $langs->trans('PleaseConfigureDriverfromList');
             }
    -
         } else {
             print $langs->trans('PleaseSelectaDriverfromList');
         }
    @@ -333,7 +328,6 @@ if ($mode == 'userconf' && $user->admin)
         print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
     
         print '<table class="noborder" width="100%">';
    -    $var=true;
         print '<tr class="liste_titre">';
         print '<th>'.$langs->trans("User").'</th>';
         print '<th>'.$langs->trans("PrintModule").'</th>';
    @@ -362,9 +356,8 @@ if ($mode == 'userconf' && $user->admin)
         print '</table>';
     
         dol_fiche_end();
    -
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/printing/index.php b/htdocs/printing/index.php
    index 384d0834cc0..a95e3517be6 100644
    --- a/htdocs/printing/index.php
    +++ b/htdocs/printing/index.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2014-2015  Frederic France      <frederic.france@free.fr>
    - * Copyright (C) 2016       Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2014-2018  Frederic France         <frederic.france@netlogic.fr>
    + * Copyright (C) 2016       Laurent Destailleur     <eldy@users.sourceforge.net>
      *
      * 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
    @@ -40,34 +40,31 @@ $langs->load("printing");
      * View
      */
     
    -llxHeader("",$langs->trans("Printing"));
    +llxHeader("", $langs->trans("Printing"));
     
    -print_barre_liste($langs->trans("Printing"), 0, $_SERVER["PHP_SELF"], '', '', '', '<a class="button" href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("Refresh").'</a>', 0, 0, 'title_setup.png');
    +print_barre_liste($langs->trans("Printing"), 0, $_SERVER["PHP_SELF"], '', '', '', '<a class="button" href="' . $_SERVER["PHP_SELF"] . '">' . $langs->trans("Refresh") . '</a>', 0, 0, 'title_setup.png');
     
     print $langs->trans("DirectPrintingJobsDesc").'<br><br>';
     
     // List Jobs from printing modules
     $object = new PrintingDriver($db);
     $result = $object->listDrivers($db, 10);
    -foreach ($result as $driver) 
    -{
    +foreach ($result as $driver) {
         require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
         $classname = 'printing_'.$driver;
         $langs->load($driver);
         $printer = new $classname($db);
    -    if ($conf->global->{$printer->active}) 
    -    {
    -        //$printer->list_jobs('commande');
    -        $result = $printer->list_jobs();
    +    if ($conf->global->{$printer->active}) {
    +        //$printer->listJobs('commande');
    +        $result = $printer->listJobs();
             print $printer->resprint;
    -        
    -        if ($result > 0) 
    -        {
    +
    +        if ($result > 0) {
                 setEventMessages($printer->error, $printer->errors, 'errors');
             }
         }
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/printing/lib/printing.lib.php b/htdocs/printing/lib/printing.lib.php
    index 697e986cd56..53257891e25 100644
    --- a/htdocs/printing/lib/printing.lib.php
    +++ b/htdocs/printing/lib/printing.lib.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2015       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -26,10 +27,10 @@
     /**
      *  Define head array for tabs of printing tools setup pages
      *
    - *  @param	string	$mode		Mode
    - *  @return         			Array of head
    + *  @param  string  $mode       Mode
    + *  @return array               Array of head
      */
    -function printingadmin_prepare_head($mode)
    +function printingAdminPrepareHead($mode)
     {
         global $langs, $conf;
     
    @@ -41,28 +42,26 @@ function printingadmin_prepare_head($mode)
         $head[$h][2] = 'config';
         $h++;
     
    -    if ($mode == 'setup')
    -    {
    -	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup&driver=".GETPOST('driver','alpha');
    -	    $head[$h][1] = $langs->trans("SetupDriver");
    -	    $head[$h][2] = 'setup';
    -	    $h++;
    +    if ($mode == 'setup') {
    +        $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup&driver=".GETPOST('driver','alpha');
    +        $head[$h][1] = $langs->trans("SetupDriver");
    +        $head[$h][2] = 'setup';
    +        $h++;
         }
     
    -    if ($mode == 'test')
    -    {
    -	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test&driver=".GETPOST('driver','alpha');
    -	    $head[$h][1] = $langs->trans("TargetedPrinter");
    -	    $head[$h][2] = 'test';
    -	    $h++;
    +    if ($mode == 'test') {
    +        $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test&driver=".GETPOST('driver','alpha');
    +        $head[$h][1] = $langs->trans("TargetedPrinter");
    +        $head[$h][2] = 'test';
    +        $h++;
         }
     
    -		/** TODO This feature seem to be not ready yet.
    -	    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=userconf";
    -	    $head[$h][1] = $langs->trans("UserConf");
    -	    $head[$h][2] = 'userconf';
    -	    $h++;
    -	    */
    +    /** TODO This feature seem to be not ready yet.
    +    $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=userconf";
    +    $head[$h][1] = $langs->trans("UserConf");
    +    $head[$h][2] = 'userconf';
    +    $h++;
    +    */
     
         //$object=new stdClass();
     
    @@ -76,4 +75,3 @@ function printingadmin_prepare_head($mode)
     
         return $head;
     }
    -
    diff --git a/htdocs/product/admin/dynamic_prices.php b/htdocs/product/admin/dynamic_prices.php
    index 348380e9b37..4f40c85e2a9 100644
    --- a/htdocs/product/admin/dynamic_prices.php
    +++ b/htdocs/product/admin/dynamic_prices.php
    @@ -357,5 +357,6 @@ if ($action == 'create_updater' || $action == 'edit_updater') {
         print '</form>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/admin/price_rules.php b/htdocs/product/admin/price_rules.php
    index 0049daeaa7d..730a8fd31f2 100644
    --- a/htdocs/product/admin/price_rules.php
    +++ b/htdocs/product/admin/price_rules.php
    @@ -14,7 +14,7 @@
      *
      * You should have received a copy of the GNU General Public License
      * along with this program. If not, see <http://www.gnu.org/licenses/>.
    - * 
    + *
      * Page to set how to autocalculate price for each level when option
      * PRODUCT_MULTIPRICE is on.
      */
    @@ -92,7 +92,6 @@ if ($_POST) {
     				setEventMessages($langs->trans('ErrorSavingChanges'), null, 'errors');
     			}
     		}
    -
     	}
     
     	setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
    @@ -145,7 +144,7 @@ for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) {
     	$price_options[$i] = $langs->trans('SellingPrice').' '.$i;
     }
     
    -$genPriceOptions = function($level) use ($price_options) {
    +$genPriceOptions = function ($level) use ($price_options) {
     
     	$return = array();
     
    @@ -190,16 +189,16 @@ $genPriceOptions = function($level) use ($price_options) {
     		<?php endfor ?>
     	</table>
     
    -<?php 
    +<?php
     
     dol_fiche_end();
     
     print '<div style="text-align: center">
     		<input type="submit" value="'.$langs->trans('Save').'" class="button">
     	</div>';
    -	
    +
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php
    index bb214ffc06a..45f938431c3 100644
    --- a/htdocs/product/admin/product.php
    +++ b/htdocs/product/admin/product.php
    @@ -127,7 +127,6 @@ if ($action == 'other')
     				$res = dolibarr_set_const($db, $rule, 0, 'chaine', 0, '', $conf->entity);
     			}
     		}
    -
     	}
     
     	$value = GETPOST('PRODUIT_SOUSPRODUITS','alpha');
    @@ -144,6 +143,18 @@ if ($action == 'other')
     
     	$value = GETPOST('activate_usesearchtoselectproduct','alpha');
     	$res = dolibarr_set_const($db, "PRODUIT_USE_SEARCH_TO_SELECT", $value,'chaine',0,'',$conf->entity);
    +	
    +	$value = GETPOST('activate_useProdFournDesc', 'alpha');
    +	$res = dolibarr_set_const($db, "PRODUIT_FOURN_TEXTS", $value,'chaine',0,'',$conf->entity);
    +	if ($value) {
    +	    $sql_test = "SELECT count(desc_fourn) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1";
    +	    $resql = $db->query($sql_test);
    +	    if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') // if the field does not exist, we create it
    +	    {
    +	        $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN desc_fourn text";
    +	        $resql_new = $db->query($sql_new);
    +	    }
    +	}
     }
     
     if ($action == 'specimen') // For products
    @@ -180,13 +191,13 @@ if ($action == 'specimen') // For products
     		}
     		else
     		{
    -			setEventMessage($obj->error,'errors');
    +			setEventMessages($obj->error, $obj->errors, 'errors');
     			dol_syslog($obj->error, LOG_ERR);
     		}
     	}
     	else
     	{
    -		setEventMessage($langs->trans("ErrorModuleNotFound"),'errors');
    +		setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors');
     		dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR);
     	}
     }
    @@ -401,7 +412,6 @@ print "</tr>\n";
     
     clearstatcache();
     
    -$var=true;
     foreach ($dirmodels as $reldir)
     {
         foreach (array('','/doc') as $valdir)
    @@ -438,7 +448,6 @@ foreach ($dirmodels as $reldir)
     
     	                        if ($modulequalified)
     	                        {
    -	                            $var = !$var;
     	                            print '<tr class="oddeven"><td width="100">';
     	                            print (empty($module->name)?$name:$module->name);
     	                            print "</td><td>\n";
    @@ -524,12 +533,10 @@ print "<br>";
     print load_fiche_titre($langs->trans("ProductOtherConf"), '', '');
     
     
    -
     print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     print '<input type="hidden" name="action" value="other">';
     
    -$var=true;
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("Parameters").'</td>'."\n";
    @@ -545,6 +552,7 @@ $rowspan = 4;
     if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) $rowspan++;
     if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) $rowspan++;
     if (! empty($conf->global->MAIN_MULTILANGS)) $rowspan++;
    +if (! empty($conf->fournisseur->enabled)) $rowspan++;
     
     
     print '<tr class="oddeven">';
    @@ -569,7 +577,6 @@ print '</tr>';
     // multiprix nombre de prix a proposer
     if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
     {
    -
     	print '<tr class="oddeven">';
     	print '<td>'.$langs->trans("MultiPricesNumPrices").'</td>';
     	print '<td align="right"><input size="3" type="text" class="flat" name="value_PRODUIT_MULTIPRICES_LIMIT" value="'.$conf->global->PRODUIT_MULTIPRICES_LIMIT.'"></td>';
    @@ -611,7 +618,6 @@ print '</tr>';
     
     if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
     {
    -
     	print '<tr class="oddeven">';
     	print '<td>'.$langs->trans("NumberOfProductShowInSelect").'</td>';
     	print '<td align="right"><input size="3" type="text" class="flat" name="value_PRODUIT_LIMIT_SIZE" value="'.$conf->global->PRODUIT_LIMIT_SIZE.'"></td>';
    @@ -619,7 +625,6 @@ if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
     }
     
     // Visualiser description produit dans les formulaires activation/desactivation
    -
     print '<tr class="oddeven">';
     print '<td>'.$langs->trans("ViewProductDescInFormAbility").'</td>';
     print '<td width="60" align="right">';
    @@ -652,7 +657,6 @@ print '</tr>';
     // View product description in thirdparty language
     if (! empty($conf->global->MAIN_MULTILANGS))
     {
    -
     	print '<tr class="oddeven">';
     	print '<td>'.$langs->trans("ViewProductDescInThirdpartyLanguageAbility").'</td>';
     	print '<td width="60" align="right">';
    @@ -661,12 +665,20 @@ if (! empty($conf->global->MAIN_MULTILANGS))
     	print '</tr>';
     }
     
    +if (! empty($conf->fournisseur->enabled))
    +{
    +    print '<tr class="oddeven">';
    +    print '<td>'.$langs->trans("UseProductFournDesc").'</td>';
    +    print '<td width="60" align="right">';
    +    print $form->selectyesno("activate_useProdFournDesc", (! empty($conf->global->PRODUIT_FOURN_TEXTS)?$conf->global->PRODUIT_FOURN_TEXTS:0), 1);
    +    print '</td>';
    +    print '</tr>';
    +}
     
     if (! empty($conf->global->PRODUCT_CANVAS_ABILITY))
     {
     	// Add canvas feature
     	$dir = DOL_DOCUMENT_ROOT . "/product/canvas/";
    -	$var = false;
     
     	print '<tr class="liste_titre">';
     	print '<td>'.$langs->trans("ProductSpecial").'</td>'."\n";
    @@ -694,8 +706,7 @@ if (! empty($conf->global->PRODUCT_CANVAS_ABILITY))
     
         				if ($conf->$module->enabled)
         				{
    -
    -    					print "<tr ".$bc[$var]."><td>";
    +    					print '<tr class="oddeven"><td>';
     
         					print $object->description;
     
    @@ -732,7 +743,7 @@ print '</table>';
     
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
    diff --git a/htdocs/product/admin/product_extrafields.php b/htdocs/product/admin/product_extrafields.php
    index 849b346244d..82eafd230d7 100644
    --- a/htdocs/product/admin/product_extrafields.php
    +++ b/htdocs/product/admin/product_extrafields.php
    @@ -94,7 +94,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -107,8 +107,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    @@ -126,6 +126,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/admin/product_lot_extrafields.php b/htdocs/product/admin/product_lot_extrafields.php
    index be3651344ff..8e57daf7491 100644
    --- a/htdocs/product/admin/product_lot_extrafields.php
    +++ b/htdocs/product/admin/product_lot_extrafields.php
    @@ -84,7 +84,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -97,8 +97,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    @@ -116,6 +116,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php
    index 291aba9bcf1..b0c62c81d4f 100644
    --- a/htdocs/product/admin/product_tools.php
    +++ b/htdocs/product/admin/product_tools.php
    @@ -267,7 +267,6 @@ if ($action == 'convert')
     		{
     			setEventMessages($langs->trans("Error"), null, 'errors');
     		}
    -
     	}
     }
     
    @@ -294,8 +293,6 @@ if (empty($mysoc->country_code))
     else
     {
     
    -	$var=true;
    -
     	print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
     	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'" />';
     	print '<input type="hidden" name="action" value="convert" />';
    @@ -344,6 +341,6 @@ else
     	print '</form>';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/agenda.php b/htdocs/product/agenda.php
    index 9eee66664d9..2dfe8aa425f 100644
    --- a/htdocs/product/agenda.php
    +++ b/htdocs/product/agenda.php
    @@ -203,7 +203,6 @@ if ($id > 0 || $ref)
         }
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/canvas/product/actions_card_product.class.php b/htdocs/product/canvas/product/actions_card_product.class.php
    index 3c0fc4d2b2f..bcd9773c719 100644
    --- a/htdocs/product/canvas/product/actions_card_product.class.php
    +++ b/htdocs/product/canvas/product/actions_card_product.class.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin  <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin  <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -64,6 +64,7 @@ class ActionsCardProduct
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Assign custom values for canvas (for example into this->tpl to be used by templates)
     	 *
    @@ -74,6 +75,7 @@ class ActionsCardProduct
     	 */
     	function assign_values(&$action, $id=0, $ref='')
     	{
    +        // phpcs:enable
     		global $limit, $offset, $sortfield, $sortorder;
             global $conf, $langs, $user, $mysoc, $canvas;
     		global $form, $formproduct;
    @@ -123,20 +125,6 @@ class ActionsCardProduct
     			$this->tpl['tva_tx'] = $form->load_tva("tva_tx",-1,$mysoc,'');
     		}
     
    -		if ($action == 'create' || $action == 'edit')
    -		{
    -			// Status
    -			$statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSell"));
    -			$this->tpl['status'] = $form->selectarray('statut',$statutarray,$this->status);
    -
    -			//To Buy
    -			$statutarray=array('1' => $langs->trans("Yes"), '0' => $langs->trans("No"));
    -			$this->tpl['tobuy'] = $form->selectarray('tobuy',$statutarray,$this->status_buy);
    -
    -            $this->tpl['description'] = $this->description;
    -            $this->tpl['note'] = $this->note;
    -		}
    -
     		if ($action == 'view')
     		{
                 $head = product_prepare_head($this->object);
    @@ -180,10 +168,13 @@ class ActionsCardProduct
     		{
         		// Status
         		$statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSell"));
    -    		$this->tpl['status'] = $form->selectarray('statut',$statutarray,$_POST["statut"]);
    +    		$this->tpl['status'] = $form->selectarray('statut',$statutarray,$this->object->status);
     
         		$statutarray=array('1' => $langs->trans("ProductStatusOnBuy"), '0' => $langs->trans("ProductStatusNotOnBuy"));
    -    		$this->tpl['status_buy'] = $form->selectarray('statut_buy',$statutarray,$_POST["statut_buy"]);
    +    		$this->tpl['status_buy'] = $form->selectarray('statut_buy',$statutarray,$this->object->status_buy);
    +
    +    		$this->tpl['description'] = $this->description;
    +    		$this->tpl['note'] = $this->note;
     
     		    // Finished
     			$statutarray=array('1' => $langs->trans("Finished"), '0' => $langs->trans("RowMaterial"));
    @@ -208,10 +199,6 @@ class ActionsCardProduct
     
     		if ($action == 'view')
     		{
    -    		// Status
    -    		$this->tpl['status'] = $this->object->getLibStatut(2,0);
    -    		$this->tpl['status_buy'] = $this->object->getLibStatut(2,1);
    -
         		// Photo
     			$this->tpl['nblignes'] = 4;
     			if ($this->object->is_photo_available($conf->product->multidir_output[$this->object->entity]))
    @@ -253,7 +240,6 @@ class ActionsCardProduct
     		{
     	        $this->LoadListDatas($limit, $offset, $sortfield, $sortorder);
     		}
    -
     	}
     
     
    @@ -268,7 +254,7 @@ class ActionsCardProduct
     
     		$this->field_list = array();
     
    -		$sql = "SELECT rowid, name, alias, title, align, sort, search, enabled, rang";
    +		$sql = "SELECT rowid, name, alias, title, align, sort, search, visible, enabled, rang";
     		$sql.= " FROM ".MAIN_DB_PREFIX."c_field_list";
     		$sql.= " WHERE element = '".$this->db->escape($this->fieldListName)."'";
     		$sql.= " AND entity = ".$conf->entity;
    @@ -293,6 +279,7 @@ class ActionsCardProduct
     				$fieldlist["align"]		= $obj->align;
     				$fieldlist["sort"]		= $obj->sort;
     				$fieldlist["search"]	= $obj->search;
    +				$fieldlist["visible"]	= $obj->visible;
     				$fieldlist["enabled"]	= verifCond($obj->enabled);
     				$fieldlist["order"]		= $obj->rang;
     
    @@ -309,6 +296,7 @@ class ActionsCardProduct
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Fetch datas list and save into ->list_datas
     	 *
    @@ -320,6 +308,7 @@ class ActionsCardProduct
     	 */
     	function LoadListDatas($limit, $offset, $sortfield, $sortorder)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
             $this->getFieldList();
    @@ -445,6 +434,4 @@ class ActionsCardProduct
     			dol_print_error($this->db);
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/product/canvas/product/tpl/card_create.tpl.php b/htdocs/product/canvas/product/tpl/card_create.tpl.php
    index bc4b5409688..dbaaed35319 100644
    --- a/htdocs/product/canvas/product/tpl/card_create.tpl.php
    +++ b/htdocs/product/canvas/product/tpl/card_create.tpl.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -30,7 +30,10 @@ $statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSe
     
     <!-- BEGIN PHP TEMPLATE -->
     
    -<?php print load_fiche_titre($langs->trans("Product")); ?>
    +<?php
    +print load_fiche_titre($langs->trans("NewProduct"),'','title_products.png');
    +dol_fiche_head('');
    +?>
     
     <?php dol_htmloutput_errors((is_numeric($object->error)?'':$object->error),$object->errors); ?>
     
    @@ -65,7 +68,7 @@ $statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSe
     
     <tr>
     <td class="fieldrequired"><?php echo $langs->trans("Status").' ('.$langs->trans("Buy").')'; ?></td>
    -<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_tobuy); ?></td>
    +<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_buy); ?></td>
     </tr>
     
     <?php if (! empty($conf->stock->enabled)) { ?>
    diff --git a/htdocs/product/canvas/product/tpl/card_edit.tpl.php b/htdocs/product/canvas/product/tpl/card_edit.tpl.php
    index 6c13bddb6a1..f114020a4bc 100644
    --- a/htdocs/product/canvas/product/tpl/card_edit.tpl.php
    +++ b/htdocs/product/canvas/product/tpl/card_edit.tpl.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -31,7 +31,9 @@ $statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSe
     <!-- BEGIN PHP TEMPLATE -->
     
     <?php
    -print load_fiche_titre($langs->trans("Product"));
    +$head=product_prepare_head($object);
    +$titre=$langs->trans("CardProduct".$object->type);
    +dol_fiche_head($head, 'card', $titre, 0, 'product');
     
     dol_htmloutput_errors($object->error,$object->errors);
     ?>
    @@ -65,7 +67,7 @@ dol_htmloutput_errors($object->error,$object->errors);
     
     <tr>
     <td class="fieldrequired"><?php echo $langs->trans("Status").' ('.$langs->trans("Buy").')'; ?></td>
    -<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_tobuy); ?></td>
    +<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_buy); ?></td>
     </tr>
     
     <?php if (! empty($conf->stock->enabled)) { ?>
    diff --git a/htdocs/product/canvas/product/tpl/card_view.tpl.php b/htdocs/product/canvas/product/tpl/card_view.tpl.php
    index 44b1f96203b..61964399e1c 100644
    --- a/htdocs/product/canvas/product/tpl/card_view.tpl.php
    +++ b/htdocs/product/canvas/product/tpl/card_view.tpl.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -27,7 +27,20 @@ $object=$GLOBALS['object'];
     ?>
     
     <!-- BEGIN PHP TEMPLATE -->
    -<?php echo $langs->trans("Product"); ?>
    +<?php
    +$head=product_prepare_head($object);
    +$titre=$langs->trans("CardProduct".$object->type);
    +
    +dol_fiche_head($head, 'card', $titre, -1, 'product');
    +
    +$linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1&type='.$object->type.'">'.$langs->trans("BackToList").'</a>';
    +$object->next_prev_filter=" fk_product_type = ".$object->type;
    +
    +$shownav = 1;
    +if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0;
    +
    +dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
    +?>
     
     <?php dol_htmloutput_errors($object->error,$object->errors); ?>
     
    @@ -50,16 +63,6 @@ $object=$GLOBALS['object'];
     
     </tr>
     
    -<tr>
    -<td><?php echo $langs->trans("Status").' ('.$langs->trans("Sell").')'; ?></td>
    -<td><?php echo $object->status; ?></td>
    -</tr>
    -
    -<tr>
    -<td><?php echo $langs->trans("Status").' ('.$langs->trans("Buy").')'; ?></td>
    -<td><?php echo $object->status_buy; ?></td>
    -</tr>
    -
     <tr>
     <td class="tdtop"><?php echo $langs->trans("Description"); ?></td>
     <td colspan="2"><?php echo $object->description; ?></td>
    diff --git a/htdocs/product/canvas/product/tpl/list.tpl.php b/htdocs/product/canvas/product/tpl/list.tpl.php
    deleted file mode 100644
    index e5c315e8148..00000000000
    --- a/htdocs/product/canvas/product/tpl/list.tpl.php
    +++ /dev/null
    @@ -1,108 +0,0 @@
    -<?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    - *
    - * 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 <http://www.gnu.org/licenses/>.
    - */
    -
    -// Protection to avoid direct call of template
    -if (empty($conf) || ! is_object($conf))
    -{
    -	print "Error, template page can't be called as URL";
    -	exit;
    -}
    -
    -?>
    -
    -<!-- BEGIN PHP TEMPLATE -->
    -
    -<table class="notopnoleftnoright allwidth" style="margin-bottom: 2px;">
    -<tr>
    -	<td class="nobordernopadding" width="40" align="left" valign="middle">
    -		<?php echo $title_picto; ?>
    -	</td>
    -	<td class="nobordernopadding" valign="middle">
    -    	<div class="titre"><?php echo $title_text; ?></div>
    -	</td>
    -</tr>
    -</table>
    -
    -<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post" name="formulaire">
    -<input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>">
    -<input type="hidden" name="action" value="list">
    -<input type="hidden" name="sortfield" value="<?php echo $sortfield; ?>">
    -<input type="hidden" name="sortorder" value="<?php echo $sortorder; ?>">
    -<input type="hidden" name="canvas" value="default">
    -<input type="hidden" name="type" value="0">
    -
    -<table class="liste allwidth">
    -
    -<!-- FIELDS TITLE -->
    -
    -<tr class="liste_titre">
    -	<?php
    - 	foreach($fieldlist as $field) {
    - 		if ($field['enabled']) {
    - 			if ($field['sort'])	{ ?>
    - 				<td class="liste_titre" align="<?php echo $field['align']; ?>"><?php echo $field['title']; ?>
    - 					<a href="<?php echo $_SERVER["PHP_SELF"];?>?sortfield=<?php echo $field['name']; ?>&amp;sortorder=asc&amp;begin=&amp;tosell=&amp;canvas=default&amp;fourn_id=&amp;snom=&amp;sref=">
    - 						<img src="<?php echo DOL_URL_ROOT; ?>/theme/<?php echo $conf->theme; ?>/img/1downarrow.png" border="0" alt="A-Z" title="A-Z">
    - 					</a>
    -  					<a href="<?php echo $_SERVER["PHP_SELF"];?>?sortfield=<?php echo $field['name']; ?>&amp;sortorder=desc&amp;begin=&amp;tosell=&amp;canvas=default&amp;fourn_id=&amp;snom=&amp;sref=">
    -  						<img src="<?php echo DOL_URL_ROOT; ?>/theme/<?php echo $conf->theme; ?>/img/1uparrow.png" border="0" alt="Z-A" title="Z-A">
    -  					</a>
    -  				</td>
    -  		<?php } else { ?>
    -  				<td class="liste_titre" align="<?php echo $field['align']; ?>"><?php echo $field['title']; ?></td>
    -	<?php } } } ?>
    -</tr>
    -
    - <!-- FIELDS SEARCH -->
    -
    -<tr class="liste_titre">
    -	<?php
    - 	$num = count($fieldlist);
    - 	foreach($fieldlist as $key => $searchfield)	{
    - 		if ($searchfield['enabled']) {
    - 			if ($searchfield['search'])	{ ?>
    -  				<td class="liste_titre" align="<?php echo $searchfield['align']; ?>"><input class="flat" type="text" name="s<?php echo $searchfield['alias']; ?>" value=""></td>
    -	<?php } else if ($key == $num) {
    -        print '<td class="liste_titre" align="right">';
    -        $searchpicto=$form->showFilterAndCheckAddButtons(0);
    -        print $searchpicto;
    -        print '</td>';
    -	} else { ?>
    -  			<td class="liste_titre">&nbsp;</td>
    - 	<?php } } } ?>
    -</tr>
    -
    -<!-- FIELDS DATA -->
    -
    -<?php
    -$var=true;
    -foreach($datas as $line) {
    -		?>
    -	<tr <?php echo $bc[$var]; ?>>
    -   		<?php
    -   		foreach($line as $key => $value) {
    -   			foreach($fieldlist as $field) {
    -   				if ($field['alias'] == $key) { ?>
    -   					<td align="<?php echo $field['align']; ?>"><?php echo $value; ?></td>
    -   		<?php } } } ?>
    -   	</tr>
    -<?php } ?>
    -
    -</table>
    -</form>
    -
    -<!-- END PHP TEMPLATE -->
    \ No newline at end of file
    diff --git a/htdocs/product/canvas/service/actions_card_service.class.php b/htdocs/product/canvas/service/actions_card_service.class.php
    index af227e54b0b..2f0489b6f91 100644
    --- a/htdocs/product/canvas/service/actions_card_service.class.php
    +++ b/htdocs/product/canvas/service/actions_card_service.class.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin  <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin  <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -63,6 +63,7 @@ class ActionsCardService
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *    Assign custom values for canvas (for example into this->tpl to be used by templates)
     	 *
    @@ -73,6 +74,7 @@ class ActionsCardService
     	 */
     	function assign_values(&$action, $id=0, $ref='')
     	{
    +        // phpcs:enable
     		global $limit, $offset, $sortfield, $sortorder;
             global $conf, $langs, $user, $mysoc, $canvas;
     		global $form, $formproduct;
    @@ -122,20 +124,6 @@ class ActionsCardService
     			$this->tpl['tva_tx'] = $form->load_tva("tva_tx",-1,$mysoc,'');
     		}
     
    -		if ($action == 'create' || $action == 'edit')
    -		{
    -			// Status
    -			$statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSell"));
    -			$this->tpl['status'] = $form->selectarray('statut',$statutarray,$this->status);
    -
    -			//To Buy
    -			$statutarray=array('1' => $langs->trans("Yes"), '0' => $langs->trans("No"));
    -			$this->tpl['tobuy'] = $form->selectarray('tobuy',$statutarray,$this->status_buy);
    -
    -            $this->tpl['description'] = $this->description;
    -            $this->tpl['note'] = $this->note;
    -		}
    -
     		if ($action == 'view')
     		{
                 $head = product_prepare_head($this->object);
    @@ -182,10 +170,13 @@ class ActionsCardService
     		{
         		// Status
         		$statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSell"));
    -    		$this->tpl['status'] = $form->selectarray('statut',$statutarray,$_POST["statut"]);
    +    		$this->tpl['status'] = $form->selectarray('statut',$statutarray,$this->object->status);
     
         		$statutarray=array('1' => $langs->trans("ProductStatusOnBuy"), '0' => $langs->trans("ProductStatusNotOnBuy"));
    -    		$this->tpl['status_buy'] = $form->selectarray('statut_buy',$statutarray,$_POST["statut_buy"]);
    +    		$this->tpl['status_buy'] = $form->selectarray('statut_buy',$statutarray,$this->object->status_buy);
    +
    +    		$this->tpl['description'] = $this->description;
    +    		$this->tpl['note'] = $this->note;
     
     		    // Duration unit
     			// TODO creer fonction
    @@ -203,10 +194,6 @@ class ActionsCardService
     
     		if ($action == 'view')
     		{
    -    		// Status
    -    		$this->tpl['status'] = $this->object->getLibStatut(2,0);
    -    		$this->tpl['status_buy'] = $this->object->getLibStatut(2,1);
    -
     		    // Photo
     			$this->tpl['nblignes'] = 4;
     			if ($this->object->is_photo_available($conf->service->multidir_output[$this->object->entity]))
    @@ -232,7 +219,6 @@ class ActionsCardService
     		{
     	        $this->LoadListDatas($limit, $offset, $sortfield, $sortorder);
     		}
    -
     	}
     
     
    @@ -247,7 +233,7 @@ class ActionsCardService
     
             $this->field_list = array();
     
    -		$sql = "SELECT rowid, name, alias, title, align, sort, search, enabled, rang";
    +		$sql = "SELECT rowid, name, alias, title, align, sort, search, visible, enabled, rang";
     		$sql.= " FROM ".MAIN_DB_PREFIX."c_field_list";
     		$sql.= " WHERE element = '".$this->db->escape($this->fieldListName)."'";
     		$sql.= " AND entity = ".$conf->entity;
    @@ -272,6 +258,7 @@ class ActionsCardService
     				$fieldlist["align"]		= $obj->align;
     				$fieldlist["sort"]		= $obj->sort;
     				$fieldlist["search"]	= $obj->search;
    +				$fieldlist["visible"]	= $obj->visible;
     				$fieldlist["enabled"]	= verifCond($obj->enabled);
     				$fieldlist["order"]		= $obj->rang;
     
    @@ -287,6 +274,7 @@ class ActionsCardService
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Fetch datas list and save into ->list_datas
     	 *
    @@ -298,6 +286,7 @@ class ActionsCardService
     	 */
     	function LoadListDatas($limit, $offset, $sortfield, $sortorder)
     	{
    +        // phpcs:enable
     		global $conf;
     		global $search_categ,$sall,$sref,$search_barcode,$snom,$catid;
     
    @@ -377,6 +366,4 @@ class ActionsCardService
     			print $sql;
     		}
     	}
    -
     }
    -
    diff --git a/htdocs/product/canvas/service/tpl/card_create.tpl.php b/htdocs/product/canvas/service/tpl/card_create.tpl.php
    index b9dc10fd5dc..f748edc03e6 100644
    --- a/htdocs/product/canvas/service/tpl/card_create.tpl.php
    +++ b/htdocs/product/canvas/service/tpl/card_create.tpl.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -30,7 +30,10 @@ $statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSe
     
     <!-- BEGIN PHP TEMPLATE CREATE.TPL -->
     
    -<?php print load_fiche_titre($langs->trans("Service")); ?>
    +<?php
    +print load_fiche_titre($langs->trans("NewService"),'','title_products.png');
    +dol_fiche_head('');
    +?>
     
     <?php dol_htmloutput_errors($this->control->tpl['error'],$this->control->tpl['errors']); ?>
     
    @@ -62,7 +65,7 @@ $statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSe
     
     <tr>
     <td class="fieldrequired"><?php echo $langs->trans("Status").' ('.$langs->trans("Buy").')'; ?></td>
    -<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_tobuy); ?></td>
    +<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_buy); ?></td>
     </tr>
     
     <tr><td><?php echo $langs->trans("Duration"); ?></td>
    diff --git a/htdocs/product/canvas/service/tpl/card_edit.tpl.php b/htdocs/product/canvas/service/tpl/card_edit.tpl.php
    index 6fc3bf3273a..969ce3de2da 100644
    --- a/htdocs/product/canvas/service/tpl/card_edit.tpl.php
    +++ b/htdocs/product/canvas/service/tpl/card_edit.tpl.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -31,7 +31,9 @@ $statutarray=array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSe
     <!-- BEGIN PHP TEMPLATE EDIT.TPL -->
     
     <?php
    -print load_fiche_titre($langs->trans("Service"));
    +$head=product_prepare_head($object);
    +$titre=$langs->trans("CardProduct".$object->type);
    +dol_fiche_head($head, 'card', $titre, 0, 'service');
     
     dol_htmloutput_errors($object->error,$object->errors);
     ?>
    @@ -62,7 +64,7 @@ dol_htmloutput_errors($object->error,$object->errors);
     
     <tr>
     <td class="fieldrequired"><?php echo $langs->trans("Status").' ('.$langs->trans("Buy").')'; ?></td>
    -<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_tobuy); ?></td>
    +<td><?php echo $form->selectarray('statut_buy',$statutarray,$object->status_buy); ?></td>
     </tr>
     
     <tr><td><?php echo $langs->trans("Duration"); ?></td>
    diff --git a/htdocs/product/canvas/service/tpl/card_view.tpl.php b/htdocs/product/canvas/service/tpl/card_view.tpl.php
    index fc129132dee..5826d78583f 100644
    --- a/htdocs/product/canvas/service/tpl/card_view.tpl.php
    +++ b/htdocs/product/canvas/service/tpl/card_view.tpl.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    +/* Copyright (C) 2010-2018 Regis Houssin <regis.houssin@capnetworks.com>
      *
      * 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
    @@ -27,7 +27,20 @@ $object=$GLOBALS['object'];
     ?>
     
     <!-- BEGIN PHP TEMPLATE VIEW.TPL -->
    -<?php echo $langs->trans("Service"); ?>
    +<?php
    +$head=product_prepare_head($object);
    +$titre=$langs->trans("CardProduct".$object->type);
    +
    +dol_fiche_head($head, 'card', $titre, -1, 'service');
    +
    +$linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?restore_lastsearch_values=1&type='.$object->type.'">'.$langs->trans("BackToList").'</a>';
    +$object->next_prev_filter=" fk_product_type = ".$object->type;
    +
    +$shownav = 1;
    +if ($user->societe_id && ! in_array('product', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0;
    +
    +dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
    +?>
     
     <?php dol_htmloutput_errors($object->error,$object->errors); ?>
     
    @@ -50,16 +63,6 @@ $object=$GLOBALS['object'];
     
     </tr>
     
    -<tr>
    -<td><?php echo $langs->trans("Status").' ('.$langs->trans("Sell").')'; ?></td>
    -<td><?php echo $object->status; ?></td>
    -</tr>
    -
    -<tr>
    -<td><?php echo $langs->trans("Status").' ('.$langs->trans("Buy").')'; ?></td>
    -<td><?php echo $object->status_buy; ?></td>
    -</tr>
    -
     <tr>
     <td class="tdtop"><?php echo $langs->trans("Description"); ?></td>
     <td colspan="2"><?php echo $object->description; ?></td>
    diff --git a/htdocs/product/canvas/service/tpl/list.tpl.php b/htdocs/product/canvas/service/tpl/list.tpl.php
    deleted file mode 100644
    index ef6d461fc5c..00000000000
    --- a/htdocs/product/canvas/service/tpl/list.tpl.php
    +++ /dev/null
    @@ -1,107 +0,0 @@
    -<?php
    -/* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com>
    - *
    - * 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 <http://www.gnu.org/licenses/>.
    - */
    -
    -// Protection to avoid direct call of template
    -if (empty($conf) || ! is_object($conf))
    -{
    -	print "Error, template page can't be called as URL";
    -	exit;
    -}
    -
    -?>
    -
    -<!-- BEGIN PHP TEMPLATE -->
    -
    -<table class="notopnoleftnoright allwidth" style="margin-bottom: 2px;">
    -<tr>
    -	<td class="nobordernopadding" width="40" align="left" valign="middle">
    -		<?php echo $title_picto; ?>
    -	</td>
    -	<td class="nobordernopadding" valign="middle">
    -    	<div class="titre"><?php echo $title_text; ?></div>
    -	</td>
    -</tr>
    -</table>
    -
    -<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post" name="formulaire">
    -<input type="hidden" name="token" value="<?php echo $_SESSION['newtoken']; ?>">
    -<input type="hidden" name="action" value="list">
    -<input type="hidden" name="sortfield" value="<?php echo $sortfield; ?>">
    -<input type="hidden" name="sortorder" value="<?php echo $sortorder; ?>">
    -<input type="hidden" name="canvas" value="service">
    -<input type="hidden" name="type" value="1">
    -
    -<table class="liste allwidth">
    -
    -<!-- FIELDS TITLE -->
    -
    -<tr class="liste_titre">
    -	<?php
    - 	foreach($fieldlist as $field) {
    - 		if ($field['enabled']) {
    - 			if ($field['sort'])	{ ?>
    - 				<td class="liste_titre" align="<?php echo $field['align']; ?>"><?php echo $field['title']; ?>
    - 					<a href="<?php echo $_SERVER["PHP_SELF"];?>?sortfield=<?php echo $field['name']; ?>&amp;sortorder=asc&amp;begin=&amp;tosell=&amp;canvas=default&amp;fourn_id=&amp;snom=&amp;sref=">
    - 						<img src="<?php echo DOL_URL_ROOT; ?>/theme/<?php echo $conf->theme; ?>/img/1downarrow.png" border="0" alt="A-Z" title="A-Z">
    - 					</a>
    -  					<a href="<?php echo $_SERVER["PHP_SELF"];?>?sortfield=<?php echo $field['name']; ?>&amp;sortorder=desc&amp;begin=&amp;tosell=&amp;canvas=default&amp;fourn_id=&amp;snom=&amp;sref=">
    -  						<img src="<?php echo DOL_URL_ROOT; ?>/theme/<?php echo $conf->theme; ?>/img/1uparrow.png" border="0" alt="Z-A" title="Z-A">
    -  					</a>
    -  				</td>
    -  		<?php } else { ?>
    -  				<td class="liste_titre" align="<?php echo $field['align']; ?>"><?php echo $field['title']; ?></td>
    -	<?php } } } ?>
    -</tr>
    -
    - <!-- FIELDS SEARCH -->
    -
    -<tr class="liste_titre">
    -	<?php
    - 	$num = count($fieldlist);
    - 	foreach($fieldlist as $key => $searchfield)	{
    - 		if ($searchfield['enabled']) {
    - 			if ($searchfield['search'])	{ ?>
    -  				<td class="liste_titre" align="<?php echo $searchfield['align']; ?>"><input class="flat" type="text" name="s<?php echo $searchfield['alias']; ?>" value=""></td>
    -	<?php } else if ($key == $num) {
    -        print '<td class="liste_titre" align="right">';
    -        $searchpicto=$form->showFilterAndCheckAddButtons(0);
    -        print $searchpicto;
    -        print '</td>';
    - 			} else { ?>
    -  			<td class="liste_titre">&nbsp;</td>
    - 	<?php } } } ?>
    -</tr>
    -
    -<!-- FIELDS DATA -->
    -
    -<?php
    -foreach($datas as $line) {
    -		?>
    -	<tr class="oddeven">
    -   		<?php
    -   		foreach($line as $key => $value) {
    -   			foreach($fieldlist as $field) {
    -   				if ($field['alias'] == $key) { ?>
    -   					<td align="<?php echo $field['align']; ?>"><?php echo $value; ?></td>
    -   		<?php } } } ?>
    -   	</tr>
    -<?php } ?>
    -
    -</table>
    -</form>
    -
    -<!-- END PHP TEMPLATE -->
    \ No newline at end of file
    diff --git a/htdocs/product/card.php b/htdocs/product/card.php
    index 1fe43240305..31d2d7509c9 100644
    --- a/htdocs/product/card.php
    +++ b/htdocs/product/card.php
    @@ -112,7 +112,7 @@ if (! empty($canvas))
     // Security check
     $fieldvalue = (! empty($id) ? $id : (! empty($ref) ? $ref : ''));
     $fieldtype = (! empty($id) ? 'rowid' : 'ref');
    -$result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype,$objcanvas);
    +$result=restrictedArea($user,'produit|service',$fieldvalue,'product&product','','',$fieldtype);
     
     // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
     $hookmanager->initHooks(array('productcard','globalcard'));
    @@ -477,7 +477,6 @@ if (empty($reshook))
                         $action = 'edit';
                     }
                 }
    -
             }
         }
     
    @@ -689,7 +688,7 @@ if (empty($reshook))
                     if (($result = $propal->defineBuyPrice($pu_ht, GETPOST('remise_percent'), $object->id)) < 0)
                     {
                         dol_syslog($langs->trans('FailedToGetCostPrice'));
    -                    setEventMessage($langs->trans('FailedToGetCostPrice'), 'errors');
    +                    setEventMessages($langs->trans('FailedToGetCostPrice'), null, 'errors');
                     }
                     else
                     {
    @@ -732,7 +731,7 @@ if (empty($reshook))
                     if (($result = $commande->defineBuyPrice($pu_ht, GETPOST('remise_percent'), $object->id)) < 0)
                     {
                         dol_syslog($langs->trans('FailedToGetCostPrice'));
    -                    setEventMessage($langs->trans('FailedToGetCostPrice'), 'errors');
    +                    setEventMessages($langs->trans('FailedToGetCostPrice'), null, 'errors');
                     }
                     else
                     {
    @@ -775,7 +774,7 @@ if (empty($reshook))
                     if (($result = $facture->defineBuyPrice($pu_ht, GETPOST('remise_percent'), $object->id)) < 0)
                     {
                         dol_syslog($langs->trans('FailedToGetCostPrice'));
    -                    setEventMessage($langs->trans('FailedToGetCostPrice'), 'errors');
    +                    setEventMessages($langs->trans('FailedToGetCostPrice'), null, 'errors');
                     }
                     else
                     {
    @@ -977,7 +976,7 @@ else
     	        }
     	        require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php';
                 $formbarcode = new FormBarCode($db);
    -	        print $formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1);
    +            print $formbarcode->selectBarcodeType($fk_barcode_type, 'fk_barcode_type', 1);
     	        print '</td><td>'.$langs->trans("BarcodeValue").'</td><td>';
     	        $tmpcode=isset($_POST['barcode'])?GETPOST('barcode'):$object->barcode;
     	        if (empty($tmpcode) && ! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type);
    @@ -1067,11 +1066,14 @@ else
                     print $formproduct->select_measuring_units("surface_units","surface");
                     print '</td></tr>';
                 }
    -            // Volume
    -            print '<tr><td>'.$langs->trans("Volume").'</td><td colspan="3">';
    -            print '<input name="volume" size="4" value="'.GETPOST('volume').'">';
    -            print $formproduct->select_measuring_units("volume_units","volume");
    -            print '</td></tr>';
    +            if (empty($conf->global->PRODUCT_DISABLE_VOLUME))
    +            {
    +                // Volume
    +                print '<tr><td>'.$langs->trans("Volume").'</td><td colspan="3">';
    +                print '<input name="volume" size="4" value="'.GETPOST('volume').'">';
    +                print $formproduct->select_measuring_units("volume_units","volume");
    +                print '</td></tr>';
    +            }
             }
     
             // Units
    @@ -1340,7 +1342,7 @@ else
     		        }
     		        require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php';
     	            $formbarcode = new FormBarCode($db);
    -		        print $formbarcode->select_barcode_type($fk_barcode_type, 'fk_barcode_type', 1);
    +                print $formbarcode->selectBarcodeType($fk_barcode_type, 'fk_barcode_type', 1);
     		        print '</td><td>'.$langs->trans("BarcodeValue").'</td><td>';
     		        $tmpcode=isset($_POST['barcode'])?GETPOST('barcode'):$object->barcode;
     		        if (empty($tmpcode) && ! empty($modBarCodeProduct->code_auto)) $tmpcode=$modBarCodeProduct->getNextValue($object,$type);
    @@ -1636,7 +1638,7 @@ else
     				}
                     if ($action == 'editbarcodetype')
                     {
    -                    $formbarcode->form_barcode_type($_SERVER['PHP_SELF'].'?id='.$object->id,$object->barcode_type,'fk_barcode_type');
    +                    print $formbarcode->formBarcodeType($_SERVER['PHP_SELF'].'?id='.$object->id, $object->barcode_type, 'fk_barcode_type');
                     }
                     else
                     {
    @@ -1940,7 +1942,6 @@ else
     
                 dol_fiche_end();
             }
    -
         }
         else if ($action != 'create')
         {
    @@ -2199,6 +2200,6 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete')
         print '</div></div></div>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php
    index 8ba4eaaecc8..ce6928c7331 100644
    --- a/htdocs/product/class/api_products.class.php
    +++ b/htdocs/product/class/api_products.class.php
    @@ -102,7 +102,8 @@ class Products extends DolibarrApi
          * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.tobuy:=:0) and (t.tosell:=:1)"
          * @return array                Array of product objects
          */
    -    function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode=0, $category=0, $sqlfilters = '') {
    +    function index($sortfield = "t.ref", $sortorder = 'ASC', $limit = 100, $page = 0, $mode=0, $category=0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -340,7 +341,7 @@ class Products extends DolibarrApi
     		}
     
     		if ($result < 0) {
    -			throw new RestException(503, 'Error when retrieve category list : '.array_merge(array($categories->error), $categories->errors));  
    +			throw new RestException(503, 'Error when retrieve category list : '.array_merge(array($categories->error), $categories->errors));
     		}
     
     		return $result;
    @@ -467,7 +468,8 @@ class Products extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php
    index 6ae31645a50..5356d212c38 100644
    --- a/htdocs/product/class/html.formproduct.class.php
    +++ b/htdocs/product/class/html.formproduct.class.php
    @@ -29,8 +29,15 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
      */
     class FormProduct
     {
    -	var $db;
    -	var $error;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     	// Cache arrays
     	var $cache_warehouses=array();
    @@ -45,8 +52,6 @@ class FormProduct
     	function __construct($db)
     	{
     		$this->db = $db;
    -
    -		return 1;
     	}
     
     
    @@ -160,6 +165,7 @@ class FormProduct
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
     	 * Return full path to current warehouse in $tab (recursive function)
     	 *
    @@ -167,8 +173,9 @@ class FormProduct
     	 * @param	String	$final_label	full label with all parents, separated by ' >> ' (completed on each call)
     	 * @return	String					full label with all parents, separated by ' >> '
     	 */
    -	private function get_parent_path($tab, $final_label='') {
    -
    +    private function get_parent_path($tab, $final_label='')
    +    {
    +        //phpcs:enable
     		if(empty($final_label)) $final_label = $tab['label'];
     
     		if(empty($tab['parent_id'])) return $final_label;
    @@ -180,7 +187,6 @@ class FormProduct
     		}
     
     		return $final_label;
    -
     	}
     
     	/**
    @@ -274,6 +280,7 @@ class FormProduct
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Output a combo box with list of units
     	 *  pour l'instant on ne definit pas les unites dans la base
    @@ -286,9 +293,11 @@ class FormProduct
     	 */
     	function select_measuring_units($name='measuring_units', $measuring_style='', $default='0', $adddefault=0)
     	{
    +        //phpcs:enable
     		print $this->load_measuring_units($name, $measuring_style, $default, $adddefault);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return a combo box with list of units
     	 *  For the moment, units labels are defined in measuring_units_string
    @@ -301,6 +310,7 @@ class FormProduct
     	 */
     	function load_measuring_units($name='measuring_units', $measuring_style='', $default='0', $adddefault=0)
     	{
    +        //phpcs:enable
     		global $langs,$conf,$mysoc;
     		$langs->load("other");
     
    @@ -483,4 +493,4 @@ class FormProduct
     			}
     		}
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index c30376622a4..805d5d214a2 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4,7 +4,7 @@
      * Copyright (C) 2005-2015	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2006		Andre Cianfarani		<acianfa@free.fr>
      * Copyright (C) 2007-2011	Jean Heimburger			<jean@tiaris.info>
    - * Copyright (C) 2010-2013	Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2010-2018	Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2012       Cedric Salvador         <csalvador@gpcsolutions.fr>
      * Copyright (C) 2013-2014	Cedric GROSS			<c.gross@kreiz-it.fr>
      * Copyright (C) 2013-2016	Marcos García			<marcosgdf@gmail.com>
    @@ -43,11 +43,28 @@ require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
      */
     class Product extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='product';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='product';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_product';
    +
     	protected $childtables=array('supplier_proposaldet', 'propaldet','commandedet','facturedet','contratdet','facture_fourn_det','commande_fournisseurdet');    // To test if we can delete object
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
     
     	/**
     	 * {@inheritdoc}
    @@ -273,6 +290,9 @@ class Product extends CommonObject
     
     	public $oldcopy;
     
    +	/**
    +     * @var int ID
    +     */
         public $fk_price_expression;
     
         /* To store supplier price found */
    @@ -282,7 +302,7 @@ class Product extends CommonObject
     
     	/**
     	 * @deprecated
    -	 * @see ref_supplier
    +	 * @see $ref_supplier
     	 */
     	public $ref_fourn;
     	public $ref_supplier;
    @@ -300,6 +320,23 @@ class Product extends CommonObject
     	public $price_autogen = 0;
     
     
    +	public $fields = array(
    +		'rowid'         =>array('type'=>'integer',      'label'=>'TechnicalID',      'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'index'=>1, 'position'=>1, 'comment'=>'Id'),
    +		'ref'           =>array('type'=>'varchar(128)', 'label'=>'Ref',              'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    +		'entity'        =>array('type'=>'integer',      'label'=>'Entity',           'enabled'=>1, 'visible'=>0,  'default'=>1, 'notnull'=>1,  'index'=>1, 'position'=>20),
    +		'note_public'   =>array('type'=>'html',			'label'=>'NotePublic',		 'enabled'=>1, 'visible'=>0,  'position'=>61),
    +		'note'          =>array('type'=>'html',			'label'=>'NotePrivate',		 'enabled'=>1, 'visible'=>0,  'position'=>62),
    +		'datec'         =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>500),
    +		'tms'           =>array('type'=>'timestamp',    'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>501),
    +		//'date_valid'    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
    +		'fk_user_author'=>array('type'=>'integer',      'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>510, 'foreignkey'=>'llx_user.rowid'),
    +		'fk_user_modif' =>array('type'=>'integer',      'label'=>'UserModif',        'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511),
    +		//'fk_user_valid' =>array('type'=>'integer',      'label'=>'UserValidation',        'enabled'=>1, 'visible'=>-1, 'position'=>512),
    +		'import_key'    =>array('type'=>'varchar(14)',  'label'=>'ImportId',         'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0,  'position'=>1000),
    +		//'tosell'       =>array('type'=>'integer',      'label'=>'Status',           'enabled'=>1, 'visible'=>1,  'notnull'=>1, 'default'=>0, 'index'=>1,  'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')),
    +		//'tobuy'        =>array('type'=>'integer',      'label'=>'Status',           'enabled'=>1, 'visible'=>1,  'notnull'=>1, 'default'=>0, 'index'=>1,  'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')),
    +	);
    +
     	/**
     	 * Regular product
     	 */
    @@ -325,8 +362,6 @@ class Product extends CommonObject
     	 */
     	function __construct($db)
     	{
    -		global $langs;
    -
     		$this->db = $db;
     		$this->canvas = '';
     	}
    @@ -622,7 +657,6 @@ class Product extends CommonObject
                 dol_syslog(get_class($this)."::Create fails verify ".join(',',$this->errors), LOG_WARNING);
                 return -3;
             }
    -
     	}
     
     
    @@ -668,11 +702,12 @@ class Product extends CommonObject
             return $result;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Check barcode
          *
    -     *	@param	string	$valuetotest	Value to test
    -     *  @param	string	$typefortest	Type of barcode (ISBN, EAN, ...)
    +     *  @param  string  $valuetotest    Value to test
    +     *  @param  string  $typefortest    Type of barcode (ISBN, EAN, ...)
          *  @return int						0 if OK
          * 									-1 ErrorBadBarCodeSyntax
          * 									-2 ErrorBarCodeRequired
    @@ -680,6 +715,7 @@ class Product extends CommonObject
          */
         function check_barcode($valuetotest,$typefortest)
         {
    +        // phpcs:enable
             global $conf;
             if (! empty($conf->barcode->enabled) && ! empty($conf->global->BARCODE_PRODUCT_ADDON_NUM))
             {
    @@ -1434,6 +1470,7 @@ class Product extends CommonObject
     
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Insert a track that we changed a customer price
     	 *
    @@ -1443,6 +1480,7 @@ class Product extends CommonObject
     	 */
     	function _log_price($user,$level=0)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$now=dol_now();
    @@ -1472,6 +1510,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Delete a price line
     	 *
    @@ -1481,6 +1520,7 @@ class Product extends CommonObject
     	 */
     	function log_price_delete($user, $rowid)
     	{
    +        // phpcs:enable
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_price_by_qty";
     		$sql.= " WHERE fk_product_price=".$rowid;
     		$resql=$this->db->query($sql);
    @@ -1500,6 +1540,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Read price used by a provider.
     	 *	We enter as input couple prodfournprice/qty or triplet qty/product_id/fourn_ref.
    @@ -1514,12 +1555,13 @@ class Product extends CommonObject
     	 */
     	function get_buyprice($prodfournprice, $qty, $product_id=0, $fourn_ref='', $fk_soc=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$result = 0;
     
     		// We do a first seach with a select by searching with couple prodfournprice and qty only (later we will search on triplet qty/product_id/fourn_ref)
     		$sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.remise_percent,";
    -		$sql.= " pfp.fk_product, pfp.ref_fourn, pfp.fk_soc, pfp.tva_tx, pfp.fk_supplier_price_expression";
    +		$sql.= " pfp.fk_product, pfp.ref_fourn, pfp.desc_fourn, pfp.fk_soc, pfp.tva_tx, pfp.fk_supplier_price_expression";
     		$sql.= " ,pfp.default_vat_code";
             $sql.= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code";
     		$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
    @@ -1556,6 +1598,7 @@ class Product extends CommonObject
     				$this->fourn_socid = $obj->fk_soc;                  // Company that offer this price
     				$this->ref_fourn = $obj->ref_fourn;                 // deprecated
     				$this->ref_supplier = $obj->ref_fourn;              // Ref supplier
    +				$this->desc_supplier = $obj->desc_fourn;            // desc supplier
     				$this->remise_percent = $obj->remise_percent;       // remise percent if present and not typed
     				$this->vatrate_supplier = $obj->tva_tx;             // Vat ref supplier
     				$this->default_vat_code = $obj->default_vat_code;   // Vat code supplier
    @@ -1571,7 +1614,7 @@ class Product extends CommonObject
     			{
     				// We do a second search by doing a select again but searching with less reliable criteria: couple qty/id product, and if set fourn_ref or fk_soc.
     				$sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.fk_soc,";
    -				$sql.= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.tva_tx, pfp.fk_supplier_price_expression";
    +				$sql.= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.desc_fourn as desc_supplier, pfp.tva_tx, pfp.fk_supplier_price_expression";
     				$sql.= " ,pfp.default_vat_code";
                     $sql.= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code";
     				$sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp";
    @@ -1612,6 +1655,7 @@ class Product extends CommonObject
     						$this->fourn_socid = $obj->fk_soc;                  // Company that offer this price
     						$this->ref_fourn = $obj->ref_supplier;              // deprecated
     						$this->ref_supplier = $obj->ref_supplier;           // Ref supplier
    +						$this->desc_supplier = $obj->desc_supplier;         // desc supplier
     						$this->remise_percent = $obj->remise_percent;       // remise percent if present and not typed
     						$this->vatrate_supplier = $obj->tva_tx;             // Vat ref supplier
     						$this->default_vat_code = $obj->default_vat_code;   // Vat code supplier
    @@ -2199,6 +2243,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats propale pour le produit/service
     	 *
    @@ -2207,6 +2252,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_propale($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2242,6 +2288,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats propale pour le produit/service
     	 *
    @@ -2250,6 +2297,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_proposal_supplier($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2285,6 +2333,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats commande client pour le produit/service
     	 *
    @@ -2295,6 +2344,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_commande($socid=0,$filtrestatut='', $forVirtualStock = 0)
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		$sql = "SELECT COUNT(DISTINCT c.fk_soc) as nb_customers, COUNT(DISTINCT c.rowid) as nb,";
    @@ -2337,7 +2387,6 @@ class Product extends CommonObject
     							$this->stats_commande['nb']+=$pFather->stats_commande['nb'];
     							$this->stats_commande['rows']+=$pFather->stats_commande['rows'];
     							$this->stats_commande['qty']+=$pFather->stats_commande['qty'] * $qtyCoef;
    -
     						}
     					}
     				}
    @@ -2381,6 +2430,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats commande fournisseur pour le produit/service
     	 *
    @@ -2391,6 +2441,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_commande_fournisseur($socid=0,$filtrestatut='', $forVirtualStock = 0)
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		$sql = "SELECT COUNT(DISTINCT c.fk_soc) as nb_suppliers, COUNT(DISTINCT c.rowid) as nb,";
    @@ -2424,6 +2475,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats expedition client pour le produit/service
     	 *
    @@ -2434,6 +2486,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_sending($socid=0,$filtrestatut='', $forVirtualStock = 0)
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		$sql = "SELECT COUNT(DISTINCT e.fk_soc) as nb_customers, COUNT(DISTINCT e.rowid) as nb,";
    @@ -2471,6 +2524,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats réception fournisseur pour le produit/service
     	 *
    @@ -2481,6 +2535,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_reception($socid=0,$filtrestatut='', $forVirtualStock = 0)
     	{
    +        // phpcs:enable
     		global $conf,$user;
     
     		$sql = "SELECT COUNT(DISTINCT cf.fk_soc) as nb_customers, COUNT(DISTINCT cf.rowid) as nb,";
    @@ -2514,14 +2569,16 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats contrat pour le produit/service
     	 *
    -	 *  @param    int	$socid      Id societe
    +	 *  @param    int   $socid      Id societe
     	 *  @return   array       		Tableau des stats
     	 */
     	function load_stats_contrat($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2556,6 +2613,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats facture pour le produit/service
     	 *
    @@ -2564,6 +2622,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_facture($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2598,6 +2657,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge tableau des stats facture pour le produit/service
     	 *
    @@ -2606,6 +2666,7 @@ class Product extends CommonObject
     	 */
     	function load_stats_facture_fournisseur($socid=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2640,6 +2701,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return an array formated for showing graphs
     	 *
    @@ -2650,6 +2712,7 @@ class Product extends CommonObject
     	 */
     	function _get_stats($sql, $mode, $year=0)
     	{
    +        // phpcs:enable
     		$resql = $this->db->query($sql);
     		if ($resql)
     		{
    @@ -2704,6 +2767,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return nb of units or customers invoices in which product is included
     	 *
    @@ -2716,6 +2780,7 @@ class Product extends CommonObject
     	 */
     	function get_nb_vente($socid, $mode, $filteronproducttype=-1, $year=0, $morefilter='')
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2740,6 +2805,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return nb of units or supplier invoices in which product is included
     	 *
    @@ -2752,6 +2818,7 @@ class Product extends CommonObject
     	 */
     	function get_nb_achat($socid, $mode, $filteronproducttype=-1, $year=0, $morefilter='')
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2775,6 +2842,7 @@ class Product extends CommonObject
     		return $this->_get_stats($sql,$mode, $year);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return nb of units or proposals in which product is included
     	 *
    @@ -2787,6 +2855,7 @@ class Product extends CommonObject
     	 */
     	function get_nb_propal($socid, $mode, $filteronproducttype=-1, $year=0, $morefilter='')
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2810,6 +2879,7 @@ class Product extends CommonObject
     		return $this->_get_stats($sql,$mode, $year);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return nb of units or proposals in which product is included
     	 *
    @@ -2822,6 +2892,7 @@ class Product extends CommonObject
     	 */
     	function get_nb_propalsupplier($socid, $mode, $filteronproducttype=-1, $year=0, $morefilter='')
     	{
    +        // phpcs:enable
     		global $conf;
     		global $user;
     
    @@ -2845,6 +2916,7 @@ class Product extends CommonObject
     		return $this->_get_stats($sql,$mode, $year);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return nb of units or orders in which product is included
     	 *
    @@ -2857,6 +2929,7 @@ class Product extends CommonObject
     	 */
     	function get_nb_order($socid, $mode, $filteronproducttype=-1, $year=0, $morefilter='')
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		$sql = "SELECT sum(d.qty), date_format(c.date_commande, '%Y%m')";
    @@ -2879,6 +2952,7 @@ class Product extends CommonObject
     		return $this->_get_stats($sql,$mode, $year);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return nb of units or orders in which product is included
     	 *
    @@ -2891,6 +2965,7 @@ class Product extends CommonObject
     	 */
     	function get_nb_ordersupplier($socid, $mode, $filteronproducttype=-1, $year=0, $morefilter='')
     	{
    +        // phpcs:enable
     		global $conf, $user;
     
     		$sql = "SELECT sum(d.qty), date_format(c.date_commande, '%Y%m')";
    @@ -2913,6 +2988,7 @@ class Product extends CommonObject
     		return $this->_get_stats($sql,$mode, $year);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Link a product/service to a parent product/service
     	 *
    @@ -2924,6 +3000,7 @@ class Product extends CommonObject
     	 */
     	function add_sousproduit($id_pere, $id_fils, $qty, $incdec=1)
     	{
    +        // phpcs:enable
     		// Clean parameters
     		if (! is_numeric($id_pere)) $id_pere=0;
     		if (! is_numeric($id_fils)) $id_fils=0;
    @@ -2969,6 +3046,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Modify composed product
     	 *
    @@ -2980,6 +3058,7 @@ class Product extends CommonObject
     	 */
     	function update_sousproduit($id_pere, $id_fils, $qty, $incdec=1)
     	{
    +        // phpcs:enable
     		// Clean parameters
     		if (! is_numeric($id_pere)) $id_pere=0;
     		if (! is_numeric($id_fils)) $id_fils=0;
    @@ -3000,9 +3079,9 @@ class Product extends CommonObject
     		{
     			return 1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Retire le lien entre un sousproduit et un produit/service
     	 *
    @@ -3012,6 +3091,7 @@ class Product extends CommonObject
     	 */
     	function del_sousproduit($fk_parent, $fk_child)
     	{
    +        // phpcs:enable
     		if (! is_numeric($fk_parent)) $fk_parent=0;
     		if (! is_numeric($fk_child)) $fk_child=0;
     
    @@ -3029,15 +3109,17 @@ class Product extends CommonObject
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Verifie si c'est un sous-produit
     	 *
    -	 *  @param      int	$fk_parent		Id du produit auquel le produit est lie
    -	 *  @param      int	$fk_child		Id du produit lie
    +	 *  @param      int $fk_parent		Id du produit auquel le produit est lie
    +	 *  @param      int $fk_child		Id du produit lie
     	 *  @return     int			    	< 0 si erreur, > 0 si ok
     	 */
     	function is_sousproduit($fk_parent, $fk_child)
     	{
    +        // phpcs:enable
     		$sql = "SELECT fk_product_pere, qty, incdec";
     		$sql.= " FROM ".MAIN_DB_PREFIX."product_association";
     		$sql.= " WHERE fk_product_pere  = '".$fk_parent."'";
    @@ -3069,6 +3151,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Add a supplier price for the product.
     	 *  Note: Duplicate ref is accepted for different quantity only, or for different companies.
    @@ -3081,6 +3164,7 @@ class Product extends CommonObject
     	 */
     	function add_fournisseur($user, $id_fourn, $ref_fourn, $quantity)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$now=dol_now();
    @@ -3173,6 +3257,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoie la liste des fournisseurs du produit/service
     	 *
    @@ -3180,6 +3265,7 @@ class Product extends CommonObject
     	 */
     	function list_suppliers()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$list = array();
    @@ -3205,15 +3291,17 @@ class Product extends CommonObject
     		return $list;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Recopie les prix d'un produit/service sur un autre
     	 *
     	 *  @param	int		$fromId     Id product source
     	 *  @param  int		$toId       Id product target
    -	 *  @return nt         			< 0 if KO, > 0 if OK
    +	 *  @return int         			< 0 if KO, > 0 if OK
     	 */
     	function clone_price($fromId, $toId)
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		// les prix
    @@ -3233,6 +3321,7 @@ class Product extends CommonObject
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Clone links between products
     	 *
    @@ -3242,6 +3331,7 @@ class Product extends CommonObject
     	 */
     	function clone_associations($fromId, $toId)
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_association (fk_product_pere, fk_product_fils, qty)';
    @@ -3259,6 +3349,7 @@ class Product extends CommonObject
     		return 1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Recopie les fournisseurs et prix fournisseurs d'un produit/service sur un autre
     	 *
    @@ -3268,6 +3359,7 @@ class Product extends CommonObject
     	 */
     	function clone_fournisseurs($fromId, $toId)
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		$now=dol_now();
    @@ -3306,6 +3398,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Fonction recursive uniquement utilisee par get_arbo_each_prod, recompose l'arborescence des sousproduits
     	 * 	Define value of this->res
    @@ -3319,6 +3412,7 @@ class Product extends CommonObject
     	 */
     	function fetch_prod_arbo($prod, $compl_path="", $multiply=1, $level=1, $id_parent=0)
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$product = new Product($this->db);
    @@ -3365,6 +3459,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Build the tree of subproducts into an array
     	 *  this->sousprods is loaded by this->get_sousproduits_arbo()
    @@ -3374,6 +3469,7 @@ class Product extends CommonObject
     	 */
     	function get_arbo_each_prod($multiply=1)
     	{
    +        // phpcs:enable
     		$this->res = array();
     		if (isset($this->sousprods) && is_array($this->sousprods))
     		{
    @@ -3391,7 +3487,7 @@ class Product extends CommonObject
     	 *
     	 *  @return 	int			Nb of father + child
     	 */
    -	function hasFatherOrChild()
    +	public function hasFatherOrChild()
     	{
     		$nb = 0;
     
    @@ -3412,12 +3508,60 @@ class Product extends CommonObject
     		return $nb;
     	}
     
    +	/**
    +	 * Return if a product has variants or not
    +	 *
    +	 * @return 	int		Number of variants
    +	 */
    +	public function hasVariants()
    +	{
    +		$nb = 0;
    +		$sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".$this->id;
    +		$sql.= " AND entity IN (".getEntity('product').")";
    +
    +		$resql = $this->db->query($sql);
    +		if ($resql) {
    +			$obj = $this->db->fetch_object($resql);
    +			if ($obj) $nb = $obj->nb;
    +		}
    +
    +		return $nb;
    +	}
    +
    +
    +	/**
    +	 * Return if loaded product is a variant
    +	 *
    +	 * @return int
    +	 */
    +	public function isVariant()
    +	{
    +		global $conf;
    +		if (!empty($conf->variants->enabled)) {
    +			$sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product_attribute_combination WHERE fk_product_child = " . $this->id . " AND entity IN (" . getEntity('product') . ")";
    +
    +			$query = $this->db->query($sql);
    +
    +			if ($query) {
    +				if (!$this->db->num_rows($query)) {
    +					return false;
    +				}
    +				return true;
    +			} else {
    +				dol_print_error($this->db);
    +				return -1;
    +			}
    +		} else {
    +			return false;
    +		}
    +	}
    +
     	/**
     	 *  Return all parent products for current product (first level only)
     	 *
     	 *  @return 	array 		Array of product
     	 */
    -	function getFather()
    +	public function getFather()
     	{
     		$sql = "SELECT p.rowid, p.label as label, p.ref as ref, pa.fk_product_pere as id, p.fk_product_type, pa.qty, pa.incdec, p.entity";
     		$sql.= " FROM ".MAIN_DB_PREFIX."product_association as pa,";
    @@ -3458,7 +3602,7 @@ class Product extends CommonObject
     	 *  @param		int		$level				Level of recursing call (start to 1)
     	 *  @return     array       				Return array(prodid=>array(0=prodid, 1=>qty, 2=> ...)
     	 */
    -	function getChildsArbo($id, $firstlevelonly=0, $level=1)
    +	public function getChildsArbo($id, $firstlevelonly=0, $level=1)
     	{
     		global $alreadyfound;
     
    @@ -3515,6 +3659,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Return tree of all subproducts for product. Tree contains id, name and quantity.
     	 * 	Set this->sousprods
    @@ -3523,6 +3668,7 @@ class Product extends CommonObject
     	 */
     	function get_sousproduits_arbo()
     	{
    +        // phpcs:enable
     	    $parent=array();
     
     		foreach($this->getChildsArbo($this->id) as $keyChild => $valueChild)	// Warning. getChildsArbo can call getChildsArbo recursively. Starting point is $value[0]=id of product
    @@ -3544,7 +3690,7 @@ class Product extends CommonObject
          *  @param      int     $save_lastsearch_value		-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
     	 *	@return		string								String with URL
     	 */
    -	function getNomUrl($withpicto=0, $option='', $maxlength=0, $save_lastsearch_value=-1)
    +	public function getNomUrl($withpicto=0, $option='', $maxlength=0, $save_lastsearch_value=-1)
     	{
     		global $conf, $langs, $hookmanager;
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
    @@ -3576,10 +3722,10 @@ class Product extends CommonObject
                     $label.="<br><b>".$langs->trans("ManageLotSerial").'</b>: '.$this->getLibStatut(0,2);
                 }
             }
    -        if ($this->type == Product::TYPE_SERVICE)
    -        {
    +        //if ($this->type == Product::TYPE_SERVICE)
    +        //{
                 //
    -        }
    +        //}
             if (! empty($conf->accounting->enabled) && $this->status)
             {
             	include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
    @@ -3643,7 +3789,7 @@ class Product extends CommonObject
             $result.=$linkstart;
     		if ($withpicto) {
     			if ($this->type == Product::TYPE_PRODUCT) $result.=(img_object(($notooltip?'':$label), 'product', ($notooltip?'class="paddingright"':'class="paddingright classfortooltip"'), 0, 0, $notooltip?0:1));
    -			if ($this->type == Product::TYPE_SERVICE) $result.=(img_object(($notooltip?'':$label), 'service',  ($notooltip?'class="paddinright"':'class="paddingright classfortooltip"'), 0, 0, $notooltip?0:1));
    +			if ($this->type == Product::TYPE_SERVICE) $result.=(img_object(($notooltip?'':$label), 'service', ($notooltip?'class="paddinright"':'class="paddingright classfortooltip"'), 0, 0, $notooltip?0:1));
     		}
     		$result.= $newref;
     		$result.= $linkend;
    @@ -3700,7 +3846,7 @@ class Product extends CommonObject
     	 *	@param      int	$type       0=Sell, 1=Buy, 2=Batch Number management
     	 *	@return     string      	Label of status
     	 */
    -	function getLibStatut($mode=0, $type=0)
    +	public function getLibStatut($mode=0, $type=0)
     	{
     		switch ($type)
     		{
    @@ -3716,6 +3862,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return label of a given status
     	 *
    @@ -3726,6 +3873,7 @@ class Product extends CommonObject
     	 */
     	function LibStatut($status,$mode=0,$type=0)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		$langs->load('products');
    @@ -3758,37 +3906,37 @@ class Product extends CommonObject
     		if ($mode == 0)
     		{
     			if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort'));
    -			if ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort'));
    +			elseif ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort'));
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSell'):$langs->trans('ProductStatusNotOnBuy'));
    -			if ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy'));
    +			elseif ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy'));
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 0) return img_picto($langs->trans('ProductStatusNotOnSell'),'statut5', 'class="pictostatus"').' '.($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort'));
    -			if ($status == 1) return img_picto($langs->trans('ProductStatusOnSell'),'statut4', 'class="pictostatus"').' '.($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort'));
    +			elseif ($status == 1) return img_picto($langs->trans('ProductStatusOnSell'),'statut4', 'class="pictostatus"').' '.($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort'));
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 0) return img_picto(($type==0 ? $langs->trans('ProductStatusNotOnSell') : $langs->trans('ProductStatusNotOnBuy')),'statut5', 'class="pictostatus"');
    -			if ($status == 1) return img_picto(($type==0 ? $langs->trans('ProductStatusOnSell') : $langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"');
    +			elseif ($status == 1) return img_picto(($type==0 ? $langs->trans('ProductStatusOnSell') : $langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 0) return img_picto($langs->trans('ProductStatusNotOnSell'),'statut5', 'class="pictostatus"').' '.($type==0 ? $langs->trans('ProductStatusNotOnSell'):$langs->trans('ProductStatusNotOnBuy'));
    -			if ($status == 1) return img_picto($langs->trans('ProductStatusOnSell'),'statut4', 'class="pictostatus"').' '.($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy'));
    +			elseif ($status == 1) return img_picto($langs->trans('ProductStatusOnSell'),'statut4', 'class="pictostatus"').' '.($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy'));
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusNotOnSell'):$langs->trans('ProductStatusNotOnBuy')), 'statut5', 'class="pictostatus"');
    -			if ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"');
    +			elseif ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 0) return ($type==0 ? $langs->trans('ProductStatusNotOnSellShort'):$langs->trans('ProductStatusNotOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusNotOnSell'):$langs->trans('ProductStatusNotOnBuy')), 'statut5', 'class="pictostatus"');
    -			if ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"');
    +			elseif ($status == 1) return ($type==0 ? $langs->trans('ProductStatusOnSellShort'):$langs->trans('ProductStatusOnBuyShort')).' '.img_picto(($type==0 ? $langs->trans('ProductStatusOnSell'):$langs->trans('ProductStatusOnBuy')),'statut4', 'class="pictostatus"');
     		}
     		return $langs->trans('Unknown');
     	}
    @@ -3810,6 +3958,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Adjust stock in a warehouse for product
     	 *
    @@ -3826,6 +3975,7 @@ class Product extends CommonObject
     	 */
     	function correct_stock($user, $id_entrepot, $nbpiece, $movement, $label='', $price=0, $inventorycode='', $origin_element='', $origin_id=null)
     	{
    +        // phpcs:enable
     		if ($id_entrepot)
     		{
     			$this->db->begin();
    @@ -3855,6 +4005,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Adjust stock in a warehouse for product with batch number
     	 *
    @@ -3874,6 +4025,7 @@ class Product extends CommonObject
     	 */
     	function correct_stock_batch($user, $id_entrepot, $nbpiece, $movement, $label='', $price=0, $dlc='', $dluo='',$lot='', $inventorycode='', $origin_element='', $origin_id=null)
     	{
    +        // phpcs:enable
     		if ($id_entrepot)
     		{
     			$this->db->begin();
    @@ -3903,6 +4055,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Load information about stock of a product into ->stock_reel, ->stock_warehouse[] (including stock_warehouse[idwarehouse]->detail_batch for batch products)
     	 *    This function need a lot of load. If you use it on list, use a cache to execute it once for each product id.
    @@ -3915,10 +4068,11 @@ class Product extends CommonObject
     	 *										'warehouseclosed' = Load stock from closed warehouses only,
     	 *										'warehouseinternal' = Load stock from warehouses for internal correction/transfer only
     	 *    @return     int                   < 0 if KO, > 0 if OK
    -	 *    @see		  load_virtual_stock, getBatchInfo
    +	 *    @see		  load_virtual_stock(), loadBatchInfo()
     	 */
     	function load_stock($option='')
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$this->stock_reel = 0;
    @@ -3983,66 +4137,80 @@ class Product extends CommonObject
     		}
     	}
     
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Load value ->stock_theorique of a product. Property this->id must be defined.
     	 *    This function need a lot of load. If you use it on list, use a cache to execute it one for each product id.
     	 *
     	 *    @return   int             < 0 if KO, > 0 if OK
    -	 *    @see		load_stock, getBatchInfo
    +	 *    @see		load_stock(), loadBatchInfo()
     	 */
    -    function load_virtual_stock()
    -    {
    -        global $conf;
    +	function load_virtual_stock()
    +	{
    +		// phpcs:enable
    +		global $conf, $hookmanager, $action;
     
    -        $stock_commande_client=0;
    -        $stock_commande_fournisseur=0;
    -        $stock_sending_client=0;
    -        $stock_reception_fournisseur=0;
    +		$stock_commande_client=0;
    +		$stock_commande_fournisseur=0;
    +		$stock_sending_client=0;
    +		$stock_reception_fournisseur=0;
     
    -        if (! empty($conf->commande->enabled))
    -        {
    -            $result=$this->load_stats_commande(0,'1,2', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_commande_client=$this->stats_commande['qty'];
    -        }
    -        if (! empty($conf->expedition->enabled))
    -        {
    -            $result=$this->load_stats_sending(0,'1,2', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_sending_client=$this->stats_expedition['qty'];
    -        }
    -        if (! empty($conf->fournisseur->enabled))
    -        {
    -            $result=$this->load_stats_commande_fournisseur(0,'1,2,3,4', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_commande_fournisseur=$this->stats_commande_fournisseur['qty'];
    +		if (! empty($conf->commande->enabled))
    +		{
    +			$result=$this->load_stats_commande(0,'1,2', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_commande_client=$this->stats_commande['qty'];
    +		}
    +		if (! empty($conf->expedition->enabled))
    +		{
    +			$result=$this->load_stats_sending(0,'1,2', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_sending_client=$this->stats_expedition['qty'];
    +		}
    +		if (! empty($conf->fournisseur->enabled))
    +		{
    +			$result=$this->load_stats_commande_fournisseur(0,'1,2,3,4', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_commande_fournisseur=$this->stats_commande_fournisseur['qty'];
     
    -            $result=$this->load_stats_reception(0,'4', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_reception_fournisseur=$this->stats_reception['qty'];
    -        }
    +			$result=$this->load_stats_reception(0,'4', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_reception_fournisseur=$this->stats_reception['qty'];
    +		}
     
    -        // Stock decrease mode
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) {
    -            $this->stock_theorique=$this->stock_reel-$stock_commande_client+$stock_sending_client;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)) {
    -            $this->stock_theorique=$this->stock_reel;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
    -            $this->stock_theorique=$this->stock_reel-$stock_commande_client;
    -        }
    -        // Stock Increase mode
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
    -            $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) {
    -            $this->stock_theorique-=$stock_reception_fournisseur;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) {
    -            $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    -        }
    -    }
    +		// Stock decrease mode
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) {
    +			$this->stock_theorique=$this->stock_reel-$stock_commande_client+$stock_sending_client;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)) {
    +			$this->stock_theorique=$this->stock_reel;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
    +			$this->stock_theorique=$this->stock_reel-$stock_commande_client;
    +		}
    +		// Stock Increase mode
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
    +			$this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) {
    +			$this->stock_theorique-=$stock_reception_fournisseur;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) {
    +			$this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    +		}
    +
    +		if (! is_object($hookmanager)) {
    +			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    +			$hookmanager=new HookManager($this->db);
    +		}
    +		$hookmanager->initHooks(array('productdao'));
    +		$parameters=array('id'=>$this->id);
    +		// Note that $action and $object may have been modified by some hooks
    +		$reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action);
    +		if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique'];
    +
    +		return 1;
    +	}
     
     
     	/**
    @@ -4050,7 +4218,7 @@ class Product extends CommonObject
     	 *
     	 *	@param		string		$batch		Lot/serial number
     	 *  @return     array					Array with record into product_batch
    -	 *  @see		load_stock, load_virtual_stock
    +	 *  @see		load_stock(), load_virtual_stock()
     	 */
         function loadBatchInfo($batch)
         {
    @@ -4082,6 +4250,7 @@ class Product extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Move an uploaded file described into $file array into target directory $sdir.
     	 *
    @@ -4091,6 +4260,7 @@ class Product extends CommonObject
     	 */
     	function add_photo($sdir, $file)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -4123,6 +4293,7 @@ class Product extends CommonObject
     		else return -1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return if at least one photo is available
     	 *
    @@ -4131,6 +4302,7 @@ class Product extends CommonObject
     	 */
     	function is_photo_available($sdir)
     	{
    +        // phpcs:enable
     	    include_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php';
     	    include_once DOL_DOCUMENT_ROOT .'/core/lib/images.lib.php';
     
    @@ -4159,6 +4331,7 @@ class Product extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Retourne tableau de toutes les photos du produit
     	 *
    @@ -4168,6 +4341,7 @@ class Product extends CommonObject
     	 */
     	function liste_photos($dir,$nbmax=0)
     	{
    +        // phpcs:enable
     	    include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     	    include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
     
    @@ -4214,6 +4388,7 @@ class Product extends CommonObject
     		return $tabobj;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Efface la photo du produit et sa vignette
     	 *
    @@ -4222,6 +4397,7 @@ class Product extends CommonObject
     	 */
     	function delete_photo($file)
     	{
    +        // phpcs:enable
     	    require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     	    require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
     
    @@ -4249,6 +4425,7 @@ class Product extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load size of image file
     	 *
    @@ -4257,12 +4434,14 @@ class Product extends CommonObject
     	 */
     	function get_image_size($file)
     	{
    +        // phpcs:enable
     		$file_osencoded=dol_osencode($file);
     		$infoImg = getimagesize($file_osencoded); // Get information on image
     		$this->imgWidth = $infoImg[0]; // Largeur de l'image
     		$this->imgHeight = $infoImg[1]; // Hauteur de l'image
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Load indicators this->nb for the dashboard
     	 *
    @@ -4270,6 +4449,7 @@ class Product extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf, $user, $hookmanager;
     
     		$this->nb=array();
    @@ -4325,6 +4505,7 @@ class Product extends CommonObject
     		return ($this->type == Product::TYPE_SERVICE ? true : false);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Get a barcode from the module to generate barcode values.
          *  Return value is stored into this->barcode
    @@ -4335,6 +4516,7 @@ class Product extends CommonObject
          */
         function get_barcode($object,$type='')
         {
    +        // phpcs:enable
             global $conf;
     
             $result='';
    @@ -4453,13 +4635,15 @@ class Product extends CommonObject
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          * Return minimum product recommended price
          *
    -	 * @return	int			Minimum recommanded price that is higher price among all suppliers * PRODUCT_MINIMUM_RECOMMENDED_PRICE
    +     * @return  int			Minimum recommanded price that is higher price among all suppliers * PRODUCT_MINIMUM_RECOMMENDED_PRICE
          */
     	function min_recommended_price()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$maxpricesupplier=0;
    @@ -4496,8 +4680,10 @@ class Product extends CommonObject
     	 * Existing categories are left untouch.
     	 *
     	 * @param int[]|int $categories Category or categories IDs
    +     * @return void
     	 */
    -	public function setCategories($categories) {
    +    public function setCategories($categories)
    +    {
     		// Handle single category
     		if (! is_array($categories)) {
     			$categories = array($categories);
    @@ -4628,52 +4814,50 @@ class Product extends CommonObject
     		}
     	}
     
    -    /**
    -     *  Load information for tab info
    -     *
    -     *  @param  int		$id     Id of thirdparty to load
    -     *  @return	void
    -     */
    -    function info($id)
    -    {
    -        $sql = "SELECT p.rowid, p.ref, p.datec as date_creation, p.tms as date_modification,";
    -        $sql.= " p.fk_user_author, p.fk_user_modif";
    -        $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p";
    -        $sql.= " WHERE p.rowid = ".$id;
    +	/**
    +	 *  Load information for tab info
    +	 *
    +	 *  @param  int		$id     Id of thirdparty to load
    +	 *  @return	void
    +	 */
    +	function info($id)
    +	{
    +		$sql = "SELECT p.rowid, p.ref, p.datec as date_creation, p.tms as date_modification,";
    +		$sql.= " p.fk_user_author, p.fk_user_modif";
    +		$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p";
    +		$sql.= " WHERE p.rowid = ".$id;
     
    -        $result=$this->db->query($sql);
    -        if ($result)
    -        {
    -            if ($this->db->num_rows($result))
    -            {
    -                $obj = $this->db->fetch_object($result);
    -
    -                $this->id = $obj->rowid;
    -
    -                if ($obj->fk_user_author) {
    -                    $cuser = new User($this->db);
    -                    $cuser->fetch($obj->fk_user_author);
    -                    $this->user_creation     = $cuser;
    -                }
    -
    -                if ($obj->fk_user_modif) {
    -                    $muser = new User($this->db);
    -                    $muser->fetch($obj->fk_user_modif);
    -                    $this->user_modification = $muser;
    -                }
    -
    -                $this->ref			     = $obj->ref;
    -                $this->date_creation     = $this->db->jdate($obj->date_creation);
    -                $this->date_modification = $this->db->jdate($obj->date_modification);
    -            }
    -
    -            $this->db->free($result);
    -
    -        }
    -        else
    +		$result=$this->db->query($sql);
    +		if ($result)
     		{
    -            dol_print_error($this->db);
    -        }
    -    }
    +			if ($this->db->num_rows($result))
    +			{
    +				$obj = $this->db->fetch_object($result);
     
    +				$this->id = $obj->rowid;
    +
    +				if ($obj->fk_user_author) {
    +					$cuser = new User($this->db);
    +					$cuser->fetch($obj->fk_user_author);
    +					$this->user_creation     = $cuser;
    +				}
    +
    +				if ($obj->fk_user_modif) {
    +					$muser = new User($this->db);
    +					$muser->fetch($obj->fk_user_modif);
    +					$this->user_modification = $muser;
    +				}
    +
    +				$this->ref			     = $obj->ref;
    +				$this->date_creation     = $this->db->jdate($obj->date_creation);
    +				$this->date_modification = $this->db->jdate($obj->date_modification);
    +			}
    +
    +			$this->db->free($result);
    +		}
    +		else
    +		{
    +			dol_print_error($this->db);
    +		}
    +	}
     }
    diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php
    index 48afbcc9dbb..eb4fc32baed 100644
    --- a/htdocs/product/class/productbatch.class.php
    +++ b/htdocs/product/class/productbatch.class.php
    @@ -22,7 +22,7 @@
      *  \brief      Manage record and specific data for batch number management
      */
     
    -require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
    +require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
     
     
     /**
    @@ -30,16 +30,24 @@ require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
      */
     class Productbatch extends CommonObject
     {
    -	var $element='productbatch';			//!< Id that identify managed objects
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='productbatch';
    +
     	private static $_table_element='product_batch';		//!< Name of table without prefix where object is stored
     
    -	var $tms='';
    -	var $fk_product_stock;
    -	var $sellby='';
    -	var $eatby='';
    -	var $batch='';
    -	var $qty;
    +	public $tms='';
    +	public $fk_product_stock;
    +	public $sellby='';
    +	public $eatby='';
    +	public $batch='';
    +	public $qty;
     	public $warehouseid;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
     
     
    @@ -52,7 +60,6 @@ class Productbatch extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -69,7 +76,7 @@ class Productbatch extends CommonObject
     		$error=0;
     
     		// Clean parameters
    -		$this->clean_param();
    +		$this->cleanParam();
     
     		// Check parameters
     		// Put here code to add control on parameters values
    @@ -200,7 +207,7 @@ class Productbatch extends CommonObject
     		$error=0;
     
     		// Clean parameters
    -		$this->clean_param();
    +		$this->cleanParam();
     
     		// TODO Check qty is ok for stock move. Negative may not be allowed.
     		if ($this->qty < 0)
    @@ -391,16 +398,14 @@ class Productbatch extends CommonObject
     		$this->eatby='';
     		$this->batch='';
     		$this->import_key='';
    -
    -
     	}
     
     	/**
     	 *  Clean fields (triming)
     	 *
    -	 *	@return	void
    +	 *  @return	void
     	 */
    -	private function clean_param()
    +	private function cleanParam()
     	{
     		if (isset($this->fk_product_stock)) $this->fk_product_stock=(int) trim($this->fk_product_stock);
     		if (isset($this->batch)) $this->batch=trim($this->batch);
    @@ -539,5 +544,4 @@ class Productbatch extends CommonObject
                 return -1;
             }
         }
    -
     }
    diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php
    index fdff7b1fe6d..3079fef5412 100644
    --- a/htdocs/product/class/productcustomerprice.class.php
    +++ b/htdocs/product/class/productcustomerprice.class.php
    @@ -28,36 +28,62 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
      */
     class Productcustomerprice extends CommonObject
     {
    -	var $element = 'product_customer_price'; // !< Id that identify managed objects
    -	var $table_element = 'product_customer_price'; // !< Name of table without prefix where object is stored
    -	var $entity;
    -	var $datec = '';
    -	var $tms = '';
    -	var $fk_product;
    -	var $fk_soc;
    -	var $price;
    -	var $price_ttc;
    -	var $price_min;
    -	var $price_min_ttc;
    -	var $price_base_type;
    -	var $tva_tx;
    -	var $recuperableonly;
    -	var $localtax1_type;
    -	var $localtax1_tx;
    -	var $localtax2_type;
    -	var $localtax2_tx;
    -	var $fk_user;
    -	var $lines = array ();
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element = 'product_customer_price';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element = 'product_customer_price';
    +
    +	/**
    +	 * @var int Entity
    +	 */
    +	public $entity;
    +
    +	public $datec = '';
    +	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_product;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +  public $fk_soc;
    +
    +	public $price;
    +	public $price_ttc;
    +	public $price_min;
    +	public $price_min_ttc;
    +	public $price_base_type;
    +	public $tva_tx;
    +	public $recuperableonly;
    +	public $localtax1_type;
    +	public $localtax1_tx;
    +	public $localtax2_type;
    +	public $localtax2_tx;
    +
    +	/**
    +	 * @var int User ID
    +	 */
    +	public $fk_user;
    +
    +	public $lines = array ();
    +
     
     	/**
     	 * Constructor
     	 *
     	 * @param DoliDb $db handler
     	 */
    -	function __construct($db) {
    -
    +    function __construct($db)
    +    {
     		$this->db = $db;
    -		return 1;
     	}
     
     	/**
    @@ -68,7 +94,8 @@ class Productcustomerprice extends CommonObject
     	 * @param int $forceupdateaffiliate update price on each soc child
     	 * @return int <0 if KO, Id of created object if OK
     	 */
    -	function create($user, $notrigger = 0, $forceupdateaffiliate = 0) {
    +    function create($user, $notrigger = 0, $forceupdateaffiliate = 0)
    +    {
     
     		global $conf, $langs;
     		$error = 0;
    @@ -294,6 +321,7 @@ class Productcustomerprice extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load all customer prices in memory from database
     	 *
    @@ -306,6 +334,7 @@ class Productcustomerprice extends CommonObject
     	 */
     	function fetch_all($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = array())
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ( empty($sortfield)) $sortfield = "t.rowid";
    @@ -342,7 +371,7 @@ class Productcustomerprice extends CommonObject
     		$sql .= " AND prod.rowid=t.fk_product ";
     		$sql .= " AND prod.entity IN (" . getEntity('product') . ")";
     		$sql .= " AND t.entity IN (" . getEntity('productprice') . ")";
    -		
    +
     		// Manage filter
     		if (count($filter) > 0) {
     			foreach ( $filter as $key => $value ) {
    @@ -407,6 +436,7 @@ class Productcustomerprice extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load all objects in memory from database
     	 *
    @@ -419,6 +449,7 @@ class Productcustomerprice extends CommonObject
     	 */
     	function fetch_all_log($sortorder, $sortfield, $limit, $offset, $filter = array())
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if (! empty($sortfield)) $sortfield = "t.rowid";
    @@ -522,7 +553,8 @@ class Productcustomerprice extends CommonObject
     	 * @param int $forceupdateaffiliate update price on each soc child
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function update($user = 0, $notrigger = 0, $forceupdateaffiliate = 0) {
    +    function update($user = 0, $notrigger = 0, $forceupdateaffiliate = 0)
    +    {
     
     		global $conf, $langs;
     		$error = 0;
    @@ -719,7 +751,8 @@ class Productcustomerprice extends CommonObject
     	 * @param int $forceupdateaffiliate update price on each soc child
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate) {
    +    function setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate)
    +    {
     
     		$error = 0;
     
    @@ -811,7 +844,8 @@ class Productcustomerprice extends CommonObject
     	 * @param int $notrigger triggers after, 1=disable triggers
     	 * @return int <0 if KO, >0 if OK
     	 */
    -	function delete($user, $notrigger = 0) {
    +    function delete($user, $notrigger = 0)
    +    {
     
     		global $conf, $langs;
     		$error = 0;
    @@ -864,7 +898,8 @@ class Productcustomerprice extends CommonObject
     	 * @param int $fromid of object to clone
     	 * @return int id of clone
     	 */
    -	function createFromClone($fromid) {
    +    function createFromClone($fromid)
    +    {
     
     		global $user, $langs;
     
    @@ -914,7 +949,8 @@ class Productcustomerprice extends CommonObject
     	 *
     	 * @return void
     	 */
    -	function initAsSpecimen() {
    +    function initAsSpecimen()
    +    {
     
     		$this->id = 0;
     
    @@ -943,24 +979,46 @@ class Productcustomerprice extends CommonObject
      */
     class PriceByCustomerLine
     {
    -	var $id;
    -	var $entity;
    -	var $datec = '';
    -	var $tms = '';
    -	var $fk_product;
    -	var $fk_soc;
    -	var $price;
    -	var $price_ttc;
    -	var $price_min;
    -	var $price_min_ttc;
    -	var $price_base_type;
    -	var $default_vat_code;
    -	var $tva_tx;
    -	var $recuperableonly;
    -	var $localtax1_tx;
    -	var $localtax2_tx;
    -	var $fk_user;
    -	var $import_key;
    -	var $socname;
    -	var $prodref;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +	 * @var int Entity
    +	 */
    +	public $entity;
    +
    +	public $datec = '';
    +	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_product;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +    public $fk_soc;
    +
    +	public $price;
    +	public $price_ttc;
    +	public $price_min;
    +	public $price_min_ttc;
    +	public $price_base_type;
    +	public $default_vat_code;
    +	public $tva_tx;
    +	public $recuperableonly;
    +	public $localtax1_tx;
    +	public $localtax2_tx;
    +
    +	/**
    +	 * @var int User ID
    +	 */
    +	public $fk_user;
    +
    +	public $import_key;
    +	public $socname;
    +	public $prodref;
     }
    diff --git a/htdocs/product/class/propalmergepdfproduct.class.php b/htdocs/product/class/propalmergepdfproduct.class.php
    index 87fdd132878..b5d2d639ae4 100644
    --- a/htdocs/product/class/propalmergepdfproduct.class.php
    +++ b/htdocs/product/class/propalmergepdfproduct.class.php
    @@ -22,7 +22,7 @@
      *  \brief      This file is an CRUD class file (Create/Read/Update/Delete)
      */
     
    -require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
    +require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
     
     
     
    @@ -31,8 +31,15 @@ require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
      */
     class Propalmergepdfproduct extends CommonObject
     {
    -	var $element='propal_merge_pdf_product';			//!< Id that identify managed objects
    -	var $table_element='propal_merge_pdf_product';		//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='propal_merge_pdf_product';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='propal_merge_pdf_product';
     
     	var $fk_product;
     	var $file_name;
    @@ -55,7 +62,6 @@ class Propalmergepdfproduct extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -201,8 +207,6 @@ class Propalmergepdfproduct extends CommonObject
     				$this->datec = $this->db->jdate($obj->datec);
     				$this->tms = $this->db->jdate($obj->tms);
     				$this->import_key = $obj->import_key;
    -
    -
                 }
                 $this->db->free($resql);
     
    @@ -216,6 +220,7 @@ class Propalmergepdfproduct extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Load object in memory from the database
          *
    @@ -225,6 +230,7 @@ class Propalmergepdfproduct extends CommonObject
          */
         function fetch_by_product($product_id, $lang='')
         {
    +        // phpcs:enable
         	global $langs,$conf;
     
         	$sql = "SELECT";
    @@ -275,11 +281,7 @@ class Propalmergepdfproduct extends CommonObject
     	    			}else {
     	    				$this->lines[$obj->file_name]=$line;
     	    			}
    -
    -
         			}
    -
    -
         		}
         		$this->db->free($resql);
     
    @@ -313,9 +315,6 @@ class Propalmergepdfproduct extends CommonObject
     		if (isset($this->fk_user_mod)) $this->fk_user_mod=trim($this->fk_user_mod);
     		if (isset($this->lang)) $this->lang=trim($this->lang);
     
    -
    -
    -
     		// Check parameters
     		// Put here code to add a control on parameters values
     
    @@ -431,6 +430,7 @@ class Propalmergepdfproduct extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Delete object in database
     	 *
    @@ -442,6 +442,7 @@ class Propalmergepdfproduct extends CommonObject
     	 */
     	function delete_by_product($user, $product_id, $lang_id='',  $notrigger=0)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     		$error=0;
     
    @@ -495,6 +496,7 @@ class Propalmergepdfproduct extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Delete object in database
     	 *
    @@ -503,6 +505,7 @@ class Propalmergepdfproduct extends CommonObject
     	 */
     	function delete_by_file($user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     		$error=0;
     
    @@ -625,10 +628,7 @@ class Propalmergepdfproduct extends CommonObject
     		$this->datec='';
     		$this->tms='';
     		$this->import_key='';
    -
    -
     	}
    -
     }
     
     /**
    @@ -636,18 +636,38 @@ class Propalmergepdfproduct extends CommonObject
      */
     class PropalmergepdfproductLine
     {
    -	var $id;
    +	/**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    -	var $fk_product;
    -	var $file_name;
    -	var $lang;
    -	var $fk_user_author;
    -	var $fk_user_mod;
    -	var $datec='';
    -	var $tms='';
    -	var $import_key;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_product;
     
    -	function __construct() {
    -		return 1;
    -	}
    +	public $file_name;
    +	public $lang;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_mod;
    +
    +	public $datec='';
    +	public $tms='';
    +	public $import_key;
    +
    +    /**
    +     *  Constructor
    +     */
    +    function __construct()
    +    {
    +        return 1;
    +    }
     }
    diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php
    index a1cd63eea12..d2ef4210e9c 100644
    --- a/htdocs/product/composition/card.php
    +++ b/htdocs/product/composition/card.php
    @@ -407,7 +407,6 @@ if ($id > 0 || ! empty($ref))
     						{
     							print '<td align="center"><input type="text" value="'.$nb_of_subproduct.'" name="TProduct['.$productstatic->id.'][qty]" size="4" /></td>';
     							print '<td align="center"><input type="checkbox" name="TProduct['.$productstatic->id.'][incdec]" value="1" '.($value['incdec']==1?'checked':''  ).' /></td>';
    -
     						}
     						else{
     							print '<td>'.$nb_of_subproduct.'</td>';
    @@ -551,7 +550,6 @@ if ($id > 0 || ! empty($ref))
     			{
     				$num = $db->num_rows($resql);
     				$i=0;
    -				$var=true;
     
     				if($num == 0) print '<tr><td colspan="4">'.$langs->trans("NoMatchFound").'</td></tr>';
     
    @@ -635,7 +633,6 @@ if ($id > 0 || ! empty($ref))
     					}
     					$i++;
     				}
    -
     			}
     			else
     			{
    @@ -655,11 +652,9 @@ if ($id > 0 || ! empty($ref))
     
     			print '</form>';
     		}
    -
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/document.php b/htdocs/product/document.php
    index 34337218a62..d0bc7b3f9be 100644
    --- a/htdocs/product/document.php
    +++ b/htdocs/product/document.php
    @@ -113,7 +113,6 @@ if (empty($reshook))
     
     	// Action submit/delete file/link
     	include_once DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
    -
     }
     
     if ($action=='filemerge')
    @@ -197,7 +196,7 @@ if ($object->id)
         print $hookmanager->resPrint;
     	if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     
     	if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))    // For backward compatiblity, we scan also old dirs
    @@ -288,11 +287,11 @@ if ($object->id)
     
         			print  '<tr class="liste_titre"><td>';
     
    -    			$delauft_lang = empty($lang_id) ? $langs->getDefaultLang() : $lang_id;
    +    			$default_lang = empty($lang_id) ? $langs->getDefaultLang() : $lang_id;
     
         			$langs_available = $langs->get_available_languages(DOL_DOCUMENT_ROOT, 12);
     
    -			    print Form::selectarray('lang_id', $langs_available, $delauft_lang, 0, 0, 0, '', 0, 0, 0, 'ASC');
    +			    print Form::selectarray('lang_id', $langs_available, $default_lang, 0, 0, 0, '', 0, 0, 0, 'ASC');
     
         			if ($conf->global->MAIN_MULTILANGS) {
         				print  '<input type="submit" class="button" name="refresh" value="' . $langs->trans('Refresh') . '">';
    @@ -301,25 +300,18 @@ if ($object->id)
         			print  '</td></tr>';
         		}
     
    -    		$style = 'impair';
         		foreach ($filearray as $filetoadd)
         		{
         			if ($ext = pathinfo($filetoadd['name'], PATHINFO_EXTENSION) == 'pdf')
         			{
    -    				if ($style == 'pair') {
    -    					$style = 'impair';
    -    				} else {
    -    					$style = 'pair';
    -    				}
    -
         				$checked = '';
         				$filename = $filetoadd['name'];
     
         				if ($conf->global->MAIN_MULTILANGS)
         				{
    -    					if (array_key_exists($filetoadd['name'] . '_' . $delauft_lang, $filetomerge->lines))
    +    					if (array_key_exists($filetoadd['name'] . '_' . $default_lang, $filetomerge->lines))
         					{
    -    						$filename = $filetoadd['name'] . ' - ' . $langs->trans('Language_' . $delauft_lang);
    +    						$filename = $filetoadd['name'] . ' - ' . $langs->trans('Language_' . $default_lang);
         						$checked = ' checked ';
         					}
         				}
    @@ -331,7 +323,7 @@ if ($object->id)
         					}
         				}
     
    -    				print  '<tr class="' . $style . '"><td>';
    +    				print  '<tr class="oddeven"><td>';
         				print  '<input type="checkbox" ' . $checked . ' name="filetoadd[]" id="filetoadd" value="' . $filetoadd['name'] . '">' . $filename . '</input>';
         				print  '</td></tr>';
         			}
    @@ -352,6 +344,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/dynamic_price/class/price_expression.class.php b/htdocs/product/dynamic_price/class/price_expression.class.php
    index 5ce3068c144..6b73b413522 100644
    --- a/htdocs/product/dynamic_price/class/price_expression.class.php
    +++ b/htdocs/product/dynamic_price/class/price_expression.class.php
    @@ -29,12 +29,32 @@
      */
     class PriceExpression
     {
    -	var $db;							//!< To store db handler
    -	var $error;							//!< To return error code (or message)
    -	var $errors=array();				//!< To return several error codes (or messages)
    -    var $id;
    -    var $title;
    -	var $expression;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +    public $title;
    +    public $expression;
    +
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element = "c_price_expression";
     
         /**
    @@ -45,7 +65,6 @@ class PriceExpression
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -127,7 +146,7 @@ class PriceExpression
                 $this->error='ErrorWrongParameters';
                 return -1;
             }
    -        
    +
             $sql = "SELECT title, expression";
             $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element;
             $sql.= " WHERE rowid = ".$id;
    @@ -156,6 +175,7 @@ class PriceExpression
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    List all price expressions
          *
    @@ -163,6 +183,7 @@ class PriceExpression
          */
         function list_price_expression()
         {
    +        // phpcs:enable
             $sql = "SELECT rowid, title, expression";
             $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element;
             $sql.= " ORDER BY title";
    @@ -193,6 +214,7 @@ class PriceExpression
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Returns any existing rowid with specified title
          *
    @@ -201,6 +223,7 @@ class PriceExpression
          */
         function find_title($title)
         {
    +        // phpcs:enable
             $sql = "SELECT rowid";
             $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element;
             $sql.= " WHERE title = '".$this->db->escape($title)."'";
    @@ -299,7 +322,7 @@ class PriceExpression
     		$error=0;
     
     		$rowid = $this->id;
    -		
    +
     		$this->db->begin();
     
     		if (! $error)
    diff --git a/htdocs/product/dynamic_price/class/price_global_variable.class.php b/htdocs/product/dynamic_price/class/price_global_variable.class.php
    index 97a3ee1f4e6..4cd900979ab 100644
    --- a/htdocs/product/dynamic_price/class/price_global_variable.class.php
    +++ b/htdocs/product/dynamic_price/class/price_global_variable.class.php
    @@ -29,14 +29,39 @@
      */
     class PriceGlobalVariable
     {
    -    var $db;							//!< To store db handler
    -    var $error;							//!< To return error code (or message)
    -    var $errors=array();				//!< To return several error codes (or messages)
    -    var $id;
    -    var $code;
    -    var $description;
    -    var $value;
    -    public $table_element = "c_price_global_variable";
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    /**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +    public $code;
    +
    +    /**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +    public $value;
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element = "c_price_global_variable";
     
         /**
          *  Constructor
    @@ -46,7 +71,6 @@ class PriceGlobalVariable
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    diff --git a/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php b/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php
    index f4595062098..c4dda3481bb 100644
    --- a/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php
    +++ b/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php
    @@ -29,30 +29,60 @@
      */
     class PriceGlobalVariableUpdater
     {
    -    var $db;							//!< To store db handler
    -    var $error;							//!< To return error code (or message)
    -    var $errors=array();				//!< To return several error codes (or messages)
    -    var $types=array(0, 1);				//!< Updater types
    -    var $update_min = 5;				//!< Minimal update rate
    -    var $id;
    -    var $type;
    -    var $description;
    -    var $parameters;
    -    var $fk_variable;
    -    var $update_interval;				//!< Interval in mins
    -    var $next_update;					//!< Next update timestamp
    -    var $last_status;
    -    public $table_element = "c_price_global_variable_updater";
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +    /**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
    +    public $types=array(0, 1);				//!< Updater types
    +    public $update_min = 5;				//!< Minimal update rate
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +    public $type;
    +
    +    /**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +    public $parameters;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_variable;
    +
    +    public $update_interval;				//!< Interval in mins
    +    public $next_update;					//!< Next update timestamp
    +    public $last_status;
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element = "c_price_global_variable_updater";
     
         /**
          *  Constructor
          *
    -     *  @param	DoliDb		$db      Database handler
    +     *  @param  DoliDb      $db      Database handler
          */
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
     
    @@ -530,6 +560,7 @@ class PriceGlobalVariableUpdater
             return 1;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Update next_update into database
          *
    @@ -540,6 +571,7 @@ class PriceGlobalVariableUpdater
          */
         function update_next_update($next_update, $user=0, $notrigger=0)
         {
    +        // phpcs:enable
             $error=0;
     
             $this->next_update = $next_update;
    @@ -574,6 +606,7 @@ class PriceGlobalVariableUpdater
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Update last_status into database
          *
    @@ -584,6 +617,7 @@ class PriceGlobalVariableUpdater
          */
         function update_status($last_status, $user=0, $notrigger=0)
         {
    +        // phpcs:enable
             $error=0;
     
             $this->last_status = $last_status;
    diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php
    index 867a30faaeb..3249671d173 100644
    --- a/htdocs/product/dynamic_price/class/price_parser.class.php
    +++ b/htdocs/product/dynamic_price/class/price_parser.class.php
    @@ -335,4 +335,4 @@ class PriceParser
     		));
     		return $this->parseExpression($product, $expression, $extra_values);
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/product/dynamic_price/editor.php b/htdocs/product/dynamic_price/editor.php
    index 9187775f8e9..baa738c20c5 100644
    --- a/htdocs/product/dynamic_price/editor.php
    +++ b/htdocs/product/dynamic_price/editor.php
    @@ -244,5 +244,6 @@ print '<script type="text/javascript">
     	}
     </script>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php
    index 0d4563c10c1..7ad740eab0a 100644
    --- a/htdocs/product/fournisseurs.php
    +++ b/htdocs/product/fournisseurs.php
    @@ -156,6 +156,7 @@ if (empty($reshook))
     		$price_expression = GETPOST('eid', 'int') ? GETPOST('eid', 'int') : ''; // Discard expression if not in expression mode
     		$delivery_time_days = GETPOST('delivery_time_days', 'int') ? GETPOST('delivery_time_days', 'int') : '';
     		$supplier_reputation = GETPOST('supplier_reputation');
    +		$supplier_description = GETPOST('supplier_description', 'alpha');
     
     		if ($tva_tx == '')
     		{
    @@ -256,9 +257,9 @@ if (empty($reshook))
                     	$multicurrency_price = price2num(GETPOST("multicurrency_price",'alpha'));
                     	$multicurrency_code = GETPOST("multicurrency_code",'alpha');
     
    -                    $ret = $object->update_buyprice($quantity, $newprice, $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation, array(), '', $multicurrency_price, $_POST["multicurrency_price_base_type"], $multicurrency_tx, $multicurrency_code);
    +                    $ret = $object->update_buyprice($quantity, $newprice, $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation, array(), '', $multicurrency_price, $_POST["multicurrency_price_base_type"], $multicurrency_tx, $multicurrency_code, $supplier_description);
                     } else {
    -                    $ret = $object->update_buyprice($quantity, $newprice, $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation);
    +                    $ret = $object->update_buyprice($quantity, $newprice, $user, $_POST["price_base_type"], $supplier, $_POST["oselDispo"], $ref_fourn, $tva_tx, $_POST["charges"], $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation, array(), '', 0, 'HT', 1, '', $supplier_description);
                     }
     				if ($ret < 0)
     				{
    @@ -678,6 +679,23 @@ SCRIPT;
     					}
     				}
     
    +				// Product description of the supplier
    +				if (! empty($conf->global->PRODUIT_FOURN_TEXTS))
    +				{
    +				    //WYSIWYG Editor
    +				    require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    +
    +    				print '<tr>';
    +    				print '<td>'.$langs->trans('ProductSupplierDescription').'</td>';
    +    				print '<td>';
    +
    +    				$doleditor = new DolEditor('supplier_description', $object->desc_supplier, '', 160, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_PRODUCTDESC, ROWS_4, '90%');
    +    				$doleditor->Create();
    +
    +    				print '</td>';
    +    				print '</tr>';
    +				}
    +
     				if (is_object($hookmanager))
     				{
     					$parameters=array('id_fourn'=>$id_fourn,'prod_id'=>$object->id);
    @@ -765,12 +783,9 @@ SCRIPT;
     
     				if (is_array($product_fourn_list))
     				{
    -					$var=true;
     
     					foreach($product_fourn_list as $productfourn)
     					{
    -
    -
     						print '<tr class="oddeven">';
     
     						// Supplier
    @@ -880,7 +895,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/index.php b/htdocs/product/index.php
    index 9f11813fdee..2089193e208 100644
    --- a/htdocs/product/index.php
    +++ b/htdocs/product/index.php
    @@ -152,7 +152,6 @@ if (! empty($conf->product->enabled))
     	$statProducts.= '<tr class="oddeven">';
     	$statProducts.= '<td><a href="list.php?type=0&amp;tosell=1&amp;tobuy=1">'.$langs->trans("ProductsOnSellAndOnBuy").'</a></td><td align="right">'.round($prodser[0][3]).'</td>';
     	$statProducts.= "</tr>";
    -
     }
     if (! empty($conf->service->enabled))
     {
    @@ -168,7 +167,6 @@ if (! empty($conf->service->enabled))
     	$statServices.= '<tr class="oddeven">';
     	$statServices.= '<td><a href="list.php?type=1&amp;tosell=1&amp;tobuy=1">'.$langs->trans("ServicesOnSellAndOnBuy").'</a></td><td align="right">'.round($prodser[1][3]).'</td>';
     	$statServices.= "</tr>";
    -
     }
     $total=0;
     if ($type == '0')
    @@ -397,8 +395,8 @@ if (! empty($conf->global->MAIN_SHOW_PRODUCT_ACTIVITY_TRIM))
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    @@ -457,8 +455,6 @@ function activitytrim($product_type)
     		}
     		$i = 0;
     
    -		$var=true;
    -
     		while ($i < $num)
     		{
     			$objp = $db->fetch_object($result);
    @@ -466,7 +462,6 @@ function activitytrim($product_type)
     			{
     				if ($trim1+$trim2+$trim3+$trim4 > 0)
     				{
    -
     					print '<tr class="oddeven"><td align=left>'.$tmpyear.'</td>';
     					print '<td align=right>'.price($trim1).'</td>';
     					print '<td align=right>'.price($trim2).'</td>';
    @@ -500,7 +495,6 @@ function activitytrim($product_type)
     		}
     		if ($trim1+$trim2+$trim3+$trim4 > 0)
     		{
    -
     			print '<tr class="oddeven"><td align=left>'.$tmpyear.'</td>';
     			print '<td align=right>'.price($trim1).'</td>';
     			print '<td align=right>'.price($trim2).'</td>';
    diff --git a/htdocs/product/inventory/ajax/ajax.inventory.php b/htdocs/product/inventory/ajax/ajax.inventory.php
    index 4884d7ab065..56459ab7be9 100644
    --- a/htdocs/product/inventory/ajax/ajax.inventory.php
    +++ b/htdocs/product/inventory/ajax/ajax.inventory.php
    @@ -1,51 +1,50 @@
     <?php
     
    -    require '../../../main.inc.php';
    -    require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php';
    -  
    -    $get = GETPOST('get');
    -    $put = GETPOST('put');
    -    
    +require '../../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php';
    +
    +$get = GETPOST('get');
    +$put = GETPOST('put');
    +
         switch ($put)
         {
             case 'qty':
             	if (empty($user->rights->stock->creer)) { echo -1; exit; }
    -            
    +
                 $fk_det_inventory = GETPOST('fk_det_inventory');
    -            
    +
                 $det = new Inventorydet($db);
                 if( $det->fetch( $fk_det_inventory))
                 {
                     $det->qty_view+=GETPOST('qty');
                     $res = $det->update($user);
    -                
    +
                     echo $det->qty_view;
                 }
                 else
                 {
                     echo -2;
    -            }            
    -           
    +            }
    +
                 break;
    -			
    +
             case 'pmp':
             	if (empty($user->rights->stock->creer) || empty($user->rights->stock->changePMP)) { echo -1; exit; }
    -            
    +
                 $fk_det_inventory = GETPOST('fk_det_inventory');
    -            
    +
                 $det = new Inventorydet($db);
                 if( $det->fetch( $fk_det_inventory))
                 {
                     $det->new_pmp=price2num(GETPOST('pmp'));
                     $det->update($user);
    -                
    +
                     echo $det->new_pmp;
                 }
                 else
                 {
                     echo -2;
    -            }            
    -            
    +            }
    +
                 break;
         }
    - 
    diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php
    index 80b17a5e31d..2784e3c303b 100644
    --- a/htdocs/product/inventory/card.php
    +++ b/htdocs/product/inventory/card.php
    @@ -224,12 +224,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	    $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteInventory'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 1);
     	}
     
    -	if (! $formconfirm) {
    -	    $parameters = array('lineid' => $lineid);
    -	    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -	    if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -	    elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    @@ -409,7 +408,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	*/
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php
    index dc4f600b529..1bc98d32d93 100644
    --- a/htdocs/product/inventory/class/inventory.class.php
    +++ b/htdocs/product/inventory/class/inventory.class.php
    @@ -38,6 +38,7 @@ class Inventory extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'inventory';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
    @@ -47,6 +48,7 @@ class Inventory extends CommonObject
     	 * @var array  Does inventory support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * @var string String with name of icon for inventory
     	 */
    @@ -76,7 +78,7 @@ class Inventory extends CommonObject
     	 */
     	public $fields=array(
     		'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>'Id',),
    -		'ref'        => array('type'=>'varchar(64)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>'Reference of object', 'css'=>'maxwidth200'),
    +		'ref' => array('type'=>'varchar(64)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>'Reference of object', 'css'=>'maxwidth200'),
     		'entity'         => array('type'=>'integer', 'label'=>'Entity', 'visible'=>0, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,),
     		'title'          => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>25, 'css'=>'minwidth300'),
     		'fk_warehouse'   => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Warehouse', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'index'=>1, 'help'=>'LinkToThirparty'),
    @@ -97,19 +99,53 @@ class Inventory extends CommonObject
     		'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'default'=>0, 'arrayofkeyval'=>array(0=>'Todo', 1=>'Done', -1=>'Cancel')),
     	);
     
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_warehouse;
    +
     	public $date_inventory;
     	public $title;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	public $date_creation;
     	public $date_validation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_valid;
    +
     	public $import_key;
     	// END MODULEBUILDER PROPERTIES
     
    @@ -121,18 +157,22 @@ class Inventory extends CommonObject
     	 * @var int    Name of subtable line
     	 */
     	//public $table_element_line = 'inventorydet';
    +
     	/**
     	 * @var int    Field with ID of parent key if this field has a parent
     	 */
     	//public $fk_element = 'fk_inventory';
    +
     	/**
     	 * @var int    Name of subtable class that manage subtable lines
     	 */
     	//public $class_element_line = 'Inventoryline';
    +
     	/**
     	 * @var array  Array of child tables (child tables to delete before deleting a record)
     	 */
     	//protected $childtables=array('inventorydet');
    +
     	/**
     	 * @var InventoryLine[]     Array of subtable lines
     	 */
    @@ -333,6 +373,7 @@ class Inventory extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -342,50 +383,51 @@ class Inventory extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			$prefix='';
     			if ($status == 0) return $langs->trans('Draft');
    -			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == -1) return $langs->trans('Canceled');
    +			elseif ($status == 1) return $langs->trans('Enabled');
    +			elseif ($status == -1) return $langs->trans('Canceled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 0) return $langs->trans('Draft');
    -			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == -1) return $langs->trans('Canceled');
    +			elseif ($status == 1) return $langs->trans('Enabled');
    +			elseif ($status == -1) return $langs->trans('Canceled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 0) return img_picto($langs->trans('Draft'),'statut0').' '.$langs->trans('Draft');
    -			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == -1) return img_picto($langs->trans('Canceled'),'statut6').' '.$langs->trans('Canceled');
    +			elseif ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    +			elseif ($status == -1) return img_picto($langs->trans('Canceled'),'statut6').' '.$langs->trans('Canceled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 0) return img_picto($langs->trans('Draft'),'statut0');
    -			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == -1) return img_picto($langs->trans('Canceled'),'statut6');
    +			elseif ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
    +			elseif ($status == -1) return img_picto($langs->trans('Canceled'),'statut6');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 0) return img_picto($langs->trans('Draft'),'statut0').' '.$langs->trans('Draft');
    -			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == -1) return img_picto($langs->trans('Canceled'),'statut6').' '.$langs->trans('Canceled');
    +			elseif ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    +			elseif ($status == -1) return img_picto($langs->trans('Canceled'),'statut6').' '.$langs->trans('Canceled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 0) return $langs->trans('Draft').' '.img_picto($langs->trans('Draft'),'statut0');
    -			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == -1) return $langs->trans('Canceled').' '.img_picto($langs->trans('Canceled'),'statut6');
    +			elseif ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    +			elseif ($status == -1) return $langs->trans('Canceled').' '.img_picto($langs->trans('Canceled'),'statut6');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 0) return $langs->trans('Draft').' '.img_picto($langs->trans('Draft'),'statut0');
    -			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == -1) return $langs->trans('Canceled').' '.img_picto($langs->trans('Canceled'),'statut6');
    +			elseif ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    +			elseif ($status == -1) return $langs->trans('Canceled').' '.img_picto($langs->trans('Canceled'),'statut6');
     		}
     	}
     
    @@ -435,7 +477,6 @@ class Inventory extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -453,7 +494,6 @@ class Inventory extends CommonObject
     	{
     		$this->initAsSpecimenCommon();
     	}
    -
     }
     
     /**
    @@ -465,10 +505,12 @@ class InventoryObjectLine
     	 * @var int ID
     	 */
     	public $id;
    +
     	/**
     	 * @var mixed Sample line property 1
     	 */
     	public $prop1;
    +
     	/**
     	 * @var mixed Sample line property 2
     	 */
    diff --git a/htdocs/product/inventory/lib/inventory.lib.php b/htdocs/product/inventory/lib/inventory.lib.php
    index aa8c9c9677d..d6230e4f3e7 100644
    --- a/htdocs/product/inventory/lib/inventory.lib.php
    +++ b/htdocs/product/inventory/lib/inventory.lib.php
    @@ -25,7 +25,7 @@
     /**
      *  Define head array for tabs of inventory tools setup pages
      *
    - *  @return			Array of head
    + *  @return array Array of head
      */
     function inventoryAdminPrepareHead()
     {
    @@ -40,7 +40,7 @@ function inventoryAdminPrepareHead()
         $head[$h][1] = $langs->trans("Parameters");
         $head[$h][2] = 'settings';
         $h++;
    -    
    +
     
         // Show more tabs from modules
         // Entries must be declared in modules descriptor with line
    @@ -55,10 +55,19 @@ function inventoryAdminPrepareHead()
         return $head;
     }
     
    +/**
    + *  Define head array for tabs of inventory tools setup pages
    + *
    + *  @param  Inventory   $inventory      Object inventory
    + *  @param  string      $title          parameter
    + *  @param  string      $get            parameter
    + *
    + *  @return array                       Array of head
    + */
     function inventoryPrepareHead(&$inventory, $title='Inventory', $get='')
     {
     	global $langs;
    -	
    +
     	return array(
     		array(dol_buildpath('/product/inventory/card.php?id='.$inventory->id.$get, 1), $langs->trans($title),'inventory')
     	);
    @@ -66,26 +75,33 @@ function inventoryPrepareHead(&$inventory, $title='Inventory', $get='')
     
     
     
    +/**
    + *  Define head array for tabs of inventory tools setup pages
    + *
    + *  @param   Inventory  $inventory      Object inventory
    + *
    + *  @return string                      html of products
    + */
     function inventorySelectProducts(&$inventory)
     {
     	global $conf,$db,$langs;
    -	
    +
     	$except_product_id = array();
    -	
    +
     	foreach ($inventory->Inventorydet as $Inventorydet)
     	{
     		$except_product_id[] = $Inventorydet->fk_product;
     	}
    -	
    +
     	ob_start();
     	$form = new Form($db);
     	$form->select_produits(-1, 'fk_product');
    -	
    +
     	$TChildWarehouses = array($inventory->fk_warehouse);
     	$e = new Entrepot($db);
     	$e->fetch($inventory->fk_warehouse);
     	if(method_exists($e, 'get_children_warehouses')) $e->get_children_warehouses($e->id, $TChildWarehouses);
    -	
    +
     	$Tab = array();
     	$sql = 'SELECT rowid, label
     			FROM '.MAIN_DB_PREFIX.'entrepot WHERE rowid IN('.implode(', ', $TChildWarehouses).')';
    @@ -96,9 +112,8 @@ function inventorySelectProducts(&$inventory)
     	}
     	print '&nbsp;&nbsp;&nbsp;';
     	print $langs->trans('Warehouse').' : '.$form::selectarray('fk_warehouse', $Tab);
    -	
    +
     	$select_html = ob_get_clean();
    -	
    +
     	return $select_html;
     }
    -
    diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php
    index 74422cc2601..a5592c87f5d 100644
    --- a/htdocs/product/inventory/list.php
    +++ b/htdocs/product/inventory/list.php
    @@ -525,7 +525,7 @@ if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nb
     	$hidegeneratedfilelistifempty=1;
     	if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty=0;
     
    -	require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     	$formfile = new FormFile($db);
     
     	// Show list of available documents
    diff --git a/htdocs/product/inventory/tpl/inventory.tpl.php b/htdocs/product/inventory/tpl/inventory.tpl.php
    index 1946e63918d..30dc02a17d6 100644
    --- a/htdocs/product/inventory/tpl/inventory.tpl.php
    +++ b/htdocs/product/inventory/tpl/inventory.tpl.php
    @@ -165,7 +165,6 @@ if (empty($conf) || ! is_object($conf))
     				<?php } ?>
     			</tr>
     			<?php $i++;
    -
             }
     
     		_footerList($view,$total_pmp,$total_pmp_actual,$total_pa,$total_pa_actual, $total_current_pa,$total_current_pa_actual);
    diff --git a/htdocs/product/list.php b/htdocs/product/list.php
    index 7c7619fe0d5..562d09056c7 100644
    --- a/htdocs/product/list.php
    +++ b/htdocs/product/list.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2004-2018  Laurent Destailleur     <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
      * Copyright (C) 2012-2016  Marcos García           <marcosgdf@gmail.com>
    - * Copyright (C) 2013-2016	Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2013-2018	Juanjo Menent           <jmenent@2byte.es>
      * Copyright (C) 2013-2015  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2013       Jean Heimburger         <jean@tiaris.info>
      * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    @@ -53,7 +53,7 @@ $sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alp
     $search_ref=GETPOST("search_ref");
     $search_barcode=GETPOST("search_barcode");
     $search_label=GETPOST("search_label");
    -$search_type = GETPOST("search_type",'int');
    +$search_type = GETPOST("search_type", 'int');
     $search_sale = GETPOST("search_sale");
     $search_categ = GETPOST("search_categ",'int');
     $search_tosell = GETPOST("search_tosell", 'int');
    @@ -66,11 +66,11 @@ $search_accountancy_code_buy = GETPOST("search_accountancy_code_buy",'alpha');
     $optioncss = GETPOST('optioncss','alpha');
     $type=GETPOST("type","int");
     
    -//Show/hide child products. Hidden by default
    -if (!$_POST) {
    -	$search_hidechildproducts = 'on';
    +//Show/hide child products
    +if (!empty($conf->variants->enabled) && ! empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    +	$show_childproducts = GETPOST('search_show_childproducts');
     } else {
    -	$search_hidechildproducts = GETPOST('search_hidechildproducts');
    +	$show_childproducts = '';
     }
     
     $diroutputmassaction=$conf->product->dir_output . '/temp/massgeneration/'.$user->id;
    @@ -219,6 +219,8 @@ if (empty($reshook))
     		$search_tobuy="";
     		$search_tobatch='';
     		//$search_type='';						// There is 2 types of list: a list of product and a list of services. No list with both. So when we clear search criteria, we must keep the filter on type.
    +
    +		$show_childproducts = '';
     		$search_accountancy_code_sell='';
     		$search_accountancy_code_buy='';
     		$search_array_options=array();
    @@ -265,7 +267,7 @@ $sql.= ' p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte,
     $sql.= ' p.tobatch, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy,';
     $sql.= ' p.datec as date_creation, p.tms as date_update, p.pmp,';
     $sql.= ' MIN(pfp.unitprice) as minsellprice';
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) {
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
     	$sql .= ', pac.rowid prod_comb_id';
     }
     // Add fields from extrafields
    @@ -282,10 +284,12 @@ if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREF
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
     // multilang
     if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang = '".$langs->getDefaultLang() ."'";
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) {
    +
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
     	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
     }
     
    +
     $sql.= ' WHERE p.entity IN ('.getEntity('product').')';
     if ($sall) $sql .= natural_search(array_keys($fieldstosearchall), $sall);
     // if the type is not 1, we show all products (type = 0,2,3)
    @@ -294,6 +298,11 @@ if (dol_strlen($search_type) && $search_type != '-1')
     	if ($search_type == 1) $sql.= " AND p.fk_product_type = 1";
     	else $sql.= " AND p.fk_product_type <> 1";
     }
    +
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
    +	$sql .= " AND pac.rowid IS NULL";
    +}
    +
     if ($search_ref)     $sql .= natural_search('p.ref', $search_ref);
     if ($search_label)   $sql .= natural_search('p.label', $search_label);
     if ($search_barcode) $sql .= natural_search('p.barcode', $search_barcode);
    @@ -308,7 +317,7 @@ if ($fourn_id > 0)  $sql.= " AND pfp.fk_soc = ".$fourn_id;
     if ($search_tobatch != '' && $search_tobatch >= 0)   $sql.= " AND p.tobatch = ".$db->escape($search_tobatch);
     if ($search_accountancy_code_sell) $sql.= natural_search('p.accountancy_code_sell', $search_accountancy_code_sell);
     if ($search_accountancy_code_buy)  $sql.= natural_search('p.accountancy_code_buy', $search_accountancy_code_buy);
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) $sql .= " AND pac.rowid IS NULL";
    +
     // Add where from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
     // Add where from hooks
    @@ -318,7 +327,10 @@ $sql.=$hookmanager->resPrint;
     $sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type,";
     $sql.= " p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,";
     $sql.= ' p.datec, p.tms, p.entity, p.tobatch, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.pmp';
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) $sql .= ', pac.rowid';
    +
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
    +	$sql .= ', pac.rowid';
    +}
     // Add fields from extrafields
     if (! empty($extrafields->attributes[$object->table_element]['label'])) {
     	foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : '');
    @@ -392,6 +404,7 @@ if ($resql)
     	if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy);
     	if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:"");
     	if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):"");
    +	if ($show_childproducts) $param.=($show_childproducts?"&search_show_childproducts=".urlencode($show_childproducts):"");
     	if ($type != '') $param.='&type='.urlencode($type);
     	if ($search_type != '') $param.='&search_type='.urlencode($search_type);
     	if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
    @@ -450,530 +463,521 @@ if ($resql)
     		print "</div><br>";
     	}
     
    -	if (! empty($canvas) && file_exists(DOL_DOCUMENT_ROOT.'/product/canvas/'.$canvas.'/actions_card_'.$canvas.'.class.php'))
    +	if ($sall)
     	{
    -		$fieldlist = $object->field_list;
    -		$datas = $object->list_datas;
    -		$picto='title.png';
    -		$title_picto = img_picto('',$picto);
    -		$title_text = $title;
    -
    -		// Default templates directory
    -		$template_dir = DOL_DOCUMENT_ROOT . '/product/canvas/'.$canvas.'/tpl/';
    -		// Check if a custom template is present
    -		if (file_exists(DOL_DOCUMENT_ROOT . '/theme/'.$conf->theme.'/tpl/product/'.$canvas.'/list.tpl.php'))
    -		{
    -			$template_dir = DOL_DOCUMENT_ROOT . '/theme/'.$conf->theme.'/tpl/product/'.$canvas.'/';
    -		}
    -
    -		include $template_dir.'list.tpl.php';	// Include native PHP templates
    +		foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    +		print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall).'</div>';
     	}
    -	else
    +
    +	// Filter on categories
    +	$moreforfilter='';
    +	if (! empty($conf->categorie->enabled))
     	{
    -		if ($sall)
    +		$moreforfilter.='<div class="divsearchfield">';
    +		$moreforfilter.=$langs->trans('Categories'). ': ';
    +		$moreforfilter.=$htmlother->select_categories(Categorie::TYPE_PRODUCT,$search_categ,'search_categ',1);
    +		$moreforfilter.='</div>';
    +	}
    +
    +	//Show/hide child products. Hidden by default
    +	if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD )) {
    +		$moreforfilter.='<div class="divsearchfield">';
    +		$moreforfilter.= '<input type="checkbox" id="search_show_childproducts" name="search_show_childproducts"'.($show_childproducts ? 'checked="checked"':'').'>';
    +		$moreforfilter.= ' <label for="search_show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
    +		$moreforfilter.='</div>';
    +	}
    +
    +	$parameters=array();
    +	$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $moreforfilter.=$hookmanager->resPrint;
    +	else $moreforfilter=$hookmanager->resPrint;
    +
    +	if ($moreforfilter)
    +	{
    +		print '<div class="liste_titre liste_titre_bydiv centpercent">';
    +		print $moreforfilter;
    +		print '</div>';
    +	}
    +
    +	$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
    +	$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
    +	if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
    +
    +	print '<div class="div-table-responsive">';
    +	print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
    +
    +	// Lines with input filters
    +	print '<tr class="liste_titre_filter">';
    +	if (! empty($arrayfields['p.ref']['checked']))
    +	{
    +		print '<td class="liste_titre" align="left">';
    +		print '<input class="flat" type="text" name="search_ref" size="8" value="'.dol_escape_htmltag($search_ref).'">';
    +		print '</td>';
    +	}
    +	if (! empty($arrayfields['pfp.ref_fourn']['checked']))
    +	{
    +		print '<td class="liste_titre" align="left">';
    +		print '<input class="flat" type="text" name="search_ref_supplier" size="8" value="'.dol_escape_htmltag($search_ref_supplier).'">';
    +		print '</td>';
    +	}
    +	if (! empty($arrayfields['p.label']['checked']))
    +	{
    +		print '<td class="liste_titre" align="left">';
    +		print '<input class="flat" type="text" name="search_label" size="12" value="'.dol_escape_htmltag($search_label).'">';
    +		print '</td>';
    +	}
    +	// Type
    +	if (! empty($arrayfields['p.fk_product_type']['checked']))
    +	{
    +		print '<td class="liste_titre" align="left">';
    +		$array=array('-1'=>'&nbsp;', '0'=>$langs->trans('Product'), '1'=>$langs->trans('Service'));
    +		print $form->selectarray('search_type', $array, $search_type);
    +		print '</td>';
    +	}
    +	// Barcode
    +	if (! empty($arrayfields['p.barcode']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '<input class="flat" type="text" name="search_barcode" size="6" value="'.dol_escape_htmltag($search_barcode).'">';
    +		print '</td>';
    +	}
    +	// Duration
    +	if (! empty($arrayfields['p.duration']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '&nbsp;';
    +		print '</td>';
    +	}
    +	// Sell price
    +	if (! empty($arrayfields['p.sellprice']['checked']))
    +	{
    +		print '<td class="liste_titre" align="right">';
    +		print '</td>';
    +	}
    +	// Minimum buying Price
    +	if (! empty($arrayfields['p.minbuyprice']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '&nbsp;';
    +		print '</td>';
    +	}
    +	// Number buying Price
    +	if (! empty($arrayfields['p.numbuyprice']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '&nbsp;';
    +		print '</td>';
    +	}
    +	// WAP
    +	if (! empty($arrayfields['p.pmp']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '&nbsp;';
    +		print '</td>';
    +	}
    +	// Limit for alert
    +	if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '&nbsp;';
    +		print '</td>';
    +	}
    +	// Desired stock
    +	if (! empty($arrayfields['p.desiredstock']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '&nbsp;';
    +		print '</td>';
    +	}
    +	// Stock
    +	if (! empty($arrayfields['p.stock']['checked'])) print '<td class="liste_titre">&nbsp;</td>';
    +	// Stock
    +	if (! empty($arrayfields['stock_virtual']['checked'])) print '<td class="liste_titre">&nbsp;</td>';
    +	// To batch
    +	if (! empty($arrayfields['p.tobatch']['checked'])) print '<td class="liste_titre center">'.$form->selectyesno($search_tobatch, '', '', '', 1).'</td>';
    +	// Accountancy code sell
    +	if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_sell" size="6" value="'.dol_escape_htmltag($search_accountancy_code_sell).'"></td>';
    +	// Accountancy code sell
    +	if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_buy" size="6" value="'.dol_escape_htmltag($search_accountancy_code_buy).'"></td>';
    +	// Extra fields
    +	include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
    +	// 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['p.datec']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '</td>';
    +	}
    +	// Date modification
    +	if (! empty($arrayfields['p.tms']['checked']))
    +	{
    +		print '<td class="liste_titre">';
    +		print '</td>';
    +	}
    +	if (! empty($arrayfields['p.tosell']['checked']))
    +	{
    +		print '<td class="liste_titre" align="right">';
    +		print $form->selectarray('search_tosell', array('0'=>$langs->trans('ProductStatusNotOnSellShort'),'1'=>$langs->trans('ProductStatusOnSellShort')),$search_tosell,1);
    +		print '</td >';
    +	}
    +	if (! empty($arrayfields['p.tobuy']['checked']))
    +	{
    +		print '<td class="liste_titre" align="right">';
    +		print $form->selectarray('search_tobuy', array('0'=>$langs->trans('ProductStatusNotOnBuyShort'),'1'=>$langs->trans('ProductStatusOnBuyShort')),$search_tobuy,1);
    +		print '</td>';
    +	}
    +	print '<td class="liste_titre" align="middle">';
    +	$searchpicto=$form->showFilterButtons();
    +	print $searchpicto;
    +	print '</td>';
    +
    +	print '</tr>';
    +
    +	print '<tr class="liste_titre">';
    +	if (! empty($arrayfields['p.ref']['checked']))  print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder);
    +	if (! empty($arrayfields['pfp.ref_fourn']['checked']))  print_liste_field_titre($arrayfields['pfp.ref_fourn']['label'], $_SERVER["PHP_SELF"],"pfp.ref_fourn","",$param,"",$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.label']['checked']))  print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"],"p.label","",$param,"",$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.fk_product_type']['checked']))  print_liste_field_titre($arrayfields['p.fk_product_type']['label'], $_SERVER["PHP_SELF"],"p.fk_product_type","",$param,"",$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.barcode']['checked']))  print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"],"p.barcode","",$param,"",$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.duration']['checked']))  print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"],"p.duration","",$param,'align="center"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.sellprice']['checked']))  print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.minbuyprice']['checked']))  print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.numbuyprice']['checked']))  print_liste_field_titre($arrayfields['p.numbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.pmp']['checked']))  print_liste_field_titre($arrayfields['p.pmp']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))  print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.desiredstock']['checked']))  print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.stock']['checked']))  print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['stock_virtual']['checked']))  print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.tobatch']['checked']))  print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.accountancy_code_sell']['checked']))  print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.accountancy_code_buy']['checked']))  print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder);
    +	// Extra fields
    +	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);    // Note that $action and $object may have been modified by hook
    +	print $hookmanager->resPrint;
    +	if (! empty($arrayfields['p.datec']['checked']))  print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.tms']['checked']))    print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.tosell']['checked'])) print_liste_field_titre($arrayfields['p.tosell']['label'],$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder);
    +	if (! empty($arrayfields['p.tobuy']['checked']))  print_liste_field_titre($arrayfields['p.tobuy']['label'],$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder);
    +	print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ');
    +	print "</tr>\n";
    +
    +
    +	$product_static=new Product($db);
    +	$product_fourn =new ProductFournisseur($db);
    +
    +	$i = 0;
    +	$totalarray=array();
    +	while ($i < min($num,$limit))
    +	{
    +		$obj = $db->fetch_object($resql);
    +
    +		// Multilangs
    +		if (! empty($conf->global->MAIN_MULTILANGS)) // si l'option est active
     		{
    -			foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    -			print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall).'</div>';
    +			$sql = "SELECT label";
    +			$sql.= " FROM ".MAIN_DB_PREFIX."product_lang";
    +			$sql.= " WHERE fk_product=".$obj->rowid;
    +			$sql.= " AND lang='". $db->escape($langs->getDefaultLang()) ."'";
    +			$sql.= " LIMIT 1";
    +
    +			$result = $db->query($sql);
    +			if ($result)
    +			{
    +				$objtp = $db->fetch_object($result);
    +				if (! empty($objtp->label)) $obj->label = $objtp->label;
    +			}
     		}
     
    -		// Filter on categories
    -		$moreforfilter='';
    -		if (! empty($conf->categorie->enabled))
    +		$product_static->id = $obj->rowid;
    +		$product_static->ref = $obj->ref;
    +		$product_static->ref_fourn = $obj->ref_supplier;
    +		$product_static->label = $obj->label;
    +		$product_static->type = $obj->fk_product_type;
    +		$product_static->status_buy = $obj->tobuy;
    +		$product_static->status     = $obj->tosell;
    +		$product_static->status_batch = $obj->tobatch;
    +		$product_static->entity = $obj->entity;
    +		$product_static->pmp = $obj->pmp;
    +		$product_static->accountancy_code_sell = $obj->accountancy_code_sell;
    +		$product_static->accountancy_code_sell_export = $obj->accountancy_code_sell_export;
    +		$product_static->accountancy_code_sell_intra = $obj->accountancy_code_sell_intra;
    +		$product_static->accountancy_code_buy = $obj->accountancy_code_buy;
    +
    +		if ((! empty($conf->stock->enabled) && $user->rights->stock->lire && $search_type != 1) || ! empty($conf->global->STOCK_DISABLE_OPTIM_LOAD))	// To optimize call of load_stock
     		{
    -			$moreforfilter.='<div class="divsearchfield">';
    -			$moreforfilter.=$langs->trans('Categories'). ': ';
    -			$moreforfilter.=$htmlother->select_categories(Categorie::TYPE_PRODUCT,$search_categ,'search_categ',1);
    -			$moreforfilter.='</div>';
    +			if ($obj->fk_product_type != 1 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES))    // Not a service
    +			{
    +				$product_static->load_stock('nobatch');             // Load stock_reel + stock_warehouse. This also call load_virtual_stock()
    +			}
     		}
     
    -		//Show/hide child products. Hidden by default
    -		if (!empty($conf->variants->enabled) && $search_type === 0) {
    -			$moreforfilter.='<div class="divsearchfield">';
    -			$moreforfilter.= '<input type="checkbox" id="search_hidechildproducts" name="search_hidechildproducts" value="on"'.($search_hidechildproducts ? 'checked="checked"' : '').'>';
    -			$moreforfilter.= ' <label for="search_hidechildproducts">'.$langs->trans('HideChildProducts').'</label>';
    -			$moreforfilter.='</div>';
    -		}
     
    -		$parameters=array();
    -		$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
    -		if (empty($reshook)) $moreforfilter.=$hookmanager->resPrint;
    -		else $moreforfilter=$hookmanager->resPrint;
    +		print '<tr class="oddeven">';
     
    -		if ($moreforfilter)
    -		{
    -			print '<div class="liste_titre liste_titre_bydiv centpercent">';
    -			print $moreforfilter;
    -			print '</div>';
    -		}
    -
    -		$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
    -		$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
    -		if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
    -
    -		print '<div class="div-table-responsive">';
    -		print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
    -
    -		// Lines with input filters
    -		print '<tr class="liste_titre_filter">';
    +		// Ref
     		if (! empty($arrayfields['p.ref']['checked']))
     		{
    -			print '<td class="liste_titre" align="left">';
    -			print '<input class="flat" type="text" name="search_ref" size="8" value="'.dol_escape_htmltag($search_ref).'">';
    -			print '</td>';
    +			print '<td class="tdoverflowmax200">';
    +			print $product_static->getNomUrl(1);
    +			print "</td>\n";
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +		// Ref supplier
     		if (! empty($arrayfields['pfp.ref_fourn']['checked']))
     		{
    -			print '<td class="liste_titre" align="left">';
    -			print '<input class="flat" type="text" name="search_ref_supplier" size="8" value="'.dol_escape_htmltag($search_ref_supplier).'">';
    -			print '</td>';
    +			print '<td class="tdoverflowmax200">';
    +			print $product_static->getNomUrl(1);
    +			print "</td>\n";
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +		// Label
     		if (! empty($arrayfields['p.label']['checked']))
     		{
    -			print '<td class="liste_titre" align="left">';
    -			print '<input class="flat" type="text" name="search_label" size="12" value="'.dol_escape_htmltag($search_label).'">';
    -			print '</td>';
    +			print '<td class="tdoverflowmax200">'.dol_trunc($obj->label,40).'</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +
     		// Type
     		if (! empty($arrayfields['p.fk_product_type']['checked']))
     		{
    -			print '<td class="liste_titre" align="left">';
    -			$array=array('-1'=>'&nbsp;', '0'=>$langs->trans('Product'), '1'=>$langs->trans('Service'));
    -			print $form->selectarray('search_type', $array, $search_type);
    -			print '</td>';
    +			print '<td>'.$obj->fk_product_type.'</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +
     		// Barcode
     		if (! empty($arrayfields['p.barcode']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '<input class="flat" type="text" name="search_barcode" size="6" value="'.dol_escape_htmltag($search_barcode).'">';
    -			print '</td>';
    +			print '<td>'.$obj->barcode.'</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +
     		// Duration
     		if (! empty($arrayfields['p.duration']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '&nbsp;';
    +			print '<td align="center">';
    +
    +			if (preg_match('/([^a-z]+)[a-z]$/i',$obj->duration))
    +			{
    +				$duration_value	= substr($obj->duration,0,dol_strlen($obj->duration)-1);
    +				$duration_unit	= substr($obj->duration,-1);
    +
    +				if ((float) $duration_value > 1)
    +				{
    +				    $dur=array("i"=>$langs->trans("Minutes"),"h"=>$langs->trans("Hours"),"d"=>$langs->trans("Days"),"w"=>$langs->trans("Weeks"),"m"=>$langs->trans("Months"),"y"=>$langs->trans("Years"));
    +				}
    +				else if ((float) $duration_value > 0)
    +				{
    +				    $dur=array("i"=>$langs->trans("Minute"),"h"=>$langs->trans("Hour"),"d"=>$langs->trans("Day"),"w"=>$langs->trans("Week"),"m"=>$langs->trans("Month"),"y"=>$langs->trans("Year"));
    +				}
    +				print $duration_value;
    +				print (! empty($duration_unit) && isset($dur[$duration_unit]) ? ' '.$langs->trans($dur[$duration_unit]) : '');
    +			}
    +			else
    +			{
    +				print $obj->duration;
    +			}
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +
     		// Sell price
     		if (! empty($arrayfields['p.sellprice']['checked']))
     		{
    -			print '<td class="liste_titre" align="right">';
    +			print '<td class="right nowraponall">';
    +			if ($obj->tosell)
    +			{
    +				if ($obj->price_base_type == 'TTC') print price($obj->price_ttc).' '.$langs->trans("TTC");
    +				else print price($obj->price).' '.$langs->trans("HT");
    +			}
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    -		// Minimum buying Price
    +
    +		// Better buy price
     		if (! empty($arrayfields['p.minbuyprice']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '&nbsp;';
    +			print  '<td class="right nowraponall">';
    +			if ($obj->tobuy && $obj->minsellprice != '')
    +			{
    +				//print price($obj->minsellprice).' '.$langs->trans("HT");
    +				if ($product_fourn->find_min_price_product_fournisseur($obj->rowid) > 0)
    +				{
    +					if ($product_fourn->product_fourn_price_id > 0)
    +					{
    +						if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire)
    +						{
    +							$htmltext=$product_fourn->display_price_product_fournisseur(1, 1, 0, 1);
    +							print $form->textwithpicto(price($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent/100) - $product_fourn->fourn_remise).' '.$langs->trans("HT"),$htmltext);
    +						}
    +						else print price($product_fourn->fourn_unitprice).' '.$langs->trans("HT");
    +					}
    +				}
    +			}
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    -		// Number buying Price
    +
    +		// Number of buy prices
     		if (! empty($arrayfields['p.numbuyprice']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '&nbsp;';
    +			print  '<td align="right">';
    +			if ($obj->tobuy)
    +			{
    +				if (count($productFournList = $product_fourn->list_product_fournisseur_price($obj->rowid)) > 0)
    +				{
    +					$htmltext=$product_fourn->display_price_product_fournisseur(1, 1, 0, 1, $productFournList);
    +					print $form->textwithpicto(count($productFournList),$htmltext);
    +				}
    +			}
     			print '</td>';
     		}
    +
     		// WAP
     		if (! empty($arrayfields['p.pmp']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '&nbsp;';
    +			print '<td class="nowrap" align="right">';
    +			print price($product_static->pmp, 1, $langs);
     			print '</td>';
     		}
    -		// Limit for alert
    +
    +		// Limit alert
     		if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '&nbsp;';
    +			print '<td align="right">';
    +			if ($obj->fk_product_type != 1)
    +			{
    +				print $obj->seuil_stock_alerte;
    +			}
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
     		// Desired stock
     		if (! empty($arrayfields['p.desiredstock']['checked']))
     		{
    -			print '<td class="liste_titre">';
    -			print '&nbsp;';
    +			print '<td align="right">';
    +			if ($obj->fk_product_type != 1)
    +			{
    +				print $obj->desiredstock;
    +			}
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
    +		// Stock real
    +		if (! empty($arrayfields['p.stock']['checked']))
    +		{
    +			print '<td align="right">';
    +			if ($obj->fk_product_type != 1)
    +			{
    +				if ($obj->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $obj->seuil_stock_alerte) print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
    +				print $product_static->stock_reel;
    +			}
    +			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
    +		// Stock virtual
    +		if (! empty($arrayfields['stock_virtual']['checked']))
    +		{
    +			print '<td align="right">';
    +			if ($obj->fk_product_type != 1)
    +			{
    +				if ($obj->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $obj->seuil_stock_alerte) print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
    +				print $product_static->stock_theorique;
    +			}
    +			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
    +		// Lot/Serial
    +		if (! empty($arrayfields['p.tobatch']['checked']))
    +		{
    +			print '<td align="center">';
    +			print yn($obj->tobatch);
    +			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    -		// Stock
    -		if (! empty($arrayfields['p.stock']['checked'])) print '<td class="liste_titre">&nbsp;</td>';
    -		// Stock
    -		if (! empty($arrayfields['stock_virtual']['checked'])) print '<td class="liste_titre">&nbsp;</td>';
    -		// To batch
    -		if (! empty($arrayfields['p.tobatch']['checked'])) print '<td class="liste_titre center">'.$form->selectyesno($search_tobatch, '', '', '', 1).'</td>';
     		// Accountancy code sell
    -		if (! empty($arrayfields['p.accountancy_code_sell']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_sell" size="6" value="'.dol_escape_htmltag($search_accountancy_code_sell).'"></td>';
    +		if (! empty($arrayfields['p.accountancy_code_sell']['checked']))
    +		{
    +			print '<td>'.$obj->accountancy_code_sell.'</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
     		// Accountancy code sell
    -		if (! empty($arrayfields['p.accountancy_code_buy']['checked'])) print '<td class="liste_titre"><input class="flat" type="text" name="search_accountancy_code_buy" size="6" value="'.dol_escape_htmltag($search_accountancy_code_buy).'"></td>';
    +		if (! empty($arrayfields['p.accountancy_code_buy']['checked']))
    +		{
    +			print '<td>'.$obj->accountancy_code_buy.'</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
     		// Extra fields
    -		include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
    +		include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
     		// Fields from hook
    -		$parameters=array('arrayfields'=>$arrayfields);
    -		$reshook=$hookmanager->executeHooks('printFieldListOption',$parameters);    // Note that $action and $object may have been modified by hook
    +		$parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj);
    +		$reshook=$hookmanager->executeHooks('printFieldListValue',$parameters);    // Note that $action and $object may have been modified by hook
     		print $hookmanager->resPrint;
     		// Date creation
     		if (! empty($arrayfields['p.datec']['checked']))
     		{
    -			print '<td class="liste_titre">';
    +			print '<td align="center">';
    +			print dol_print_date($obj->date_creation, 'dayhour', 'tzuser');
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
     		// Date modification
     		if (! empty($arrayfields['p.tms']['checked']))
     		{
    -			print '<td class="liste_titre">';
    +			print '<td align="center">';
    +			print dol_print_date($obj->date_update, 'dayhour', 'tzuser');
     			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
     		}
    +
    +		// Status (to sell)
     		if (! empty($arrayfields['p.tosell']['checked']))
     		{
    -			print '<td class="liste_titre" align="right">';
    -			print $form->selectarray('search_tosell', array('0'=>$langs->trans('ProductStatusNotOnSellShort'),'1'=>$langs->trans('ProductStatusOnSellShort')),$search_tosell,1);
    -			print '</td >';
    -		}
    -		if (! empty($arrayfields['p.tobuy']['checked']))
    -		{
    -			print '<td class="liste_titre" align="right">';
    -			print $form->selectarray('search_tobuy', array('0'=>$langs->trans('ProductStatusNotOnBuyShort'),'1'=>$langs->trans('ProductStatusOnBuyShort')),$search_tobuy,1);
    -			print '</td>';
    -		}
    -		print '<td class="liste_titre" align="middle">';
    -		$searchpicto=$form->showFilterButtons();
    -		print $searchpicto;
    -		print '</td>';
    -
    -		print '</tr>';
    -
    -		print '<tr class="liste_titre">';
    -		if (! empty($arrayfields['p.ref']['checked']))  print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"],"p.ref","",$param,"",$sortfield,$sortorder);
    -		if (! empty($arrayfields['pfp.ref_fourn']['checked']))  print_liste_field_titre($arrayfields['pfp.ref_fourn']['label'], $_SERVER["PHP_SELF"],"pfp.ref_fourn","",$param,"",$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.label']['checked']))  print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"],"p.label","",$param,"",$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.fk_product_type']['checked']))  print_liste_field_titre($arrayfields['p.fk_product_type']['label'], $_SERVER["PHP_SELF"],"p.fk_product_type","",$param,"",$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.barcode']['checked']))  print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"],"p.barcode","",$param,"",$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.duration']['checked']))  print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"],"p.duration","",$param,'align="center"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.sellprice']['checked']))  print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.minbuyprice']['checked']))  print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.numbuyprice']['checked']))  print_liste_field_titre($arrayfields['p.numbuyprice']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.pmp']['checked']))  print_liste_field_titre($arrayfields['p.pmp']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))  print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"],"p.seuil_stock_alerte","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.desiredstock']['checked']))  print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"],"p.desiredstock","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.stock']['checked']))  print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"],"p.stock","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['stock_virtual']['checked']))  print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"],"","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.tobatch']['checked']))  print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"],"p.tobatch","",$param,'align="center"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.accountancy_code_sell']['checked']))  print_liste_field_titre($arrayfields['p.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_sell","",$param,'',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.accountancy_code_buy']['checked']))  print_liste_field_titre($arrayfields['p.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"],"p.accountancy_code_buy","",$param,'',$sortfield,$sortorder);
    -		// Extra fields
    -		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);    // Note that $action and $object may have been modified by hook
    -		print $hookmanager->resPrint;
    -		if (! empty($arrayfields['p.datec']['checked']))  print_liste_field_titre($arrayfields['p.datec']['label'],$_SERVER["PHP_SELF"],"p.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.tms']['checked']))    print_liste_field_titre($arrayfields['p.tms']['label'],$_SERVER["PHP_SELF"],"p.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.tosell']['checked'])) print_liste_field_titre($arrayfields['p.tosell']['label'],$_SERVER["PHP_SELF"],"p.tosell","",$param,'align="right"',$sortfield,$sortorder);
    -		if (! empty($arrayfields['p.tobuy']['checked']))  print_liste_field_titre($arrayfields['p.tobuy']['label'],$_SERVER["PHP_SELF"],"p.tobuy","",$param,'align="right"',$sortfield,$sortorder);
    -		print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ');
    -		print "</tr>\n";
    -
    -
    -		$product_static=new Product($db);
    -		$product_fourn =new ProductFournisseur($db);
    -
    -		$i = 0;
    -		$totalarray=array();
    -		while ($i < min($num,$limit))
    -		{
    -			$obj = $db->fetch_object($resql);
    -
    -			// Multilangs
    -			if (! empty($conf->global->MAIN_MULTILANGS)) // si l'option est active
    -			{
    -				$sql = "SELECT label";
    -				$sql.= " FROM ".MAIN_DB_PREFIX."product_lang";
    -				$sql.= " WHERE fk_product=".$obj->rowid;
    -				$sql.= " AND lang='". $db->escape($langs->getDefaultLang()) ."'";
    -				$sql.= " LIMIT 1";
    -
    -				$result = $db->query($sql);
    -				if ($result)
    -				{
    -					$objtp = $db->fetch_object($result);
    -					if (! empty($objtp->label)) $obj->label = $objtp->label;
    -				}
    -			}
    -
    -			$product_static->id = $obj->rowid;
    -			$product_static->ref = $obj->ref;
    -			$product_static->ref_fourn = $obj->ref_supplier;
    -			$product_static->label = $obj->label;
    -			$product_static->type = $obj->fk_product_type;
    -			$product_static->status_buy = $obj->tobuy;
    -			$product_static->status     = $obj->tosell;
    -			$product_static->status_batch = $obj->tobatch;
    -			$product_static->entity = $obj->entity;
    -			$product_static->pmp = $obj->pmp;
    -			$product_static->accountancy_code_sell = $obj->accountancy_code_sell;
    -			$product_static->accountancy_code_sell_export = $obj->accountancy_code_sell_export;
    -			$product_static->accountancy_code_sell_intra = $obj->accountancy_code_sell_intra;
    -			$product_static->accountancy_code_buy = $obj->accountancy_code_buy;
    -
    -			if ((! empty($conf->stock->enabled) && $user->rights->stock->lire && $search_type != 1) || ! empty($conf->global->STOCK_DISABLE_OPTIM_LOAD))	// To optimize call of load_stock
    -			{
    -				if ($obj->fk_product_type != 1 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES))    // Not a service
    -				{
    -					$product_static->load_stock('nobatch');             // Load stock_reel + stock_warehouse. This also call load_virtual_stock()
    -				}
    -			}
    -
    -
    -			print '<tr class="oddeven">';
    -
    -			// Ref
    -			if (! empty($arrayfields['p.ref']['checked']))
    -			{
    -				print '<td class="tdoverflowmax200">';
    -				print $product_static->getNomUrl(1);
    -				print "</td>\n";
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Ref supplier
    -			if (! empty($arrayfields['pfp.ref_fourn']['checked']))
    -			{
    -				print '<td class="tdoverflowmax200">';
    -				print $product_static->getNomUrl(1);
    -				print "</td>\n";
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Label
    -			if (! empty($arrayfields['p.label']['checked']))
    -			{
    -				print '<td class="tdoverflowmax200">'.dol_trunc($obj->label,40).'</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Type
    -			if (! empty($arrayfields['p.fk_product_type']['checked']))
    -			{
    -				print '<td>'.$obj->fk_product_type.'</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Barcode
    -			if (! empty($arrayfields['p.barcode']['checked']))
    -			{
    -				print '<td>'.$obj->barcode.'</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Duration
    -			if (! empty($arrayfields['p.duration']['checked']))
    -			{
    -				print '<td align="center">';
    -				if (preg_match('/([^a-z]+)[a-z]/i',$obj->duration))
    -				{
    -					if (preg_match('/([^a-z]+)y/i',$obj->duration,$regs)) print $regs[1].' '.$langs->trans("DurationYear");
    -					elseif (preg_match('/([^a-z]+)m/i',$obj->duration,$regs)) print $regs[1].' '.$langs->trans("DurationMonth");
    -					elseif (preg_match('/([^a-z]+)w/i',$obj->duration,$regs)) print $regs[1].' '.$langs->trans("DurationWeek");
    -					elseif (preg_match('/([^a-z]+)d/i',$obj->duration,$regs)) print $regs[1].' '.$langs->trans("DurationDay");
    -					//elseif (preg_match('/([^a-z]+)h/i',$obj->duration,$regs)) print $regs[1].' '.$langs->trans("DurationHour");
    -					else print $obj->duration;
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Sell price
    -			if (! empty($arrayfields['p.sellprice']['checked']))
    -			{
    -				print '<td align="right">';
    -				if ($obj->tosell)
    -				{
    -					if ($obj->price_base_type == 'TTC') print price($obj->price_ttc).' '.$langs->trans("TTC");
    -					else print price($obj->price).' '.$langs->trans("HT");
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Better buy price
    -			if (! empty($arrayfields['p.minbuyprice']['checked']))
    -			{
    -				print  '<td align="right">';
    -				if ($obj->tobuy && $obj->minsellprice != '')
    -				{
    -					//print price($obj->minsellprice).' '.$langs->trans("HT");
    -					if ($product_fourn->find_min_price_product_fournisseur($obj->rowid) > 0)
    -					{
    -						if ($product_fourn->product_fourn_price_id > 0)
    -						{
    -							if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->lire)
    -							{
    -								$htmltext=$product_fourn->display_price_product_fournisseur(1, 1, 0, 1);
    -								print $form->textwithpicto(price($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent/100) - $product_fourn->fourn_remise).' '.$langs->trans("HT"),$htmltext);
    -							}
    -							else print price($product_fourn->fourn_unitprice).' '.$langs->trans("HT");
    -						}
    -					}
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Number of buy prices
    -			if (! empty($arrayfields['p.numbuyprice']['checked']))
    -			{
    -				print  '<td align="right">';
    -				if ($obj->tobuy)
    -				{
    -					if (count($productFournList = $product_fourn->list_product_fournisseur_price($obj->rowid)) > 0)
    -					{
    -						$htmltext=$product_fourn->display_price_product_fournisseur(1, 1, 0, 1, $productFournList);
    -						print $form->textwithpicto(count($productFournList),$htmltext);
    -					}
    -				}
    -				print '</td>';
    -			}
    -
    -			// WAP
    -			if (! empty($arrayfields['p.pmp']['checked']))
    -			{
    -				print '<td class="nowrap" align="right">';
    -				print price($product_static->pmp, 1, $langs);
    -				print '</td>';
    -			}
    -
    -			// Limit alert
    -			if (! empty($arrayfields['p.seuil_stock_alerte']['checked']))
    -			{
    -				print '<td align="right">';
    -				if ($obj->fk_product_type != 1)
    -				{
    -					print $obj->seuil_stock_alerte;
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Desired stock
    -			if (! empty($arrayfields['p.desiredstock']['checked']))
    -			{
    -				print '<td align="right">';
    -				if ($obj->fk_product_type != 1)
    -				{
    -					print $obj->desiredstock;
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Stock real
    -			if (! empty($arrayfields['p.stock']['checked']))
    -			{
    -				print '<td align="right" class="nowraponall">';
    -				if ($obj->fk_product_type != 1)
    -				{
    -					if ($obj->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $obj->seuil_stock_alerte) print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
    -					print $product_static->stock_reel;
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Stock virtual
    -			if (! empty($arrayfields['stock_virtual']['checked']))
    -			{
    -				print '<td align="right" class="nowraponall">';
    -				if ($obj->fk_product_type != 1)
    -				{
    -					if ($obj->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $obj->seuil_stock_alerte) print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
    -					print $product_static->stock_theorique;
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Lot/Serial
    -			if (! empty($arrayfields['p.tobatch']['checked']))
    -			{
    -				print '<td align="center">';
    -				print yn($obj->tobatch);
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Accountancy code sell
    -			if (! empty($arrayfields['p.accountancy_code_sell']['checked']))
    -			{
    -				print '<td>'.$obj->accountancy_code_sell.'</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Accountancy code sell
    -			if (! empty($arrayfields['p.accountancy_code_buy']['checked']))
    -			{
    -				print '<td>'.$obj->accountancy_code_buy.'</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Extra fields
    -			include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
    -			// Fields from hook
    -			$parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj);
    -			$reshook=$hookmanager->executeHooks('printFieldListValue',$parameters);    // Note that $action and $object may have been modified by hook
    -			print $hookmanager->resPrint;
    -			// Date creation
    -			if (! empty($arrayfields['p.datec']['checked']))
    -			{
    -				print '<td align="center">';
    -				print dol_print_date($obj->date_creation, 'dayhour', 'tzuser');
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Date modification
    -			if (! empty($arrayfields['p.tms']['checked']))
    -			{
    -				print '<td align="center">';
    -				print dol_print_date($obj->date_update, 'dayhour', 'tzuser');
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -
    -			// Status (to sell)
    -			if (! empty($arrayfields['p.tosell']['checked']))
    -			{
    -				print '<td align="right" nowrap="nowrap">';
    -				if (! empty($conf->use_javascript_ajax) && $user->rights->produit->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
    -					print ajax_object_onoff($product_static, 'status', 'tosell', 'ProductStatusOnSell', 'ProductStatusNotOnSell');
    -				} else {
    -					print $product_static->LibStatut($obj->tosell,5,0);
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Status (to buy)
    -			if (! empty($arrayfields['p.tobuy']['checked']))
    -			{
    -				print '<td align="right" nowrap="nowrap">';
    -				if (! empty($conf->use_javascript_ajax) && $user->rights->produit->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
    -					print ajax_object_onoff($product_static, 'status_buy', 'tobuy', 'ProductStatusOnBuy', 'ProductStatusNotOnBuy');
    -				} else {
    -					print $product_static->LibStatut($obj->tobuy,5,1);
    -				}
    -				print '</td>';
    -				if (! $i) $totalarray['nbfield']++;
    -			}
    -			// Action
    -			print '<td class="nowrap" align="center">';
    -			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->rowid, $arrayofselected)) $selected=1;
    -				print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected?' checked="checked"':'').'>';
    +			print '<td align="right" nowrap="nowrap">';
    +			if (! empty($conf->use_javascript_ajax) && $user->rights->produit->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
    +				print ajax_object_onoff($product_static, 'status', 'tosell', 'ProductStatusOnSell', 'ProductStatusNotOnSell');
    +			} else {
    +				print $product_static->LibStatut($obj->tosell,5,0);
     			}
     			print '</td>';
     			if (! $i) $totalarray['nbfield']++;
    -
    -			print "</tr>\n";
    -			$i++;
     		}
    +		// Status (to buy)
    +		if (! empty($arrayfields['p.tobuy']['checked']))
    +		{
    +			print '<td align="right" nowrap="nowrap">';
    +			if (! empty($conf->use_javascript_ajax) && $user->rights->produit->creer && ! empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
    +				print ajax_object_onoff($product_static, 'status_buy', 'tobuy', 'ProductStatusOnBuy', 'ProductStatusNotOnBuy');
    +			} else {
    +				print $product_static->LibStatut($obj->tobuy,5,1);
    +			}
    +			print '</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
    +		// Action
    +		print '<td class="nowrap" align="center">';
    +		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->rowid, $arrayofselected)) $selected=1;
    +			print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected?' checked="checked"':'').'>';
    +		}
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
     
    -		$db->free($resql);
    -
    -		print "</table>";
    -		print "</div>";
    +		print "</tr>\n";
    +		$i++;
     	}
    +
    +	$db->free($resql);
    +
    +	print "</table>";
    +	print "</div>";
     	print '</form>';
     }
     else
    @@ -981,6 +985,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/note.php b/htdocs/product/note.php
    index c0e9d77ea83..8bf30c3d6e0 100644
    --- a/htdocs/product/note.php
    +++ b/htdocs/product/note.php
    @@ -115,6 +115,7 @@ if ($id > 0 || ! empty($ref))
         dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/product/popuprop.php b/htdocs/product/popuprop.php
    index d6aa23fe2c0..0d54808ecef 100644
    --- a/htdocs/product/popuprop.php
    +++ b/htdocs/product/popuprop.php
    @@ -207,6 +207,6 @@ print "</table>";
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/price.php b/htdocs/product/price.php
    index 70e09114669..561e6663b42 100644
    --- a/htdocs/product/price.php
    +++ b/htdocs/product/price.php
    @@ -5,8 +5,8 @@
      * Copyright (C) 2005-2017	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2006		Andre Cianfarani			<acianfa@free.fr>
      * Copyright (C) 2014		Florian Henry			<florian.henry@open-concept.pro>
    - * Copyright (C) 2014-2016	Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2014-2015 	Philippe Grand 		    <philippe.grand@atoo-net.com>
    + * Copyright (C) 2014-2018	Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2014-2018 	Philippe Grand 		    <philippe.grand@atoo-net.com>
      * Copyright (C) 2014		Ion agorria				<ion@agorria.com>
      * Copyright (C) 2015		Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
      * Copyright (C) 2015		Marcos García			<marcosgdf@gmail.com>
    @@ -46,7 +46,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
     }
     
     // Load translation files required by the page
    -$langs->loadLangs(array('products', 'bills', 'companies'));
    +$langs->loadLangs(array('products', 'bills', 'companies', 'other'));
     
     $mesg=''; $error=0; $errors=array();
     
    @@ -465,7 +465,7 @@ if (empty($reshook))
     
     			$result = $db->query($sql);
     		} else {
    -			setEventMessage('delete_price_by_qty Missing Ids','errors');
    +			setEventMessages(('delete_price_by_qty'.$langs->transnoentities(MissingIds)), null,'errors');
     		}
     	}
     
    @@ -478,7 +478,7 @@ if (empty($reshook))
     
     		$result = $db->query($sql);
     		} else {
    -			setEventMessage('delete_all_price_by_qty Missing Ids','errors');
    +			setEventMessages(('delete_price_by_qty'.$langs->transnoentities(MissingIds)), null,'errors');
     		}
     	}
     
    @@ -785,7 +785,6 @@ if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUI
             	else print vatrate($object->tva_tx . ($object->tva_npr ? '*' : ''), true);*/
             	print '</td></tr>';
     		}
    -
     	}
     	else
     	{
    @@ -1109,30 +1108,33 @@ if (! $action || $action == 'delete' || $action == 'showlog_customer_price' || $
     {
     	print "\n" . '<div class="tabsAction">' . "\n";
     
    -	if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
    -	{
    -    	if ($user->rights->produit->creer || $user->rights->service->creer) {
    -    		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateDefaultPrice") . '</a></div>';
    -    	}
    -	}
    +    if ($object->isVariant()) {
    +		if ($user->rights->produit->creer || $user->rights->service->creer) {
    +			print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEditVariants")).'">'.$langs->trans("UpdateDefaultPrice").'</a></div>';
    +		}
    +	} else {
    +		if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateDefaultPrice") . '</a></div>';
    +			}
    +		}
     
    -	if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
    -	{
    -	    if ($user->rights->produit->creer || $user->rights->service->creer) {
    -	 		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=add_customer_price&amp;id=' . $object->id . '">' . $langs->trans("AddCustomerPrice") . '</a></div>';
    -	  	}
    -	}
    +		if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=add_customer_price&amp;id=' . $object->id . '">' . $langs->trans("AddCustomerPrice") . '</a></div>';
    +			}
    +		}
     
    -	if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
    -	{
    -	    if ($user->rights->produit->creer || $user->rights->service->creer) {
    -    		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_vat&amp;id=' . $object->id . '">' . $langs->trans("UpdateVAT") . '</a></div>';
    -    	}
    +		if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_vat&amp;id=' . $object->id . '">' . $langs->trans("UpdateVAT") . '</a></div>';
    +			}
     
    -	    if ($user->rights->produit->creer || $user->rights->service->creer) {
    -    		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateLevelPrices") . '</a></div>';
    -    	}
    -	}
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateLevelPrices") . '</a></div>';
    +			}
    +		}
    +    }
     
     	print "\n</div>\n";
     }
    @@ -1407,7 +1409,6 @@ if ($action == 'edit_price' && $object->getRights()->creer)
     		print '&nbsp;&nbsp;&nbsp;';
     		print '<input type="submit" class="button" name="cancel" value="' . $langs->trans("Cancel") . '"></div>';
     		print '</form>';
    -
     	}
     }
     
    @@ -2193,6 +2194,6 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
    index 9ee9ab0aead..662873b7cf8 100644
    --- a/htdocs/product/reassort.php
    +++ b/htdocs/product/reassort.php
    @@ -317,7 +317,6 @@ if ($resql)
     	        foreach($warehouses_list as &$wh) {
     	            print_liste_field_titre($wh['label'], '', '','','','align="right"');
     	        }
    -
     	    }
     	}
     	if ($virtualdiffersfromphysical) print_liste_field_titre("VirtualStock",$_SERVER["PHP_SELF"], "",$param,"",'align="right"',$sortfield,$sortorder);
    @@ -381,7 +380,7 @@ if ($resql)
     			print $product->stock_theorique;
     			print '</td>';
     		}
    -		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$product->id.'">'.$langs->trans("Movements").'</a></td>';
    +		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?idproduct='.$product->id.'">'.$langs->trans("Movements").'</a></td>';
     		print '<td align="right" class="nowrap">'.$product->LibStatut($objp->statut,5,0).'</td>';
             print '<td align="right" class="nowrap">'.$product->LibStatut($objp->tobuy,5,1).'</td>';
     		print '<td></td>';
    @@ -395,13 +394,12 @@ if ($resql)
     	print '</form>';
     
     	$db->free($resql);
    -
     }
     else
     {
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
    index 3a58924108d..24aa1864a02 100644
    --- a/htdocs/product/reassortlot.php
    +++ b/htdocs/product/reassortlot.php
    @@ -408,7 +408,7 @@ if ($resql)
             //if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
     		print $objp->stock_physique;
     		print '</td>';
    -		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$product_static->id.'&search_warehouse='.$objp->fk_entrepot.'&search_batch='.($objp->batch != 'Undefined' ? $objp->batch : 'Undefined').'">'.$langs->trans("Movements").'</a></td>';
    +		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?idproduct='.$product_static->id.'&search_warehouse='.$objp->fk_entrepot.'&search_batch='.($objp->batch != 'Undefined' ? $objp->batch : 'Undefined').'">'.$langs->trans("Movements").'</a></td>';
     		print '<td align="right" class="nowrap">'.$product_static->LibStatut($objp->statut,5,0).'</td>';
             print '<td align="right" class="nowrap">'.$product_static->LibStatut($objp->tobuy,5,1).'</td>';
             print '<td></td>';
    @@ -421,13 +421,12 @@ if ($resql)
     	print '</form>';
     
     	$db->free($resql);
    -
     }
     else
     {
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/card.php b/htdocs/product/stats/card.php
    index dd12d9d7bf2..e7c50e8309e 100644
    --- a/htdocs/product/stats/card.php
    +++ b/htdocs/product/stats/card.php
    @@ -433,6 +433,6 @@ if (! $id)
         dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php
    index 77941d940df..f85fb375b5a 100644
    --- a/htdocs/product/stats/commande.php
    +++ b/htdocs/product/stats/commande.php
    @@ -257,5 +257,6 @@ if ($id > 0 || ! empty($ref))
     	dol_print_error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php
    index da5c8f24911..ed49d34fbc3 100644
    --- a/htdocs/product/stats/commande_fournisseur.php
    +++ b/htdocs/product/stats/commande_fournisseur.php
    @@ -265,5 +265,6 @@ if ($id > 0 || ! empty($ref)) {
     	dol_print_error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/contrat.php b/htdocs/product/stats/contrat.php
    index c01cbd40530..55ae3a29939 100644
    --- a/htdocs/product/stats/contrat.php
    +++ b/htdocs/product/stats/contrat.php
    @@ -236,6 +236,6 @@ else
     	dol_print_error();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/facture.php b/htdocs/product/stats/facture.php
    index d0c75ac90b4..fa4e468a5f9 100644
    --- a/htdocs/product/stats/facture.php
    +++ b/htdocs/product/stats/facture.php
    @@ -278,5 +278,6 @@ if ($id > 0 || ! empty($ref))
     	dol_print_error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php
    index 6bd722220ba..b3f8d1e41c0 100644
    --- a/htdocs/product/stats/facture_fournisseur.php
    +++ b/htdocs/product/stats/facture_fournisseur.php
    @@ -263,5 +263,6 @@ if ($id > 0 || ! empty($ref))
     	dol_print_error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/propal.php b/htdocs/product/stats/propal.php
    index 80256037dfe..a58bb01961e 100644
    --- a/htdocs/product/stats/propal.php
    +++ b/htdocs/product/stats/propal.php
    @@ -261,5 +261,6 @@ if ($id > 0 || ! empty($ref))
     	dol_print_error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stats/supplier_proposal.php b/htdocs/product/stats/supplier_proposal.php
    index cac015171cf..ca165a7cfd1 100644
    --- a/htdocs/product/stats/supplier_proposal.php
    +++ b/htdocs/product/stats/supplier_proposal.php
    @@ -260,5 +260,6 @@ if ($id > 0 || ! empty($ref))
     	dol_print_error();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php
    index 41e70a6fbf9..25e22faabcc 100644
    --- a/htdocs/product/stock/card.php
    +++ b/htdocs/product/stock/card.php
    @@ -298,12 +298,11 @@ else
     				$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("DeleteAWarehouse"),$langs->trans("ConfirmDeleteWarehouse",$object->libelle),"confirm_delete",'',0,2);
     			}
     
    -			if (! $formconfirm) {
    -			    $parameters = array();
    -			    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -			    if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -			    elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -			}
    +			// Call Hook formConfirm
    +			$parameters = array();
    +			$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +			if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +			elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     			// Print form confirm
     			print $formconfirm;
    @@ -333,7 +332,6 @@ else
     				print '<tr><td>'.$langs->trans("ParentWarehouse").'</td><td>';
     				print $e->getNomUrl(3);
     				print '</td></tr>';
    -
     			}
     
     			// Description
    @@ -385,7 +383,7 @@ else
     			if ($lastmovementdate)
     			{
     			    print dol_print_date($lastmovementdate,'dayhour').' ';
    -			    print '(<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$object->id.'">'.$langs->trans("FullList").'</a>)';
    +			    print '(<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$object->id.'">'.$langs->trans("FullList").'</a>)';
     			}
     			else
     			{
    @@ -568,7 +566,6 @@ else
                     print '<td class="liste_total">&nbsp;</td>';
     				print '<td class="liste_total">&nbsp;</td>';
     				print '</tr>';
    -
     			}
     			else
     			{
    @@ -659,7 +656,6 @@ else
     			print '</div>';
     
     			print '</form>';
    -
     		}
     	}
     }
    @@ -707,7 +703,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
     	}
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php
    index 16d21c02eb3..2dc45a262ab 100644
    --- a/htdocs/product/stock/class/api_stockmovements.class.php
    +++ b/htdocs/product/stock/class/api_stockmovements.class.php
    @@ -93,7 +93,8 @@ class StockMovements extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -153,15 +154,15 @@ class StockMovements extends DolibarrApi
     		return $obj_ret;
         }
     
    -/*
    -    * @param   int     $product_id         Id product id {@min 1}
    -    * @param   int     $warehouse_id       Id warehouse {@min 1}
    -    * @param   float   $qty                Qty to add (Use negative value for a stock decrease) {@min 0} {@message qty must be higher than 0}
    -    * @param   string  $lot                Lot
    -    * @param   string  $movementcode       Movement code {@example INV123}
    -    * @param   string  $movementlabel      Movement label {@example Inventory number 123}
    -    * @param   string  $price              To update AWP (Average Weighted Price) when you make a stock increase (qty must be higher then 0).
    -    */
    +    /*
    +     * @param   int     $product_id         Id product id {@min 1}
    +     * @param   int     $warehouse_id       Id warehouse {@min 1}
    +     * @param   float   $qty                Qty to add (Use negative value for a stock decrease) {@min 0} {@message qty must be higher than 0}
    +     * @param   string  $lot                Lot
    +     * @param   string  $movementcode       Movement code {@example INV123}
    +     * @param   string  $movementlabel      Movement label {@example Inventory number 123}
    +     * @param   string  $price              To update AWP (Average Weighted Price) when you make a stock increase (qty must be higher then 0).
    +     */
     
     
         /**
    @@ -279,7 +280,8 @@ class StockMovements extends DolibarrApi
          * @param   MouvementStock  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/product/stock/class/api_warehouses.class.php b/htdocs/product/stock/class/api_warehouses.class.php
    index 10b76d22a25..91ee105acb7 100644
    --- a/htdocs/product/stock/class/api_warehouses.class.php
    +++ b/htdocs/product/stock/class/api_warehouses.class.php
    @@ -92,7 +92,8 @@ class Warehouses extends DolibarrApi
          *
     	 * @throws RestException
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -248,7 +249,8 @@ class Warehouses extends DolibarrApi
          * @param   Entrepot  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php
    index 039918ea66c..3f298aed85d 100644
    --- a/htdocs/product/stock/class/entrepot.class.php
    +++ b/htdocs/product/stock/class/entrepot.class.php
    @@ -33,8 +33,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class Entrepot extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='stock';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='entrepot';
    +
     	public $picto='stock';
     
     	/**
    @@ -52,18 +60,32 @@ class Entrepot extends CommonObject
     	 */
     	const STATUS_OPEN_INTERNAL = 2;
     
    -	var $libelle;
    -	var $description;
    -	var $statut;
    -	var $lieu;
    -	var $address;
    +	public $libelle;
    +
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +	public $statut;
    +	public $lieu;
    +
    +	/**
    +	 * @var string Address
    +	 */
    +	public $address;
    +
     	//! Code Postal
    -	var $zip;
    -	var $town;
    -	var $fk_parent;
    +	public $zip;
    +	public $town;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_parent;
     
     	// List of short language codes for status
    -	var $statuts = array();
    +	public $statuts = array();
     
     	/**
     	 *  Constructor
    @@ -85,7 +107,6 @@ class Entrepot extends CommonObject
     		{
     			$this->statuts[self::STATUS_OPEN_ALL] = 'Opened';
     		}
    -
     	}
     
     	/**
    @@ -159,7 +180,6 @@ class Entrepot extends CommonObject
     			$this->db->rollback();
     			return -1;
     		}
    -
     	}
     
     	/**
    @@ -293,7 +313,6 @@ class Entrepot extends CommonObject
     			$this->error=$this->db->lasterror();
     			return -1;
     		}
    -
     	}
     
     
    @@ -397,11 +416,9 @@ class Entrepot extends CommonObject
     
     				$this->date_creation     = $this->db->jdate($obj->datec);
     				$this->date_modification = $this->db->jdate($obj->datem);
    -
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -410,6 +427,7 @@ class Entrepot extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of all warehouses
     	 *
    @@ -418,6 +436,7 @@ class Entrepot extends CommonObject
     	 */
     	function list_array($status=1)
     	{
    +        // phpcs:enable
     		$liste = array();
     
     		$sql = "SELECT rowid, ref as label";
    @@ -441,6 +460,7 @@ class Entrepot extends CommonObject
     		return $liste;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return number of unique different product into a warehouse
     	 *
    @@ -448,6 +468,7 @@ class Entrepot extends CommonObject
     	 */
     	function nb_different_products()
     	{
    +        // phpcs:enable
     		$ret=array();
     
     		$sql = "SELECT count(distinct p.rowid) as nb";
    @@ -473,6 +494,7 @@ class Entrepot extends CommonObject
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return stock and value of warehosue
     	 *
    @@ -480,6 +502,7 @@ class Entrepot extends CommonObject
     	 */
     	function nb_products()
     	{
    +        // phpcs:enable
     		$ret=array();
     
     		$sql = "SELECT sum(ps.reel) as nb, sum(ps.reel * p.pmp) as value";
    @@ -517,6 +540,7 @@ class Entrepot extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return label of a given status
     	 *
    @@ -526,6 +550,7 @@ class Entrepot extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$langs->load('stocks');
    @@ -643,6 +668,7 @@ class Entrepot extends CommonObject
             $this->country_code='FR';
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return full path to current warehouse
     	 *
    @@ -650,6 +676,7 @@ class Entrepot extends CommonObject
     	 */
     	function get_full_arbo()
     	{
    +        // phpcs:enable
             global $user,$langs,$conf;
     
             $TArbo = array(empty($this->label)?$this->libelle:$this->label);
    @@ -683,14 +710,17 @@ class Entrepot extends CommonObject
             return implode(' >> ', array_reverse($TArbo));
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return array of children warehouses ids from $id warehouse (recursive function)
     	 *
     	 * @param	int		$id					id parent warehouse
    -	 * @param	array()	$TChildWarehouses	array which will contain all children (param by reference)
    -	 * @return	array()	$TChildWarehouses	array which will contain all children
    +	 * @param	array	$TChildWarehouses	array which will contain all children (param by reference)
    +	 * @return	array	$TChildWarehouses	array which will contain all children
     	 */
    -	function get_children_warehouses($id, &$TChildWarehouses) {
    +    function get_children_warehouses($id, &$TChildWarehouses)
    +    {
    +        // phpcs:enable
     
     		$sql = 'SELECT rowid
     				FROM '.MAIN_DB_PREFIX.'entrepot
    @@ -705,9 +735,8 @@ class Entrepot extends CommonObject
     		}
     
     		return $TChildWarehouses;
    -
     	}
    -	
    +
     	/**
     	 *	Create object on disk
     	 *
    @@ -739,5 +768,4 @@ class Entrepot extends CommonObject
     
     		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
     	}
    -
     }
    diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
    index 825034b87cb..7991477e146 100644
    --- a/htdocs/product/stock/class/mouvementstock.class.php
    +++ b/htdocs/product/stock/class/mouvementstock.class.php
    @@ -34,6 +34,7 @@ class MouvementStock extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'stockmouvement';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
    @@ -43,14 +44,34 @@ class MouvementStock extends CommonObject
     	public $product_id;
     	public $warehouse_id;
     	public $qty;
    +
    +	/**
    +	 * @var int Type of movement
    +	 * 0=input (stock increase by a stock transfer), 1=output (stock decrease after by a stock transfer),
    +	 * 2=output (stock decrease), 3=input (stock increase)
    +	 * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2.
    +	 */
     	public $type;
     
     	public $tms = '';
     	public $datem = '';
     	public $price;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    -	public $label;
    +
    +	/**
    +     * @var string stock movements label
    +     */
    +    public $label;
    +
    +    /**
    +     * @var int ID
    +     */
     	public $fk_origin;
    +
     	public $origintype;
     	public $inventorycode;
     	public $batch;
    @@ -448,7 +469,6 @@ class MouvementStock extends CommonObject
     				{
     					$fk_product_stock = $this->db->last_insert_id(MAIN_DB_PREFIX."product_stock");
     				}
    -
     			}
     
     			// Update detail stock for batch product
    @@ -777,8 +797,8 @@ 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
    -	 *                                     - or complete array('fk_product_stock'=>, 'batchnumber'=>)
    +	 *                                    - int if row id of product_batch table
    +	 *                                    - 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
     	 */
    @@ -857,6 +877,7 @@ class MouvementStock extends CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return Url link of origin object
     	 *
    @@ -866,6 +887,7 @@ class MouvementStock extends CommonObject
     	 */
     	function get_origin($fk_origin, $origintype)
     	{
    +        // phpcs:enable
     	    $origin='';
     
     		switch ($origintype) {
    @@ -985,7 +1007,7 @@ class MouvementStock extends CommonObject
     		$label.= '<br><b>' . $langs->trans('Qty') . ':</b> ' .$this->qty;
     		$label.= '</div>';
     
    -		$link = '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$this->warehouse_id.'&msid='.$this->id.'"';
    +		$link = '<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$this->warehouse_id.'&msid='.$this->id.'"';
     		$link.= ($notooltip?'':' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip'.($morecss?' '.$morecss:'').'"');
     		$link.= '>';
     		$linkend='</a>';
    @@ -1010,6 +1032,7 @@ class MouvementStock extends CommonObject
     		return $this->LibStatut($mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un status donne
     	 *
    @@ -1018,29 +1041,26 @@ class MouvementStock extends CommonObject
     	 */
     	function LibStatut($mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
    -		if ($mode == 0)
    +		if ($mode == 0 || $mode == 1)
     		{
     			return $langs->trans('StatusNotApplicable');
     		}
    -		if ($mode == 1)
    -		{
    -			return $langs->trans('StatusNotApplicable');
    -		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			return img_picto($langs->trans('StatusNotApplicable'),'statut9').' '.$langs->trans('StatusNotApplicable');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			return img_picto($langs->trans('StatusNotApplicable'),'statut9');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			return img_picto($langs->trans('StatusNotApplicable'),'statut9').' '.$langs->trans('StatusNotApplicable');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			return $langs->trans('StatusNotApplicable').' '.img_picto($langs->trans('StatusNotApplicable'),'statut9');
     		}
    @@ -1059,7 +1079,7 @@ class MouvementStock extends CommonObject
     	public function generateDocument($modele, $outputlangs='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
     		global $conf,$user,$langs;
    -	
    +
     		$langs->load("stocks");
     
     		if (! dol_strlen($modele)) {
    diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php
    index 2ac89def512..d61630eb88e 100644
    --- a/htdocs/product/stock/class/productlot.class.php
    +++ b/htdocs/product/stock/class/productlot.class.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
      * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) ---Put here your own copyright and developer email---
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -39,6 +39,7 @@ class Productlot extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'productlot';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
    @@ -46,6 +47,10 @@ class Productlot extends CommonObject
     
     	public $picto='barcode';
     
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
         public $ismultientitymanaged = 1;
     
     	/**
    @@ -54,21 +59,32 @@ class Productlot extends CommonObject
     	public $lines = array();
     
     	/**
    +	 * @var int Entity
     	 */
    -
     	public $entity;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
     	public $batch;
     	public $eatby = '';
     	public $sellby = '';
     	public $datec = '';
     	public $tms = '';
    -	public $fk_user_creat;
    -	public $fk_user_modif;
    -	public $import_key;
     
     	/**
    -	 */
    +     * @var int ID
    +     */
    +	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_modif;
    +
    +	public $import_key;
     
     
     	/**
    @@ -99,19 +115,19 @@ class Productlot extends CommonObject
     		// Clean parameters
     
     		if (isset($this->entity)) {
    -			 $this->entity = trim($this->entity);
    +			 $this->entity = (int) $this->entity;
     		}
     		if (isset($this->fk_product)) {
    -			 $this->fk_product = trim($this->fk_product);
    +			 $this->fk_product = (int) $this->fk_product;
     		}
     		if (isset($this->batch)) {
     			 $this->batch = trim($this->batch);
     		}
     		if (isset($this->fk_user_creat)) {
    -			 $this->fk_user_creat = trim($this->fk_user_creat);
    +			 $this->fk_user_creat = (int) $this->fk_user_creat;
     		}
     		if (isset($this->fk_user_modif)) {
    -			 $this->fk_user_modif = trim($this->fk_user_modif);
    +			 $this->fk_user_modif = (int) $this->fk_user_modif;
     		}
     		if (isset($this->import_key)) {
     			 $this->import_key = trim($this->import_key);
    @@ -280,19 +296,19 @@ class Productlot extends CommonObject
     		// Clean parameters
     
     		if (isset($this->entity)) {
    -			 $this->entity = trim($this->entity);
    +			 $this->entity = (int) $this->entity;
     		}
     		if (isset($this->fk_product)) {
    -			 $this->fk_product = trim($this->fk_product);
    +			 $this->fk_product = (int) $this->fk_product;
     		}
     		if (isset($this->batch)) {
     			 $this->batch = trim($this->batch);
     		}
     		if (isset($this->fk_user_creat)) {
    -			 $this->fk_user_creat = trim($this->fk_user_creat);
    +			 $this->fk_user_creat = (int) $this->fk_user_creat;
     		}
     		if (isset($this->fk_user_modif)) {
    -			 $this->fk_user_modif = trim($this->fk_user_modif);
    +			 $this->fk_user_modif = (int) $this->fk_user_modif;
     		}
     		if (isset($this->import_key)) {
     			 $this->import_key = trim($this->import_key);
    @@ -342,9 +358,6 @@ class Productlot extends CommonObject
     		}
     
     		if (!$error && !$notrigger) {
    -			// Uncomment this and change MYOBJECT to your own tag if you
    -			// want this action calls a trigger.
    -
     			// Call triggers
     			$result=$this->call_trigger('PRODUCTLOT_MODIFY',$user);
     			if ($result < 0) { $error++; }
    @@ -379,8 +392,8 @@ class Productlot extends CommonObject
     
     		$this->db->begin();
     
    -		if (!$error) {
    -			if (!$notrigger) {
    +		//if (!$error) {
    +			//if (!$notrigger) {
     				// Uncomment this and change MYOBJECT to your own tag if you
     				// want this action calls a trigger.
     
    @@ -388,8 +401,8 @@ class Productlot extends CommonObject
     				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
     				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
     				//// End call triggers
    -			}
    -		}
    +			//}
    +		//}
     
     		if (!$error) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
    @@ -474,6 +487,7 @@ class Productlot extends CommonObject
     	    return $this->LibStatut(0,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return label of a given status
     	 *
    @@ -483,6 +497,7 @@ class Productlot extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     	    global $langs;
     
     	    //$langs->load('stocks');
    @@ -569,17 +584,15 @@ class Productlot extends CommonObject
     	{
     		$this->id = 0;
     
    -		$this->entity = '';
    -		$this->fk_product = '';
    +		$this->entity = null;
    +		$this->fk_product = null;
     		$this->batch = '';
     		$this->eatby = '';
     		$this->sellby = '';
     		$this->datec = '';
     		$this->tms = '';
    -		$this->fk_user_creat = '';
    -		$this->fk_user_modif = '';
    +		$this->fk_user_creat = null;
    +		$this->fk_user_modif = null;
     		$this->import_key = '';
     	}
    -
     }
    -
    diff --git a/htdocs/product/stock/class/productstockentrepot.class.php b/htdocs/product/stock/class/productstockentrepot.class.php
    index cbca4e5854d..aaae328de48 100644
    --- a/htdocs/product/stock/class/productstockentrepot.class.php
    +++ b/htdocs/product/stock/class/productstockentrepot.class.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2014-2016  Juanjo Menent       <jmenent@2byte.es>
      * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) ---Put here your own copyright and developer email---
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -44,24 +44,28 @@ class ProductStockEntrepot extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'ProductStockEntrepot';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'product_warehouse_properties';
     
    -	/**
    -	 */
    -
     	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_entrepot;
    +
     	public $seuil_stock_alerte;
     	public $desiredstock;
     	public $import_key;
     
    -	/**
    -	 */
    -
     
     	/**
     	 * Constructor
    @@ -89,8 +93,8 @@ class ProductStockEntrepot extends CommonObject
     
     		// Clean parameters
     
    -		if (isset($this->fk_product)) $this->fk_product = trim($this->fk_product);
    -		if (isset($this->fk_entrepot)) $this->fk_entrepot = trim($this->fk_entrepot);
    +		if (isset($this->fk_product)) $this->fk_product = (int) $this->fk_product;
    +		if (isset($this->fk_entrepot)) $this->fk_entrepot = (int) $this->fk_entrepot;
     		if (isset($this->seuil_stock_alerte)) $this->seuil_stock_alerte = trim($this->seuil_stock_alerte);
     		if (isset($this->desiredstock)) $this->desiredstock = trim($this->desiredstock);
     		if (isset($this->import_key)) $this->import_key = trim($this->import_key);
    @@ -131,7 +135,7 @@ class ProductStockEntrepot extends CommonObject
     		if (!$error) {
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     
    -			if (!$notrigger) {
    +			//if (!$notrigger) {
     				// Uncomment this and change MYOBJECT to your own tag if you
     				// want this action to call a trigger.
     
    @@ -139,7 +143,7 @@ class ProductStockEntrepot extends CommonObject
     				//$result=$this->call_trigger('MYOBJECT_CREATE',$user);
     				//if ($result < 0) $error++;
     				//// End call triggers
    -			}
    +			//}
     		}
     
     		// Commit or rollback
    @@ -198,8 +202,6 @@ class ProductStockEntrepot extends CommonObject
     				$this->seuil_stock_alerte = $obj->seuil_stock_alerte;
     				$this->desiredstock = $obj->desiredstock;
     				$this->import_key = $obj->import_key;
    -
    -
     			}
     
     			// Retreive all extrafield
    @@ -313,8 +315,8 @@ class ProductStockEntrepot extends CommonObject
     
     		// Clean parameters
     
    -		if (isset($this->fk_product)) $this->fk_product = trim($this->fk_product);
    -		if (isset($this->fk_entrepot)) $this->fk_entrepot = trim($this->fk_entrepot);
    +		if (isset($this->fk_product)) $this->fk_product = (int) $this->fk_product;
    +		if (isset($this->fk_entrepot)) $this->fk_entrepot = (int) $this->fk_entrepot;
     		if (isset($this->seuil_stock_alerte)) $this->seuil_stock_alerte = trim($this->seuil_stock_alerte);
     		if (isset($this->desiredstock)) $this->desiredstock = trim($this->desiredstock);
     		if (isset($this->import_key)) $this->import_key = trim($this->import_key);
    @@ -345,7 +347,7 @@ class ProductStockEntrepot extends CommonObject
     			dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
     		}
     
    -		if (!$error && !$notrigger) {
    +		//if (!$error && !$notrigger) {
     			// Uncomment this and change MYOBJECT to your own tag if you
     			// want this action calls a trigger.
     
    @@ -353,7 +355,7 @@ class ProductStockEntrepot extends CommonObject
     			//$result=$this->call_trigger('MYOBJECT_MODIFY',$user);
     			//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
     			//// End call triggers
    -		}
    +		//}
     
     		// Commit or rollback
     		if ($error) {
    @@ -383,8 +385,7 @@ class ProductStockEntrepot extends CommonObject
     
     		$this->db->begin();
     
    -		if (!$error) {
    -			if (!$notrigger) {
    +		//if (!$error && !$notrigger) {
     				// Uncomment this and change MYOBJECT to your own tag if you
     				// want this action calls a trigger.
     
    @@ -392,8 +393,7 @@ class ProductStockEntrepot extends CommonObject
     				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
     				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
     				//// End call triggers
    -			}
    -		}
    +		//}
     
     		if (!$error) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
    @@ -516,6 +516,7 @@ class ProductStockEntrepot extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un status donne
     	 *
    @@ -525,38 +526,38 @@ class ProductStockEntrepot extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
    -			$prefix='';
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
     	}
     
    @@ -572,13 +573,10 @@ class ProductStockEntrepot extends CommonObject
     		$this->id = 0;
     
     		$this->tms = '';
    -		$this->fk_product = '';
    -		$this->fk_entrepot = '';
    +		$this->fk_product = null;
    +		$this->fk_entrepot = null;
     		$this->seuil_stock_alerte = '';
     		$this->desiredstock = '';
     		$this->import_key = '';
    -
    -
     	}
    -
     }
    diff --git a/htdocs/product/stock/fiche-valo.php b/htdocs/product/stock/fiche-valo.php
    index 400c6183ca4..d815e56a00b 100644
    --- a/htdocs/product/stock/fiche-valo.php
    +++ b/htdocs/product/stock/fiche-valo.php
    @@ -140,5 +140,6 @@ if ($_GET["id"])
     	print "</div>";
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stock/index.php b/htdocs/product/stock/index.php
    index fd2c1d48168..c85f40ef9c2 100644
    --- a/htdocs/product/stock/index.php
    +++ b/htdocs/product/stock/index.php
    @@ -97,7 +97,6 @@ if ($result)
                 $i++;
             }
             $db->free($result);
    -
         }
         print "</table>";
     }
    @@ -143,7 +142,7 @@ if ($resql)
     		print '<th>'.$langs->trans("EatByDate").'</th>';
     	}
     	print '<th>'.$langs->trans("Warehouse").'</th>';
    -	print '<th align="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/product/stock/mouvement.php">'.$langs->trans("FullList").'</a></th>';
    +	print '<th align="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/product/stock/movement_list.php">'.$langs->trans("FullList").'</a></th>';
     	print "</tr>\n";
     
     	$i=0;
    @@ -185,6 +184,6 @@ if ($resql)
     //print '</td></tr></table>';
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/info.php b/htdocs/product/stock/info.php
    index 4653a56495d..065dd448a8d 100644
    --- a/htdocs/product/stock/info.php
    +++ b/htdocs/product/stock/info.php
    @@ -73,6 +73,6 @@ dol_print_object_info($object);
     
     print '</div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php
    index aba8655fae1..ca6cad1d664 100644
    --- a/htdocs/product/stock/list.php
    +++ b/htdocs/product/stock/list.php
    @@ -271,7 +271,6 @@ else
       dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php
    index eae89aca648..e456f966cf5 100644
    --- a/htdocs/product/stock/massstockmove.php
    +++ b/htdocs/product/stock/massstockmove.php
    @@ -161,7 +161,7 @@ if ($action == 'createmovements')
     	if (! GETPOST("label"))
     	{
     		$error++;
    -		setEventMessages($langs->trans("ErrorFieldRequired"),$langs->transnoentitiesnoconv("LabelMovement"), null, 'errors');
    +		setEventMessages($langs->trans("ErrorFieldRequired"),$langs->transnoentitiesnoconv("MovementLabel"), null, 'errors');
     	}
     
     	$db->begin();
    @@ -334,8 +334,6 @@ $buttonrecordnoent=$langs->transnoentitiesnoconv("RecordMovement");
     print '<span class="opacitymedium">'.$langs->trans("SelectProductInAndOutWareHouse",$titletoaddnoent,$buttonrecordnoent).'</span><br>';
     print '<br>'."\n";
     
    -$var=true;
    -
     // Form to add a line
     print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">';
     print '<input type="hidden" name="token" value="' .$_SESSION['newtoken'] . '">';
    @@ -402,8 +400,6 @@ print '</tr>';
     
     foreach($listofdata as $key => $val)
     {
    -
    -
     	$productstatic->fetch($val['id_product']);
     	$warehousestatics->fetch($val['id_sw']);
     	$warehousestatict->fetch($val['id_tw']);
    @@ -455,7 +451,7 @@ print '<table class="noborder" width="100%">';
     	print '</td>';
     	print '</tr>';
     	print '<tr>';
    -	print '<td>'.$langs->trans("LabelMovement").'</td>';
    +	print '<td>'.$langs->trans("MovementLabel").'</td>';
     	print '<td>';
     	print '<input type="text" name="label" class="quatrevingtpercent" value="'.dol_escape_htmltag($labelmovement).'">';
     	print '</td>';
    @@ -466,7 +462,6 @@ print '<div class="center"><input class="button" type="submit" name="valid" valu
     
     print '</form>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/movement_list.php
    similarity index 96%
    rename from htdocs/product/stock/mouvement.php
    rename to htdocs/product/stock/movement_list.php
    index 410396a152b..27c50d075aa 100644
    --- a/htdocs/product/stock/mouvement.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -20,7 +20,7 @@
      */
     
     /**
    - *	\file       htdocs/product/stock/mouvement.php
    + *	\file       htdocs/product/stock/movement_list.php
      *	\ingroup    stock
      *	\brief      Page to list stock movements
      */
    @@ -43,7 +43,7 @@ if (! empty($conf->projet->enabled))
     }
     
     // Load translation files required by the page
    -$langs->loadLangs(array('products', 'stocks'));
    +$langs->loadLangs(array('products', 'stocks', 'orders'));
     if (! empty($conf->productbatch->enabled)) $langs->load("productbatch");
     
     // Security check
    @@ -103,8 +103,8 @@ $arrayfields=array(
         'e.ref'=>array('label'=>$langs->trans("Warehouse"), 'checked'=>1, 'enabled'=>(! $id > 0)),	// If we are on specific warehouse, we hide it
         'm.fk_user_author'=>array('label'=>$langs->trans("Author"), 'checked'=>0),
         'm.inventorycode'=>array('label'=>$langs->trans("InventoryCodeShort"), 'checked'=>1),
    -    'm.label'=>array('label'=>$langs->trans("LabelMovement"), 'checked'=>1),
    -    'm.type_mouvement'=>array('label'=>$langs->trans("Type Mouvement"), 'checked'=>1),
    +    'm.label'=>array('label'=>$langs->trans("MovementLabel"), 'checked'=>1),
    +    'm.type_mouvement'=>array('label'=>$langs->trans("TypeMovement"), 'checked'=>1),
         'origin'=>array('label'=>$langs->trans("Origin"), 'checked'=>1),
     	'm.value'=>array('label'=>$langs->trans("Qty"), 'checked'=>1),
     	'm.price'=>array('label'=>$langs->trans("UnitPurchaseValue"), 'checked'=>0),
    @@ -385,7 +385,7 @@ if ($action == "transfert_stock" && ! $cancel)
                     }
                     else
                     {
    -                    header("Location: mouvement.php?id=".$object->id);
    +                    header("Location: movement_list.php?id=".$object->id);
                         exit;
                     }
                 }
    @@ -478,11 +478,11 @@ if (! empty($search_movement))      $sql.= natural_search('m.label', $search_mov
     if (! empty($search_inventorycode)) $sql.= natural_search('m.inventorycode', $search_inventorycode);
     if (! empty($search_product_ref))   $sql.= natural_search('p.ref', $search_product_ref);
     if (! empty($search_product))       $sql.= natural_search('p.label', $search_product);
    -if ($search_warehouse > 0)          $sql.= " AND e.rowid = '".$db->escape($search_warehouse)."'";
    +if ($search_warehouse != '' && $search_warehouse != '-1')          $sql.= natural_search('e.rowid', $search_warehouse, 2);
     if (! empty($search_user))          $sql.= natural_search('u.login', $search_user);
     if (! empty($search_batch))         $sql.= natural_search('m.batch', $search_batch);
     if ($search_qty != '')				$sql.= natural_search('m.value', $search_qty, 1);
    -if ($search_type_mouvement)	$sql.= " AND m.type_mouvement = '".$db->escape($search_type_mouvement)."'";
    +if ($search_type_mouvement != '' && $search_type_mouvement != '-1')	$sql.= natural_search('m.type_mouvement', $search_type_mouvement, 2);
     // Add where from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
     // Add where from hooks
    @@ -579,8 +579,10 @@ if ($resql)
     
             print '<table class="border" width="100%">';
     
    +        print '<tr>';
    +
             // Description
    -        print '<tr><td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'.dol_htmlentitiesbr($object->description).'</td></tr>';
    +        print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'.dol_htmlentitiesbr($object->description).'</td></tr>';
     
             $calcproductsunique=$object->nb_different_products();
             $calcproducts=$object->nb_products();
    @@ -841,13 +843,14 @@ if ($resql)
     	    // Type of movement
     	    print '<td class="liste_titre" align="center">';
     	    //print '<input class="flat" type="text" size="3" name="search_type_mouvement" value="'.dol_escape_htmltag($search_type_mouvement).'">';
    -		print '<select name="search_type_mouvement">';
    +		print '<select id="search_type_mouvement" name="search_type_mouvement" class="maxwidth150">';
     		print '<option value="" '.(($search_type_mouvement=="")?'selected="selected"':'').'></option>';
    -		print '<option value="0" '.(($search_type_mouvement=="0")?'selected="selected"':'').'>0</option>';
    -		print '<option value="1" '.(($search_type_mouvement=="1")?'selected="selected"':'').'>1</option>';
    -		print '<option value="2" '.(($search_type_mouvement=="2")?'selected="selected"':'').'>2</option>';
    -		print '<option value="3" '.(($search_type_mouvement=="3")?'selected="selected"':'').'>3</option>';
    +		print '<option value="0" '.(($search_type_mouvement=="0")?'selected="selected"':'').'>'.$langs->trans('StockIncreaseAfterCorrectTransfer').'</option>';
    +		print '<option value="1" '.(($search_type_mouvement=="1")?'selected="selected"':'').'>'.$langs->trans('StockDecreaseAfterCorrectTransfer').'</option>';
    +		print '<option value="2" '.(($search_type_mouvement=="2")?'selected="selected"':'').'>'.$langs->trans('StockDecrease').'</option>';
    +		print '<option value="3" '.(($search_type_mouvement=="3")?'selected="selected"':'').'>'.$langs->trans('StockIncrease').'</option>';
     		print '</select>';
    +		print ajax_combobox('search_type_mouvement');
     		// TODO: add new function $formentrepot->selectTypeOfMovement(...) like
     		// print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200');
     	    print '</td>';
    @@ -966,7 +969,7 @@ if ($resql)
     			$origin = '';
     		}
     
    -        print "<tr>";
    +        print '<tr class="oddeven">';
             // Id movement
             if (! empty($arrayfields['m.rowid']['checked']))
             {
    @@ -980,7 +983,7 @@ if ($resql)
             if (! empty($arrayfields['p.ref']['checked']))
             {
     	        // Product ref
    -	        print '<td>';
    +	        print '<td class="nowraponall">';
     	        print $productstatic->getNomUrl(1,'stock',16);
     	        print "</td>\n";
             }
    @@ -997,7 +1000,7 @@ if ($resql)
             }
             if (! empty($arrayfields['m.batch']['checked']))
             {
    -	    	print '<td align="center">';
    +	    	print '<td class="center nowraponall">';
     	    	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 '</td>';
    @@ -1027,7 +1030,15 @@ if ($resql)
             if (! empty($arrayfields['m.inventorycode']['checked']))
             {
     	        // Inventory code
    -	        print '<td>'.$objp->inventorycode.'</td>';
    +	        print '<td>'.'<a href="'
    +								.DOL_URL_ROOT.'/product/stock/movement_list.php'
    +								.'?id='.$objp->entrepot_id
    +								.'&amp;search_inventorycode='.$objp->inventorycode
    +							    .'&amp;search_type_mouvement='.$objp->type_mouvement
    +						.'">'
    +							.$objp->inventorycode
    +						.'</a>'
    +					.'</td>';
             }
             if (! empty($arrayfields['m.label']['checked']))
             {
    @@ -1042,7 +1053,7 @@ if ($resql)
             if (! empty($arrayfields['origin']['checked']))
             {
             	// Origin of movement
    -        	print '<td>'.$origin.'</td>';
    +        	print '<td class="nowraponall">'.$origin.'</td>';
             }
             if (! empty($arrayfields['m.value']['checked']))
             {
    @@ -1165,7 +1176,6 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete' && $id>0)
     }
     */
     
    +// End of page
     llxFooter();
    -
     $db->close();
    -
    diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
    index 7c18dc11281..beb3135d9f4 100644
    --- a/htdocs/product/stock/product.php
    +++ b/htdocs/product/stock/product.php
    @@ -1,13 +1,14 @@
     <?php
    -/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    +/* Copyright (C) 2001-2007  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2004      Eric Seigne          <eric.seigne@ryxeo.com>
      * Copyright (C) 2005      Simon TOSSER         <simon@kornog-computing.com>
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2013      Cédric Salvador      <csalvador.gpcsolutions.fr>
    - * Copyright (C) 2013-2015 Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2013-2018 Juanjo Menent	    <jmenent@2byte.es>
      * Copyright (C) 2014-2015 Cédric Gross         <c.gross@kreiz-it.fr>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -44,6 +45,13 @@ if (! empty($conf->projet->enabled))
     	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     }
     
    +if (! empty($conf->variants->enabled)) {
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttribute.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttributeValue.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination2ValuePair.class.php';
    +}
    +
     // Load translation files required by the page
     $langs->loadlangs(array('products', 'orders', 'bills', 'stocks', 'sendings'));
     if (! empty($conf->productbatch->enabled)) $langs->load("productbatch");
    @@ -80,10 +88,9 @@ $extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
     if ($id > 0 || ! empty($ref))
     {
         $result = $object->fetch($id, $ref);
    -
     }
     
    -if(empty($id) && !empty($object->id)) $id = $object->id; 
    +if(empty($id) && !empty($object->id)) $id = $object->id;
     
     $modulepart='product';
     
    @@ -135,8 +142,7 @@ if ($action == 'addlimitstockwarehouse' && !empty($user->rights->produit->creer)
     			// Update
     			$pse->seuil_stock_alerte = $seuil_stock_alerte;
     			$pse->desiredstock  	 = $desiredstock;
    -			if($pse->update($user) > 0) setEventMessage($langs->trans('ProductStockWarehouseUpdated'));
    -
    +			if($pse->update($user) > 0) setEventMessages($langs->trans('ProductStockWarehouseUpdated'), null, 'mesgs');
     		} else {
     
     			// Create
    @@ -144,15 +150,12 @@ if ($action == 'addlimitstockwarehouse' && !empty($user->rights->produit->creer)
     			$pse->fk_product  	 	 = $id;
     			$pse->seuil_stock_alerte = GETPOST('seuil_stock_alerte');
     			$pse->desiredstock  	 = GETPOST('desiredstock');
    -			if($pse->create($user) > 0) setEventMessage($langs->trans('ProductStockWarehouseCreated'));
    -
    +			if($pse->create($user) > 0) setEventMessages($langs->trans('ProductStockWarehouseCreated'), null, 'mesgs');
     		}
    -
     	}
     
     	header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
     	exit;
    -
     }
     
     if($action == 'delete_productstockwarehouse' && !empty($user->rights->produit->creer))
    @@ -160,10 +163,9 @@ if($action == 'delete_productstockwarehouse' && !empty($user->rights->produit->c
     
     	$pse = new ProductStockEntrepot($db);
     	$pse->fetch(GETPOST('fk_productstockwarehouse'));
    -	if($pse->delete($user) > 0) setEventMessage($langs->trans('ProductStockWarehouseDeleted'));
    +	if($pse->delete($user) > 0) setEventMessages($langs->trans('ProductStockWarehouseDeleted'), null, 'mesgs');
     
     	$action = '';
    -
     }
     
     // Set stock limit
    @@ -176,7 +178,7 @@ if ($action == 'setseuil_stock_alerte' && !empty($user->rights->produit->creer))
         if ($result < 0)
         	setEventMessages($object->error, $object->errors, 'errors');
         //else
    -    //	setEventMessage($lans->trans("SavedRecordSuccessfully"));
    +    //	setEventMessages($lans->trans("SavedRecordSuccessfully"), null, 'mesgs');
         $action='';
     }
     
    @@ -517,6 +519,8 @@ if ($id > 0 || $ref)
     	$object = new Product($db);
     	$result = $object->fetch($id,$ref);
     
    +	$variants = $object->hasVariants();
    +
     	$object->load_stock();
     
     	$title = $langs->trans('ProductServiceCard');
    @@ -557,174 +561,161 @@ if ($id > 0 || $ref)
             print '<div class="underbanner clearboth"></div>';
             print '<table class="border tableforfield" width="100%">';
     
    -		if ($conf->productbatch->enabled)
    -		{
    -			print '<tr><td class="titlefield">'.$langs->trans("ManageLotSerial").'</td><td>';
    -			print $object->getLibStatut(0,2);
    -			print '</td></tr>';
    -		}
    +		if (! $variants) {
     
    -		// PMP
    -		print '<tr><td class="titlefield">'.$langs->trans("AverageUnitPricePMP").'</td>';
    -		print '<td>';
    -		if ($object->pmp > 0) print price($object->pmp).' '.$langs->trans("HT");
    -		print '</td>';
    -		print '</tr>';
    +			if ($conf->productbatch->enabled) {
    +				print '<tr><td class="titlefield">' . $langs->trans("ManageLotSerial") . '</td><td>';
    +				print $object->getLibStatut(0, 2);
    +				print '</td></tr>';
    +			}
     
    -		// Minimum Price
    -		print '<tr><td>'.$langs->trans("BuyingPriceMin").'</td>';
    -		print '<td>';
    -		$product_fourn = new ProductFournisseur($db);
    -		if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0)
    -		{
    -			if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur();
    -			else print $langs->trans("NotDefined");
    -		}
    -		print '</td></tr>';
    +			// PMP
    +			print '<tr><td class="titlefield">' . $langs->trans("AverageUnitPricePMP") . '</td>';
    +			print '<td>';
    +			if ($object->pmp > 0) print price($object->pmp) . ' ' . $langs->trans("HT");
    +			print '</td>';
    +			print '</tr>';
     
    -		if (empty($conf->global->PRODUIT_MULTIPRICES))
    -		{
    -			// Price
    -			print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    -			if ($object->price_base_type == 'TTC') {
    -				print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
    -			} else {
    -				print price($object->price) . ' ' . $langs->trans($object->price_base_type);
    +			// Minimum Price
    +			print '<tr><td>' . $langs->trans("BuyingPriceMin") . '</td>';
    +			print '<td>';
    +			$product_fourn = new ProductFournisseur($db);
    +			if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0) {
    +				if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur();
    +				else print $langs->trans("NotDefined");
     			}
     			print '</td></tr>';
     
    -			// Price minimum
    -			print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    -			if ($object->price_base_type == 'TTC') {
    -				print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
    +			if (empty($conf->global->PRODUIT_MULTIPRICES)) {
    +				// Price
    +				print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    +				if ($object->price_base_type == 'TTC') {
    +					print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
    +				} else {
    +					print price($object->price) . ' ' . $langs->trans($object->price_base_type);
    +				}
    +				print '</td></tr>';
    +
    +				// Price minimum
    +				print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    +				if ($object->price_base_type == 'TTC') {
    +					print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
    +				} else {
    +					print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
    +				}
    +				print '</td></tr>';
     			} else {
    -				print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
    +				// Price
    +				print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    +				print $langs->trans("Variable");
    +				print '</td></tr>';
    +
    +				// Price minimum
    +				print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    +				print $langs->trans("Variable");
    +				print '</td></tr>';
     			}
    -			print '</td></tr>';
    -		}
    -		else
    -		{
    -			// Price
    -			print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    -			print $langs->trans("Variable");
    +
    +			// Stock alert threshold
    +			print '<tr><td>' . $form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1), 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer) . '</td><td>';
    +			print $form->editfieldval("StockLimit", 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer, 'string');
     			print '</td></tr>';
     
    -			// Price minimum
    -			print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    -			print $langs->trans("Variable");
    +			// Hook formObject
    +			$parameters = array();
    +			$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
    +			print $hookmanager->resPrint;
    +
    +			// Desired stock
    +			print '<tr><td>' . $form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1), 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer);
    +			print '</td><td>';
    +			print $form->editfieldval("DesiredStock", 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer, 'string');
     			print '</td></tr>';
    +
    +			// Real stock
    +			$text_stock_options = $langs->trans("RealStockDesc") . '<br>';
    +			$text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen") . '<br>';
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? $langs->trans("DeStockOnShipment") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? $langs->trans("DeStockOnValidateOrder") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? $langs->trans("DeStockOnBill") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? $langs->trans("ReStockOnBill") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? $langs->trans("ReStockOnValidateOrder") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? $langs->trans("ReStockOnDispatchOrder") . '<br>' : '');
    +			print '<tr><td>';
    +			print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1);
    +			print '</td>';
    +			print '<td>' . price2num($object->stock_reel, 'MS');
    +			if ($object->seuil_stock_alerte != '' && ($object->stock_reel < $object->seuil_stock_alerte)) print ' ' . img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    +			print '</td>';
    +			print '</tr>';
    +
    +			$stocktheo = price2num($object->stock_theorique, 'MS');
    +
    +			$found = 0;
    +			$helpondiff = '<strong>' . $langs->trans("StockDiffPhysicTeoric") . ':</strong><br>';
    +			// Number of customer orders running
    +			if (!empty($conf->commande->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$helpondiff .= $langs->trans("ProductQtyInCustomersOrdersRunning") . ': ' . $object->stats_commande['qty'];
    +				$result = $object->load_stats_commande(0, '0', 1);
    +				if ($result < 0) dol_print_error($db, $object->error);
    +				$helpondiff .= ' (' . $langs->trans("ProductQtyInDraft") . ': ' . $object->stats_commande['qty'] . ')';
    +			}
    +
    +			// Number of product from customer order already sent (partial shipping)
    +			if (!empty($conf->expedition->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$result = $object->load_stats_sending(0, '2', 1);
    +				$helpondiff .= $langs->trans("ProductQtyInShipmentAlreadySent") . ': ' . $object->stats_expedition['qty'];
    +			}
    +
    +			// Number of supplier order running
    +			if (!empty($conf->fournisseur->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$result = $object->load_stats_commande_fournisseur(0, '3,4', 1);
    +				$helpondiff .= $langs->trans("ProductQtyInSuppliersOrdersRunning") . ': ' . $object->stats_commande_fournisseur['qty'];
    +				$result = $object->load_stats_commande_fournisseur(0, '0,1,2', 1);
    +				if ($result < 0) dol_print_error($db, $object->error);
    +				$helpondiff .= ' (' . $langs->trans("ProductQtyInDraftOrWaitingApproved") . ': ' . $object->stats_commande_fournisseur['qty'] . ')';
    +			}
    +
    +			// Number of product from supplier order already received (partial receipt)
    +			if (!empty($conf->fournisseur->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$helpondiff .= $langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied") . ': ' . $object->stats_reception['qty'];
    +			}
    +
    +			// Calculating a theorical value
    +			print '<tr><td>';
    +			print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc"));
    +			print '</td>';
    +			print "<td>";
    +			//print (empty($stocktheo)?0:$stocktheo);
    +			print $form->textwithpicto((empty($stocktheo) ? 0 : $stocktheo), $helpondiff);
    +			if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' ' . img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    +			print '</td>';
    +			print '</tr>';
    +
    +			// Last movement
    +			$sql = "SELECT max(m.datem) as datem";
    +			$sql .= " FROM " . MAIN_DB_PREFIX . "stock_mouvement as m";
    +			$sql .= " WHERE m.fk_product = '" . $object->id . "'";
    +			$resqlbis = $db->query($sql);
    +			if ($resqlbis) {
    +				$obj = $db->fetch_object($resqlbis);
    +				$lastmovementdate = $db->jdate($obj->datem);
    +			} else {
    +				dol_print_error($db);
    +			}
    +			print '<tr><td class="tdtop">' . $langs->trans("LastMovement") . '</td><td>';
    +			if ($lastmovementdate) {
    +				print dol_print_date($lastmovementdate, 'dayhour') . ' ';
    +				print '(<a href="' . DOL_URL_ROOT . '/product/stock/movement_list.php?idproduct=' . $object->id . '">' . $langs->trans("FullList") . '</a>)';
    +			} else {
    +				print '<a href="' . DOL_URL_ROOT . '/product/stock/movement_list.php?idproduct=' . $object->id . '">' . $langs->trans("None") . '</a>';
    +			}
    +			print "</td></tr>";
     		}
    -
    -        // Stock alert threshold
    -        print '<tr><td>'.$form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1),'seuil_stock_alerte',$object->seuil_stock_alerte,$object,$user->rights->produit->creer).'</td><td>';
    -        print $form->editfieldval("StockLimit",'seuil_stock_alerte',$object->seuil_stock_alerte,$object,$user->rights->produit->creer,'string');
    -        print '</td></tr>';
    -
    -		// Hook formObject
    -		$parameters=array();
    -		$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
    -		print $hookmanager->resPrint;
    -
    -        // Desired stock
    -        print '<tr><td>'.$form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1),'desiredstock',$object->desiredstock,$object,$user->rights->produit->creer);
    -        print '</td><td>';
    -        print $form->editfieldval("DesiredStock",'desiredstock',$object->desiredstock,$object,$user->rights->produit->creer,'string');
    -        print '</td></tr>';
    -
    -        // Real stock
    -        $text_stock_options = $langs->trans("RealStockDesc").'<br>';
    -        $text_stock_options.= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)?$langs->trans("DeStockOnShipment").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_BILL)?$langs->trans("DeStockOnBill").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)?$langs->trans("ReStockOnBill").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)?$langs->trans("ReStockOnValidateOrder").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)?$langs->trans("ReStockOnDispatchOrder").'<br>':'');
    -        print '<tr><td>';
    -        print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1);
    -        print '</td>';
    -		print '<td>'.price2num($object->stock_reel, 'MS');
    -		if ($object->seuil_stock_alerte != '' && ($object->stock_reel < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    -		print '</td>';
    -		print '</tr>';
    -
    -		$stocktheo = price2num($object->stock_theorique, 'MS');
    -
    -		$found=0;
    -		$helpondiff='<strong>'.$langs->trans("StockDiffPhysicTeoric").':</strong><br>';
    -		// Number of customer orders running
    -		if (! empty($conf->commande->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $helpondiff.=$langs->trans("ProductQtyInCustomersOrdersRunning").': '.$object->stats_commande['qty'];
    -		    $result=$object->load_stats_commande(0,'0', 1);
    -		    if ($result < 0) dol_print_error($db,$object->error);
    -		    $helpondiff.=' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')';
    -		}
    -
    -		// Number of product from customer order already sent (partial shipping)
    -		if (! empty($conf->expedition->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $result=$object->load_stats_sending(0,'2', 1);
    -		    $helpondiff.=$langs->trans("ProductQtyInShipmentAlreadySent").': '.$object->stats_expedition['qty'];
    -		}
    -
    -		// Number of supplier order running
    -		if (! empty($conf->fournisseur->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $result=$object->load_stats_commande_fournisseur(0,'3,4', 1);
    -		    $helpondiff.=$langs->trans("ProductQtyInSuppliersOrdersRunning").': '.$object->stats_commande_fournisseur['qty'];
    -		    $result=$object->load_stats_commande_fournisseur(0,'0,1,2', 1);
    -		    if ($result < 0) dol_print_error($db,$object->error);
    -		    $helpondiff.=' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')';
    -		}
    -
    -		// Number of product from supplier order already received (partial receipt)
    -		if (! empty($conf->fournisseur->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $helpondiff.=$langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied").': '.$object->stats_reception['qty'];
    -		}
    -
    -        // Calculating a theorical value
    -        print '<tr><td>';
    -        print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc"));
    -        print '</td>';
    -        print "<td>";
    -        //print (empty($stocktheo)?0:$stocktheo);
    -        print $form->textwithpicto((empty($stocktheo)?0:$stocktheo), $helpondiff);
    -        if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    -        print '</td>';
    -        print '</tr>';
    -
    -		// Last movement
    -		$sql = "SELECT max(m.datem) as datem";
    -		$sql.= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
    -		$sql.= " WHERE m.fk_product = '".$object->id."'";
    -		$resqlbis = $db->query($sql);
    -		if ($resqlbis)
    -		{
    -			$obj = $db->fetch_object($resqlbis);
    -			$lastmovementdate=$db->jdate($obj->datem);
    -		}
    -		else
    -		{
    -			dol_print_error($db);
    -		}
    -		print '<tr><td class="tdtop">'.$langs->trans("LastMovement").'</td><td>';
    -		if ($lastmovementdate)
    -		{
    -		    print dol_print_date($lastmovementdate,'dayhour').' ';
    -		    print '(<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$object->id.'">'.$langs->trans("FullList").'</a>)';
    -		}
    -		else
    -		{
    -		     print '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$object->id.'">'.$langs->trans("None").'</a>';
    -		}
    -		print "</td></tr>";
    -
     		print "</table>";
     
             print '</div>';
    @@ -769,231 +760,325 @@ if (empty($reshook))
     	{
     	    print "<div class=\"tabsAction\">\n";
     
    -	    if ($user->rights->stock->mouvement->creer)
    -	    {
    -	        print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=correction">'.$langs->trans("CorrectStock").'</a>';
    -	    }
    -
    -	    //if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch())
    -	    if ($user->rights->stock->mouvement->creer)
    +		if ($user->rights->stock->mouvement->creer)
     		{
    -			print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=transfert">'.$langs->trans("TransferStock").'</a>';
    +			if (! $variants) {
    +				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=correction">' . $langs->trans("CorrectStock") . '</a>';
    +			}
    +			else
    +			{
    +				print '<a class="butActionRefused" href="#" title="'.$langs->trans("ActionAvailableOnVariantProductOnly").'">' . $langs->trans("CorrectStock") . '</a>';
    +			}
    +		}
    +		else
    +		{
    +			print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">' . $langs->trans("CorrectStock") . '</a>';
    +		}
    +
    +		//if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch())
    +		if ($user->rights->stock->mouvement->creer)
    +		{
    +			if (! $variants) {
    +				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=transfert">' . $langs->trans("TransferStock") . '</a>';
    +			}
    +			else
    +			{
    +				print '<a class="butActionRefused" href="#" title="'.$langs->trans("ActionAvailableOnVariantProductOnly").'">' . $langs->trans("TransferStock") . '</a>';
    +			}
    +		}
    +		else
    +		{
    +			print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">' . $langs->trans("CorrectStock") . '</a>';
     		}
     
     		print '</div>';
     	}
    -
     }
     
     
    -/*
    - * Stock detail (by warehouse). May go down into batch details.
    - */
    +if (! $variants) {
    +	/*
    +	 * Stock detail (by warehouse). May go down into batch details.
    +	 */
     
    -print '<div class="div-table-responsive">';
    -print '<table class="noborder" width="100%">';
    -print '<tr class="liste_titre">';
    -print '<td colspan="4">'.$langs->trans("Warehouse").'</td>';
    -print '<td align="right">'.$langs->trans("NumberOfUnit").'</td>';
    -print '<td align="right">'.$langs->trans("AverageUnitPricePMPShort").'</td>';
    -print '<td align="right">'.$langs->trans("EstimatedStockValueShort").'</td>';
    -print '<td align="right">'.$langs->trans("SellPriceMin").'</td>';
    -print '<td align="right">'.$langs->trans("EstimatedStockValueSellShort").'</td>';
    -print '</tr>';
    -if ((! empty($conf->productbatch->enabled)) && $object->hasbatch())
    -{
    -	print '<tr class="liste_titre"><td width="10%"></td>';
    -	print '<td align="right" width="10%">'.$langs->trans("batch_number").'</td>';
    -	print '<td align="center" width="10%">'.$langs->trans("EatByDate").'</td>';
    -	print '<td align="center" width="10%">'.$langs->trans("SellByDate").'</td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '</tr>';
    -}
    -
    -$sql = "SELECT e.rowid, e.ref as label, e.lieu, ps.reel, ps.rowid as product_stock_id, p.pmp";
    -$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
    -$sql.= " ".MAIN_DB_PREFIX."product_stock as ps";
    -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = ps.fk_product";
    -$sql.= " WHERE ps.reel != 0";
    -$sql.= " AND ps.fk_entrepot = e.rowid";
    -$sql.= " AND e.entity IN (".getEntity('stock').")";
    -$sql.= " AND ps.fk_product = ".$object->id;
    -$sql.= " ORDER BY e.ref";
    -
    -$entrepotstatic=new Entrepot($db);
    -$product_lot_static=new Productlot($db);
    -
    -$total=0;
    -$totalvalue=$totalvaluesell=0;
    -
    -$resql=$db->query($sql);
    -if ($resql)
    -{
    -	$num = $db->num_rows($resql);
    -	$total=$totalwithpmp;
    -	$i=0; $var=false;
    -	while ($i < $num)
    -	{
    -		$obj = $db->fetch_object($resql);
    -		$entrepotstatic->id=$obj->rowid;
    -		$entrepotstatic->libelle=$obj->label;
    -		$entrepotstatic->lieu=$obj->lieu;
    -		$stock_real = price2num($obj->reel, 'MS');
    -		print '<tr class="oddeven">';
    -		print '<td colspan="4">'.$entrepotstatic->getNomUrl(1).'</td>';
    -		print '<td align="right">'.$stock_real.($stock_real < 0 ?' '.img_warning():'').'</td>';
    -		// PMP
    -		print '<td align="right">'.(price2num($object->pmp)?price2num($object->pmp,'MU'):'').'</td>';
    -		// Value purchase
    -		print '<td align="right">'.(price2num($object->pmp)?price(price2num($object->pmp*$obj->reel,'MT')):'').'</td>';
    -        // Sell price
    -		print '<td align="right">';
    -        if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price,'MU'),1);
    -        else print $langs->trans("Variable");
    -        print '</td>';
    -        // Value sell
    -        print '<td align="right">';
    -        if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price*$obj->reel,'MT'),1).'</td>';
    -        else print $langs->trans("Variable");
    -		print '</tr>'; ;
    -		$total += $obj->reel;
    -		if (price2num($object->pmp)) $totalwithpmp += $obj->reel;
    -		$totalvalue = $totalvalue + ($object->pmp*$obj->reel);
    -        $totalvaluesell = $totalvaluesell + ($object->price*$obj->reel);
    -		// Batch Detail
    -		if ((! empty($conf->productbatch->enabled)) && $object->hasbatch())
    -		{
    -			$details=Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id);
    -			if ($details<0) dol_print_error($db);
    -			foreach ($details as $pdluo)
    -			{
    -				$product_lot_static->id = $pdluo->lotid;
    -				$product_lot_static->batch = $pdluo->batch;
    -				$product_lot_static->eatby = $pdluo->eatby;
    -				$product_lot_static->sellby = $pdluo->sellby;
    -
    -			    if ($action == 'editline' && GETPOST('lineid','int') == $pdluo->id)
    -			    { //Current line edit
    -			        print "\n".'<tr>';
    -			        print '<td colspan="9">';
    -			        print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    -			        print '<input type="hidden" name="pdluoid" value="'.$pdluo->id.'"><input type="hidden" name="action" value="updateline"><input type="hidden" name="id" value="'.$id.'"><table class="noborder" width="100%"><tr><td width="10%"></td>';
    -			        print '<td align="right" width="10%"><input type="text" name="batch_number" value="'.$pdluo->batch.'"></td>';
    -			        print '<td align="center" width="10%">';
    -			        $form->select_date($pdluo->eatby,'eatby','','',1,'',1,0,1);
    -			        print '</td>';
    -			        print '<td align="center" width="10%">';
    -			        $form->select_date($pdluo->sellby,'sellby','','',1,'',1,0,1);
    -			        print '</td>';
    -			        print '<td align="right" width="10%">'.$pdluo->qty.($pdluo->qty<0?' '.img_warning():'').'</td>';
    -			        print '<td colspan="4"><input type="submit" class="button" id="savelinebutton" name="save" value="'.$langs->trans("Save").'">';
    -		            print '<input type="submit" class="button" id="cancellinebutton" name="Cancel" value="'.$langs->trans("Cancel").'"></td></tr>';
    -			        print '</table>';
    -			        print '</form>';
    -			        print '</td></tr>';
    -			    }
    -			    else
    -				{
    -                    print "\n".'<tr><td align="right">';
    -                    print img_picto($langs->trans("Tranfer"),'uparrow','class="hideonsmartphone"').' ';
    -					print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;id_entrepot='.$entrepotstatic->id.'&amp;action=transfert&amp;pdluoid='.$pdluo->id.'">'.$langs->trans("TransferStock").'</a>';
    -					// Disabled, because edition of stock content must use the "Correct stock menu".
    -					// Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ...
    -                    //print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=editline&amp;lineid='.$pdluo->id.'#'.$pdluo->id.'">';
    -                    //print img_edit().'</a></td>';
    -                    print '<td align="right">';
    -                    print $product_lot_static->getNomUrl(1);
    -                    print '</td>';
    -                    print '<td align="center">'. dol_print_date($pdluo->eatby,'day') .'</td>';
    -                    print '<td align="center">'. dol_print_date($pdluo->sellby,'day') .'</td>';
    -                    print '<td align="right">'.$pdluo->qty.($pdluo->qty<0?' '.img_warning():'').'</td>';
    -                    print '<td colspan="4"></td></tr>';
    -			    }
    -			}
    -		}
    -		$i++;
    -
    -	}
    -}
    -else dol_print_error($db);
    -
    -print '<tr class="liste_total"><td align="right" class="liste_total" colspan="4">'.$langs->trans("Total").':</td>';
    -print '<td class="liste_total" align="right">'.price2num($total, 'MS').'</td>';
    -print '<td class="liste_total" align="right">';
    -print ($totalwithpmp?price(price2num($totalvalue/$totalwithpmp,'MU')):'&nbsp;');	// This value may have rounding errors
    -print '</td>';
    -// Value purchase
    -print '<td class="liste_total" align="right">';
    -print $totalvalue?price(price2num($totalvalue,'MT'),1):'&nbsp;';
    -print '</td>';
    -print '<td class="liste_total" align="right">';
    -if (empty($conf->global->PRODUIT_MULTIPRICES)) print ($total?price($totalvaluesell/$total,1):'&nbsp;');
    -else print $langs->trans("Variable");
    -print '</td>';
    -// Value to sell
    -print '<td class="liste_total" align="right">';
    -if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalvaluesell,'MT'),1);
    -else print $langs->trans("Variable");
    -print '</td>';
    -print "</tr>";
    -print "</table>";
    -print '</div>';
    -
    -if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE))
    -{
    -	print '<br><br>';
    -	print_titre($langs->trans('AddNewProductStockWarehouse'));
    -
    -	if (!empty($user->rights->produit->creer)){
    -		print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    -		print '<input type="hidden" name="action" value="addlimitstockwarehouse">';
    -		print '<input type="hidden" name="id" value="'.$id.'">';
    -	}
    +	print '<div class="div-table-responsive">';
     	print '<table class="noborder" width="100%">';
    -	if (!empty($user->rights->produit->creer)){
    -		print '<tr class="liste_titre"><td width="40%">'.$formproduct->selectWarehouses('', 'fk_entrepot').'</td>';
    -		print '<td align="right"><input name="seuil_stock_alerte" type="text" placeholder="'.$langs->trans("StockLimit").'" /></td>';
    -		print '<td align="right"><input name="desiredstock" type="text" placeholder="'.$langs->trans("DesiredStock").'" /></td>';
    -		print '<td align="right"><input type="submit" value="'.$langs->trans('Save').'" class="button" /></td>';
    -		print '</tr>';
    -	}else{
    -		print '<tr class="liste_titre"><td width="40%">'.$langs->trans("Warehouse").'</td>';
    -		print '<td align="right">'.$langs->trans("StockLimit").'</td>';
    -		print '<td align="right">'.$langs->trans("DesiredStock").'</td>';
    +	print '<tr class="liste_titre">';
    +	print '<td colspan="4">' . $langs->trans("Warehouse") . '</td>';
    +	print '<td align="right">' . $langs->trans("NumberOfUnit") . '</td>';
    +	print '<td align="right">' . $langs->trans("AverageUnitPricePMPShort") . '</td>';
    +	print '<td align="right">' . $langs->trans("EstimatedStockValueShort") . '</td>';
    +	print '<td align="right">' . $langs->trans("SellPriceMin") . '</td>';
    +	print '<td align="right">' . $langs->trans("EstimatedStockValueSellShort") . '</td>';
    +	print '</tr>';
    +	if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) {
    +		print '<tr class="liste_titre"><td width="10%"></td>';
    +		print '<td align="right" width="10%">' . $langs->trans("batch_number") . '</td>';
    +		print '<td align="center" width="10%">' . $langs->trans("EatByDate") . '</td>';
    +		print '<td align="center" width="10%">' . $langs->trans("SellByDate") . '</td>';
    +		print '<td></td>';
    +		print '<td></td>';
    +		print '<td></td>';
    +		print '<td></td>';
    +		print '<td></td>';
     		print '</tr>';
     	}
     
    -	$pse = new ProductStockEntrepot($db);
    -	$lines = $pse->fetchAll($id);
    +	$sql = "SELECT e.rowid, e.ref as label, e.lieu, ps.reel, ps.rowid as product_stock_id, p.pmp";
    +	$sql .= " FROM " . MAIN_DB_PREFIX . "entrepot as e,";
    +	$sql .= " " . MAIN_DB_PREFIX . "product_stock as ps";
    +	$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = ps.fk_product";
    +	$sql .= " WHERE ps.reel != 0";
    +	$sql .= " AND ps.fk_entrepot = e.rowid";
    +	$sql .= " AND e.entity IN (" . getEntity('stock') . ")";
    +	$sql .= " AND ps.fk_product = " . $object->id;
    +	$sql .= " ORDER BY e.ref";
     
    -	if (!empty($lines))
    -	{
    -		$var=false;
    -		foreach($lines as $line)
    -		{
    -			$ent = new Entrepot($db);
    -			$ent->fetch($line['fk_entrepot']);
    -			print '<tr class="oddeven"><td width="40%">'.$ent->getNomUrl(3).'</td>';
    -			print '<td align="right">'.$line['seuil_stock_alerte'].'</td>';
    -			print '<td align="right">'.$line['desiredstock'].'</td>';
    -			if (!empty($user->rights->produit->creer)){
    -			    print '<td align="right"><a href="?id='.$id.'&fk_productstockwarehouse='.$line['id'].'&action=delete_productstockwarehouse">'.img_delete().'</a></td>';
    +	$entrepotstatic = new Entrepot($db);
    +	$product_lot_static = new Productlot($db);
    +
    +	$total = 0;
    +	$totalvalue = $totalvaluesell = 0;
    +
    +	$resql = $db->query($sql);
    +	if ($resql) {
    +		$num = $db->num_rows($resql);
    +		$total = $totalwithpmp;
    +		$i = 0;
    +		$var = false;
    +		while ($i < $num) {
    +			$obj = $db->fetch_object($resql);
    +			$entrepotstatic->id = $obj->rowid;
    +			$entrepotstatic->libelle = $obj->label;
    +			$entrepotstatic->lieu = $obj->lieu;
    +			$stock_real = price2num($obj->reel, 'MS');
    +			print '<tr class="oddeven">';
    +			print '<td colspan="4">' . $entrepotstatic->getNomUrl(1) . '</td>';
    +			print '<td align="right">' . $stock_real . ($stock_real < 0 ? ' ' . img_warning() : '') . '</td>';
    +			// PMP
    +			print '<td align="right">' . (price2num($object->pmp) ? price2num($object->pmp, 'MU') : '') . '</td>';
    +			// Value purchase
    +			print '<td align="right">' . (price2num($object->pmp) ? price(price2num($object->pmp * $obj->reel, 'MT')) : '') . '</td>';
    +			// Sell price
    +			print '<td align="right">';
    +			if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price, 'MU'), 1);
    +			else print $langs->trans("Variable");
    +			print '</td>';
    +			// Value sell
    +			print '<td align="right">';
    +			if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price * $obj->reel, 'MT'), 1) . '</td>';
    +			else print $langs->trans("Variable");
    +			print '</tr>';;
    +			$total += $obj->reel;
    +			if (price2num($object->pmp)) $totalwithpmp += $obj->reel;
    +			$totalvalue = $totalvalue + ($object->pmp * $obj->reel);
    +			$totalvaluesell = $totalvaluesell + ($object->price * $obj->reel);
    +			// Batch Detail
    +			if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) {
    +				$details = Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id);
    +				if ($details < 0) dol_print_error($db);
    +				foreach ($details as $pdluo) {
    +					$product_lot_static->id = $pdluo->lotid;
    +					$product_lot_static->batch = $pdluo->batch;
    +					$product_lot_static->eatby = $pdluo->eatby;
    +					$product_lot_static->sellby = $pdluo->sellby;
    +
    +					if ($action == 'editline' && GETPOST('lineid', 'int') == $pdluo->id) { //Current line edit
    +						print "\n" . '<tr>';
    +						print '<td colspan="9">';
    +						print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
    +						print '<input type="hidden" name="pdluoid" value="' . $pdluo->id . '"><input type="hidden" name="action" value="updateline"><input type="hidden" name="id" value="' . $id . '"><table class="noborder" width="100%"><tr><td width="10%"></td>';
    +						print '<td align="right" width="10%"><input type="text" name="batch_number" value="' . $pdluo->batch . '"></td>';
    +						print '<td align="center" width="10%">';
    +						print $form->selectDate($pdluo->eatby, 'eatby', '', '', 1, '', 1, 0);
    +						print '</td>';
    +						print '<td align="center" width="10%">';
    +						print $form->selectDate($pdluo->sellby, 'sellby', '', '', 1, '', 1, 0);
    +						print '</td>';
    +						print '<td align="right" width="10%">' . $pdluo->qty . ($pdluo->qty < 0 ? ' ' . img_warning() : '') . '</td>';
    +						print '<td colspan="4"><input type="submit" class="button" id="savelinebutton" name="save" value="' . $langs->trans("Save") . '">';
    +						print '<input type="submit" class="button" id="cancellinebutton" name="Cancel" value="' . $langs->trans("Cancel") . '"></td></tr>';
    +						print '</table>';
    +						print '</form>';
    +						print '</td></tr>';
    +					} else {
    +						print "\n" . '<tr><td align="right">';
    +						print img_picto($langs->trans("Tranfer"), 'uparrow', 'class="hideonsmartphone"') . ' ';
    +						print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;id_entrepot=' . $entrepotstatic->id . '&amp;action=transfert&amp;pdluoid=' . $pdluo->id . '">' . $langs->trans("TransferStock") . '</a>';
    +						// Disabled, because edition of stock content must use the "Correct stock menu".
    +						// Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ...
    +						//print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=editline&amp;lineid='.$pdluo->id.'#'.$pdluo->id.'">';
    +						//print img_edit().'</a></td>';
    +						print '<td align="right">';
    +						print $product_lot_static->getNomUrl(1);
    +						print '</td>';
    +						print '<td align="center">' . dol_print_date($pdluo->eatby, 'day') . '</td>';
    +						print '<td align="center">' . dol_print_date($pdluo->sellby, 'day') . '</td>';
    +						print '<td align="right">' . $pdluo->qty . ($pdluo->qty < 0 ? ' ' . img_warning() : '') . '</td>';
    +						print '<td colspan="4"></td></tr>';
    +					}
    +				}
     			}
    +			$i++;
    +		}
    +	} else dol_print_error($db);
    +
    +	print '<tr class="liste_total"><td align="right" class="liste_total" colspan="4">' . $langs->trans("Total") . ':</td>';
    +	print '<td class="liste_total" align="right">' . price2num($total, 'MS') . '</td>';
    +	print '<td class="liste_total" align="right">';
    +	print ($totalwithpmp ? price(price2num($totalvalue / $totalwithpmp, 'MU')) : '&nbsp;');    // This value may have rounding errors
    +	print '</td>';
    +// Value purchase
    +	print '<td class="liste_total" align="right">';
    +	print $totalvalue ? price(price2num($totalvalue, 'MT'), 1) : '&nbsp;';
    +	print '</td>';
    +	print '<td class="liste_total" align="right">';
    +	if (empty($conf->global->PRODUIT_MULTIPRICES)) print ($total ? price($totalvaluesell / $total, 1) : '&nbsp;');
    +	else print $langs->trans("Variable");
    +	print '</td>';
    +// Value to sell
    +	print '<td class="liste_total" align="right">';
    +	if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalvaluesell, 'MT'), 1);
    +	else print $langs->trans("Variable");
    +	print '</td>';
    +	print "</tr>";
    +	print "</table>";
    +	print '</div>';
    +
    +	if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) {
    +		print '<br><br>';
    +		print_titre($langs->trans('AddNewProductStockWarehouse'));
    +
    +		if (!empty($user->rights->produit->creer)) {
    +			print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
    +			print '<input type="hidden" name="action" value="addlimitstockwarehouse">';
    +			print '<input type="hidden" name="id" value="' . $id . '">';
    +		}
    +		print '<table class="noborder" width="100%">';
    +		if (!empty($user->rights->produit->creer)) {
    +			print '<tr class="liste_titre"><td width="40%">' . $formproduct->selectWarehouses('', 'fk_entrepot') . '</td>';
    +			print '<td align="right"><input name="seuil_stock_alerte" type="text" placeholder="' . $langs->trans("StockLimit") . '" /></td>';
    +			print '<td align="right"><input name="desiredstock" type="text" placeholder="' . $langs->trans("DesiredStock") . '" /></td>';
    +			print '<td align="right"><input type="submit" value="' . $langs->trans('Save') . '" class="button" /></td>';
    +			print '</tr>';
    +		} else {
    +			print '<tr class="liste_titre"><td width="40%">' . $langs->trans("Warehouse") . '</td>';
    +			print '<td align="right">' . $langs->trans("StockLimit") . '</td>';
    +			print '<td align="right">' . $langs->trans("DesiredStock") . '</td>';
     			print '</tr>';
     		}
    -	}
     
    -	print "</table>";
    +		$pse = new ProductStockEntrepot($db);
    +		$lines = $pse->fetchAll($id);
     
    -	if (!empty($user->rights->produit->creer)){ 
    -	    print '</form>'; 
    +		if (!empty($lines)) {
    +			$var = false;
    +			foreach ($lines as $line) {
    +				$ent = new Entrepot($db);
    +				$ent->fetch($line['fk_entrepot']);
    +				print '<tr class="oddeven"><td width="40%">' . $ent->getNomUrl(3) . '</td>';
    +				print '<td align="right">' . $line['seuil_stock_alerte'] . '</td>';
    +				print '<td align="right">' . $line['desiredstock'] . '</td>';
    +				if (!empty($user->rights->produit->creer)) {
    +					print '<td align="right"><a href="?id=' . $id . '&fk_productstockwarehouse=' . $line['id'] . '&action=delete_productstockwarehouse">' . img_delete() . '</a></td>';
    +				}
    +				print '</tr>';
    +			}
    +		}
    +
    +		print "</table>";
    +
    +		if (!empty($user->rights->produit->creer)) {
    +			print '</form>';
    +		}
     	}
    +} else {
    +	// List of variants
    +
    +	$prodstatic = new Product($db);
    +	$prodcomb = new ProductCombination($db);
    +	$comb2val = new ProductCombination2ValuePair($db);
    +	$productCombinations = $prodcomb->fetchAllByFkProductParent($object->id);
    +
    +	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    +	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +	print '<input type="hidden" name="action" value="massaction">';
    +	print '<input type="hidden" name="id" value="'.$id.'">';
    +	print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
    +
    +	// load variants
    +	$title = $langs->trans("ProductCombinations");
    +
    +	print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0);
    +
    +	print '<div class="div-table-responsive">';
    +	?>
    +	<table class="liste">
    +		<tr class="liste_titre">
    +			<td class="liste_titre"><?php echo $langs->trans('Product') ?></td>
    +			<td class="liste_titre"><?php echo $langs->trans('Combination') ?></td>
    +			<td class="liste_titre center"><?php echo $langs->trans('OnSell') ?></td>
    +			<td class="liste_titre center"><?php echo $langs->trans('OnBuy') ?></td>
    +			<td class="liste_titre right"><?php echo $langs->trans('Stock') ?></td>
    +			<td class="liste_titre"></td>
    +		</tr>
    +		<?php
    +
    +		if (count($productCombinations))
    +		{
    +			$stock_total= 0;
    +			foreach ($productCombinations as $currcomb)
    +			{
    +				$prodstatic->fetch($currcomb->fk_product_child);
    +				$prodstatic->load_stock();
    +				$stock_total+=$prodstatic->stock_reel;
    +				?>
    +				<tr class="oddeven">
    +					<td><?php echo $prodstatic->getNomUrl(1) ?></td>
    +					<td>
    +						<?php
    +
    +						$productCombination2ValuePairs = $comb2val->fetchByFkCombination($currcomb->id);
    +						$iMax = count($productCombination2ValuePairs);
    +
    +						for ($i = 0; $i < $iMax; $i++) {
    +							echo dol_htmlentities($productCombination2ValuePairs[$i]);
    +
    +							if ($i !== ($iMax - 1)) {
    +								echo ', ';
    +							}
    +						} ?>
    +					</td>
    +					<td style="text-align: center;"><?php echo $prodstatic->getLibStatut(2, 0) ?></td>
    +					<td style="text-align: center;"><?php echo $prodstatic->getLibStatut(2, 1) ?></td>
    +					<td class="right"><?php echo $prodstatic->stock_reel ?></td>
    +					<td class="right">
    +						<a class="paddingleft paddingright" href="<?php echo dol_buildpath('/product/stock/product.php?id='.$currcomb->fk_product_child, 2) ?>"><?php echo img_edit() ?></a>
    +					</td>
    +					<?php
    +					?>
    +				</tr>
    +				<?php
    +			}
    +
    +			print '<tr class="liste_total">';
    +			print '<td colspan="4" align="left">'.$langs->trans("Total").'</td>';
    +			print '<td align="right">'.$stock_total.'</td>';
    +			print '</tr>';
    +		}
    +		else
    +		{
    +			print '<tr><td colspan="8"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
    +		}
    +		?>
    +	</table>
    +
    +	<?php
    +	print '</div>';
    +
    +	print '</form>';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php
    index 7c2f4f148ad..f72a28dbc90 100644
    --- a/htdocs/product/stock/productlot_card.php
    +++ b/htdocs/product/stock/productlot_card.php
    @@ -256,7 +256,6 @@ if (empty($reshook))
         $upload_dir = $conf->productbatch->multidir_output[$conf->entity];
         $permissioncreate = $usercancreate;
         include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
    -
     }
     
     
    @@ -388,7 +387,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     
     	print '<a href="'.DOL_URL_ROOT.'/product/reassortlot.php?sref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowCurrentStockOfLot").'</a><br>';
     	print '<br>';
    -	print '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?search_product_ref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowLogOfMovementIfLot").'</a><br>';
    +	print '<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?search_product_ref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowLogOfMovementIfLot").'</a><br>';
     
     	print '<br>';
     }
    @@ -414,10 +413,8 @@ if (empty($action))
         $somethingshown=$formfile->numoffiles;
     
         print '</div>';
    -
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stock/productlot_document.php b/htdocs/product/stock/productlot_document.php
    index f79a0d74d98..1ce4f9ba224 100644
    --- a/htdocs/product/stock/productlot_document.php
    +++ b/htdocs/product/stock/productlot_document.php
    @@ -95,7 +95,6 @@ if (empty($reshook))
     
     	// Action submit/delete file/link
     	include_once DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
    -
     }
     
     $permtoedit = $user->rights->produit->creer;
    @@ -122,7 +121,7 @@ if ($object->id)
         print $hookmanager->resPrint;
     	if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     
     	$totalsize=0;
    @@ -156,8 +155,6 @@ if ($object->id)
         $permission = ( $user->rights->produit->creer );
         $param = '&id=' . $object->id;
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
    -
     }
     else
     {
    diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php
    index 479c5a0c15c..4d9916bfa9c 100644
    --- a/htdocs/product/stock/productlot_list.php
    +++ b/htdocs/product/stock/productlot_list.php
    @@ -398,14 +398,12 @@ if ($resql)
     	$productlot = new Productlot($db);
     
     	$i=0;
    -	$var=true;
     	$totalarray=array();
     	while ($i < min($num, $limit))
     	{
     		$obj = $db->fetch_object($resql);
     		if ($obj)
     		{
    -			$var = !$var;
     
     			$productlot->id = $obj->rowid;
     			$productlot->batch = $obj->batch;
    @@ -556,7 +554,6 @@ else
     	dol_print_error($db);
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php
    index 46200a2f6a7..994edfa823e 100644
    --- a/htdocs/product/stock/replenish.php
    +++ b/htdocs/product/stock/replenish.php
    @@ -1,6 +1,6 @@
     <?php
     /* Copyright (C) 2013		Cédric Salvador		<csalvador@gpcsolutions.fr>
    - * Copyright (C) 2013-2016	Laurent Destaileur	<ely@users.sourceforge.net>
    + * Copyright (C) 2013-2018	Laurent Destaileur	<ely@users.sourceforge.net>
      * Copyright (C) 2014		Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2016		Juanjo Menent		<jmenent@2byte.es>
      * Copyright (C) 2016		ATM Consulting		<support@atm-consulting.fr>
    @@ -42,6 +42,9 @@ if ($user->societe_id) {
     }
     $result=restrictedArea($user,'produit|service');
     
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$hookmanager->initHooks(array('stockreplenishlist'));
    +
     //checks if a product has been ordered
     
     $action = GETPOST('action','alpha');
    @@ -86,6 +89,9 @@ if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)
     $usevirtualstock=0;
     if ($mode == 'virtual') $usevirtualstock=1;
     
    +$parameters=array();
    +$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');
     
     /*
      * Actions
    @@ -670,6 +676,11 @@ while ($i < ($limit ? min($num, $limit) : $num))
     	}
     	$i++;
     }
    +
    +$parameters=array('sql'=>$sql);
    +$reshook=$hookmanager->executeHooks('printFieldListFooter',$parameters);    // Note that $action and $object may have been modified by hook
    +print $hookmanager->resPrint;
    +
     print '</table>';
     print '</div>';
     
    diff --git a/htdocs/product/stock/replenishorders.php b/htdocs/product/stock/replenishorders.php
    index 942ca82bc04..316d463fb27 100644
    --- a/htdocs/product/stock/replenishorders.php
    +++ b/htdocs/product/stock/replenishorders.php
    @@ -1,7 +1,8 @@
     <?php
     /*
    - * Copyright (C) 2013	Cédric Salvador	<csalvador@gpcsolutions.fr>
    - * Copyright (C) 2014	Regis Houssin	<regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2014       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -195,76 +196,76 @@ if ($resql)
              '<input type="text" class="flat" name="search_ttc" value="' . dol_escape_htmltag($sttc) . '">'.
              '</td>'.
              '<td class="liste_titre">'.
    -         $form->select_date($search_date, 'search_date', 0, 0, 1, '', 1, 0, 1, 0, '').
    +         $form->selectDate($search_date, 'search_date', 0, 0, 1, '', 1, 0, 0, '').
              '</td>'.
              '<td class="liste_titre" align="right">';
    -         $searchpicto=$form->showFilterAndCheckAddButtons(0);
    -         print $searchpicto;
    -         '</td>'.
    -         '</tr>';
    +    $searchpicto = $form->showFilterAndCheckAddButtons(0);
    +    print $searchpicto;
    +    print '</td>';
    +    print '</tr>';
     
    -         print '<tr class="liste_titre">';
    -         print_liste_field_titre(
    -             'Ref',
    -             $_SERVER['PHP_SELF'],
    -             'cf.ref',
    -             '',
    -             $param,
    -             '',
    -             $sortfield,
    -             $sortorder
    -             );
    -         print_liste_field_titre(
    -             'Company',
    -             $_SERVER['PHP_SELF'],
    -             's.nom',
    -             '',
    -             $param,
    -             '',
    -             $sortfield,
    -             $sortorder
    -             );
    -         print_liste_field_titre(
    -             'Author',
    -             $_SERVER['PHP_SELF'],
    -             'u.login',
    -             '',
    -             '',
    -             '',
    -             $sortfield,
    -             $sortorder
    -             );
    -         print_liste_field_titre(
    -             'AmountTTC',
    -             $_SERVER['PHP_SELF'],
    -             'cf.total_ttc',
    -             '',
    -             $param,
    -             '',
    -             $sortfield,
    -             $sortorder
    -             );
    -         print_liste_field_titre(
    -             'OrderCreation',
    -             $_SERVER['PHP_SELF'],
    -             'cf.date_creation',
    -             '',
    -             $param,
    -             '',
    -             $sortfield,
    -             $sortorder
    -             );
    -         print_liste_field_titre(
    -             'Status',
    -             $_SERVER['PHP_SELF'],
    -             'cf.fk_statut',
    -             '',
    -             $param,
    -             'align="right"',
    -             $sortfield,
    -             $sortorder
    -             );
    -         print '</tr>';
    +    print '<tr class="liste_titre">';
    +    print_liste_field_titre(
    +        'Ref',
    +        $_SERVER['PHP_SELF'],
    +        'cf.ref',
    +        '',
    +        $param,
    +        '',
    +        $sortfield,
    +        $sortorder
    +    );
    +    print_liste_field_titre(
    +        'Company',
    +        $_SERVER['PHP_SELF'],
    +        's.nom',
    +        '',
    +        $param,
    +        '',
    +        $sortfield,
    +        $sortorder
    +    );
    +    print_liste_field_titre(
    +        'Author',
    +        $_SERVER['PHP_SELF'],
    +        'u.login',
    +        '',
    +        '',
    +        '',
    +        $sortfield,
    +        $sortorder
    +    );
    +    print_liste_field_titre(
    +        'AmountTTC',
    +        $_SERVER['PHP_SELF'],
    +        'cf.total_ttc',
    +        '',
    +        $param,
    +        '',
    +        $sortfield,
    +        $sortorder
    +    );
    +    print_liste_field_titre(
    +        'OrderCreation',
    +        $_SERVER['PHP_SELF'],
    +        'cf.date_creation',
    +        '',
    +        $param,
    +        '',
    +        $sortfield,
    +        $sortorder
    +    );
    +    print_liste_field_titre(
    +        'Status',
    +        $_SERVER['PHP_SELF'],
    +        'cf.fk_statut',
    +        '',
    +        $param,
    +        'align="right"',
    +        $sortfield,
    +        $sortorder
    +    );
    +    print '</tr>';
     
         $userstatic = new User($db);
     
    @@ -324,8 +325,8 @@ if ($resql)
             }
             $i++;
         }
    -    print '</table>'.
    -         '</form>';
    +    print '</table>';
    +    print '</form>';
     
         $db->free($resql);
     
    @@ -336,6 +337,6 @@ else
     	dol_print_error($db);
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/stock/tpl/stockcorrection.tpl.php b/htdocs/product/stock/tpl/stockcorrection.tpl.php
    index 3d2e1c99e9b..ce947c2003b 100644
    --- a/htdocs/product/stock/tpl/stockcorrection.tpl.php
    +++ b/htdocs/product/stock/tpl/stockcorrection.tpl.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2010-2017 Laurent Destailleur <eldy@users.sourceforge.net>
    +/* Copyright (C) 2010-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -19,8 +20,7 @@
      */
     
     // Protection to avoid direct call of template
    -if (empty($conf) || ! is_object($conf))
    -{
    +if (empty($conf) || ! is_object($conf)) {
     	print "Error, template page can't be called as URL";
     	exit;
     }
    @@ -119,11 +119,11 @@ if (empty($conf) || ! is_object($conf))
     			print '<tr>';
     			print '<td>'.$langs->trans("EatByDate").'</td><td>';
     			$eatbyselected=dol_mktime(0, 0, 0, GETPOST('eatbymonth'), GETPOST('eatbyday'), GETPOST('eatbyyear'));
    -			$form->select_date($eatbyselected,'eatby','','',1,"");
    +			print $form->selectDate($eatbyselected,'eatby','','',1,"");
     			print '</td>';
     			print '<td>'.$langs->trans("SellByDate").'</td><td>';
     			$sellbyselected=dol_mktime(0, 0, 0, GETPOST('sellbymonth'), GETPOST('sellbyday'), GETPOST('sellbyyear'));
    -			$form->select_date($sellbyselected,'sellby','','',1,"");
    +			print $form->selectDate($sellbyselected,'sellby','','',1,"");
     			print '</td>';
     			print '</tr>';
     		}
    diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php
    index 136f0f0702a..370010b07eb 100644
    --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php
    +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2010-2017 Laurent Destailleur <eldy@users.sourceforge.net>
    +/* Copyright (C) 2010-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -114,10 +115,10 @@ if (empty($conf) || ! is_object($conf))
     
     			print '<tr>';
     			print '<td>'.$langs->trans("EatByDate").'</td><td>';
    -			print $form->select_date(($d_eatby?$d_eatby:$pdluo->eatby),'eatby','','',1,"", 1, 0, 1, ($pdluoid > 0 ? 1 : 0));		// If form was opened for a specific pdluoid, field is disabled
    +			print $form->selectDate(($d_eatby?$d_eatby:$pdluo->eatby),'eatby','','',1,"", 1, 0, ($pdluoid > 0 ? 1 : 0));		// If form was opened for a specific pdluoid, field is disabled
     			print '</td>';
     			print '<td>'.$langs->trans("SellByDate").'</td><td>';
    -			print $form->select_date(($d_sellby?$d_sellby:$pdluo->sellby),'sellby','','',1,"", 1, 0, 1, ($pdluoid > 0 ? 1 : 0));		// If form was opened for a specific pdluoid, field is disabled
    +			print $form->selectDate(($d_sellby?$d_sellby:$pdluo->sellby),'sellby','','',1,"", 1, 0, ($pdluoid > 0 ? 1 : 0));		// If form was opened for a specific pdluoid, field is disabled
     			print '</td>';
     			print '</tr>';
     		}
    diff --git a/htdocs/product/stock/valo.php b/htdocs/product/stock/valo.php
    index be8ee2d500e..09524c5066a 100644
    --- a/htdocs/product/stock/valo.php
    +++ b/htdocs/product/stock/valo.php
    @@ -128,7 +128,6 @@ if ($result)
             print '<td align="right">'.price(price2num($totalsell,'MT'),1,$langs,0,0,-1,$conf->currency).'</td>';
             print '<td align="right">&nbsp;</td>';
             print "</tr>\n";
    -
         }
     
         $db->free($result);
    @@ -150,14 +149,12 @@ if ($result)
             $url=DOL_URL_ROOT.'/viewimage.php?modulepart=graph_stock&amp;file='.$file;
             print '<br><img src="'.$url.'">';
         }
    -
     }
     else
     {
         dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php
    index c96e1c0f025..9f18f644e4c 100644
    --- a/htdocs/product/traduction.php
    +++ b/htdocs/product/traduction.php
    @@ -276,7 +276,6 @@ if ($action == 'edit')
     	print '</div>';
     
     	print '</form>';
    -
     }
     else if ($action != 'add')
     {
    @@ -354,5 +353,6 @@ if ($action == 'add' && ($user->rights->produit->creer || $user->rights->service
     	print '<br>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php
    index 92719093650..e43700287cb 100644
    --- a/htdocs/projet/activity/index.php
    +++ b/htdocs/projet/activity/index.php
    @@ -23,7 +23,7 @@
      *	\brief      Page activite perso du module projet
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -325,7 +325,6 @@ if (! empty($conf->global->PROJECT_TASK_TIME_MONTH))
         		print '</td>';
         		print '<td align="right">'.convertSecondToTime($row->nb, 'allhourmin').'</td>';
         		print "</tr>\n";
    -
         	}
         	$db->free($resql);
         }
    @@ -376,7 +375,6 @@ if (! empty($conf->global->PROJECT_TASK_TIME_YEAR))
     			print '</td>';
     			print '<td align="right">'.convertSecondToTime($row->nb, 'allhourmin').'</td>';
     			print "</tr>\n";
    -
     		}
     		$db->free($resql);
     	}
    @@ -570,13 +568,11 @@ if (empty($conf->global->PROJECT_HIDE_TASKS) && ! empty($conf->global->PROJECT_S
     	{
     		dol_print_error($db);
     	}
    -
     }
     
     
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/activity/perday.php b/htdocs/projet/activity/perday.php
    index 729e60abf61..623838f8149 100644
    --- a/htdocs/projet/activity/perday.php
    +++ b/htdocs/projet/activity/perday.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2004-2016 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2010 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2010      François Legastelois <flegastelois@teclib.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -24,7 +25,7 @@
      *	\brief      List activities of tasks (per day entry)
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -369,7 +370,7 @@ $nav.=dol_print_date(dol_mktime(0,0,0,$month,$day,$year),"%A").' ';
     $nav.=" <span id=\"month_name\">".dol_print_date(dol_mktime(0,0,0,$month,$day,$year),"day")." </span>\n";
     $nav.='<a class="inline-block valignmiddle" href="?year='.$next_year."&amp;month=".$next_month."&amp;day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n";
     $nav.=" &nbsp; (<a href=\"?year=".$nowyear."&amp;month=".$nowmonth."&amp;day=".$nowday.$param."\">".$langs->trans("Today")."</a>)";
    -$nav.='<br>'.$form->select_date(-1,'',0,0,2,"addtime",1,0,1).' ';
    +$nav.='<br>'.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, 0).' ';
     $nav.=' <input type="submit" name="submitdateselect" class="button valignmiddle" value="'.$langs->trans("Refresh").'">';
     
     $picto='calendarweek';
    @@ -713,6 +714,6 @@ if ($conf->use_javascript_ajax)
     	print '</script>';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php
    index 0bf821b9f10..214879c7f92 100644
    --- a/htdocs/projet/activity/perweek.php
    +++ b/htdocs/projet/activity/perweek.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2010 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2010      François Legastelois <flegastelois@teclib.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -24,7 +25,7 @@
      *	\brief      List activities of tasks (per week entry)
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -372,7 +373,7 @@ $nav ='<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$
     $nav.=" <span id=\"month_name\">".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("WeekShort")." ".$week." </span>\n";
     $nav.='<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n";
     $nav.=" &nbsp; (<a href=\"?year=".$nowyear."&month=".$nowmonth."&day=".$nowday.$param."\">".$langs->trans("Today")."</a>)";
    -$nav.='<br>'.$form->select_date(-1,'',0,0,2,"addtime",1,0,1).' ';
    +$nav.='<br>'.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, 0).' ';
     $nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
     
     $picto='calendarweek';
    @@ -751,7 +752,6 @@ if ($conf->use_javascript_ajax)
     	print '</script>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php
    index 80a13582d4d..f82a71514c4 100644
    --- a/htdocs/projet/admin/project.php
    +++ b/htdocs/projet/admin/project.php
    @@ -910,5 +910,6 @@ print '</table>';
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/admin/project_extrafields.php b/htdocs/projet/admin/project_extrafields.php
    index d247408079c..15ccd50bf76 100644
    --- a/htdocs/projet/admin/project_extrafields.php
    +++ b/htdocs/projet/admin/project_extrafields.php
    @@ -30,8 +30,7 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
    -$langs->load("project");
    -$langs->load("admin");
    +$langs->loadLangs(array("project", "admin"));
     
     $extrafields = new ExtraFields($db);
     $form = new Form($db);
    @@ -113,6 +112,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/admin/project_task_extrafields.php b/htdocs/projet/admin/project_task_extrafields.php
    index 32e4af98f89..90729840035 100644
    --- a/htdocs/projet/admin/project_task_extrafields.php
    +++ b/htdocs/projet/admin/project_task_extrafields.php
    @@ -112,6 +112,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php
    index b92df257dd7..7aaa6805189 100644
    --- a/htdocs/projet/card.php
    +++ b/htdocs/projet/card.php
    @@ -333,7 +333,6 @@ if (empty($reshook))
     			if (GETPOST('socid','int') > 0) $object->fetch_thirdparty(GETPOST('socid','int'));
     			else unset($object->thirdparty);
     		}
    -
     	}
     
     	// Build doc
    @@ -472,6 +471,17 @@ $help_url="EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
     
     llxHeader("",$title,$help_url);
     
    +$titleboth=$langs->trans("LeadsOrProjects");
    +$titlenew = $langs->trans("NewLeadOrProject");	// Leads and opportunities by default
    +if ($conf->global->PROJECT_USE_OPPORTUNITIES == 0)
    +{
    +	$titleboth=$langs->trans("Projects");
    +	$titlenew = $langs->trans("NewProject");
    +}
    +if ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) {	// 2 = leads only
    +	$titleboth=$langs->trans("Leads");
    +	$titlenew = $langs->trans("NewLead");
    +}
     
     if ($action == 'create' && $user->rights->projet->creer)
     {
    @@ -482,7 +492,7 @@ if ($action == 'create' && $user->rights->projet->creer)
     	$thirdparty=new Societe($db);
     	if ($socid > 0) $thirdparty->fetch($socid);
     
    -	print load_fiche_titre($langs->trans("NewProject"), '', 'title_project');
    +	print load_fiche_titre($titlenew, '', 'title_project');
     
     	print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
     	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    @@ -569,12 +579,12 @@ if ($action == 'create' && $user->rights->projet->creer)
     
     	// Date start
     	print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
    -	print $form->select_date(($date_start?$date_start:''),'projectstart',0,0,0,'',1,0,1);
    +	print $form->selectDate(($date_start?$date_start:''), 'projectstart', 0, 0, 0, '', 1, 0);
     	print '</td></tr>';
     
     	// Date end
     	print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
    -	print $form->select_date(($date_end?$date_end:-1),'projectend',0,0,0,'',1,0,1);
    +	print $form->selectDate(($date_end?$date_end:-1), 'projectend', 0, 0, 0, '', 1, 0);
     	print '</td></tr>';
     
     	if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
    @@ -822,7 +832,7 @@ elseif ($object->id > 0)
     
     		// Date start
     		print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
    -		print $form->select_date($object->date_start?$object->date_start:-1,'projectstart',0,0,0,'',1,0,1);
    +		print $form->selectDate($object->date_start?$object->date_start:-1, 'projectstart', 0, 0, 0, '', 1, 0);
     		print ' &nbsp; &nbsp; <input type="checkbox" class="valignmiddle" name="reportdate" value="yes" ';
     		if ($comefromclone){print ' checked ';}
     		print '/> '. $langs->trans("ProjectReportDate");
    @@ -830,7 +840,7 @@ elseif ($object->id > 0)
     
     		// Date end
     		print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
    -		print $form->select_date($object->date_end?$object->date_end:-1,'projectend',0,0,0,'',1,0,1);
    +		print $form->selectDate($object->date_end?$object->date_end:-1, 'projectend', 0, 0, 0, '', 1, 0);
     		print '</td></tr>';
     
     		// Budget
    @@ -1289,6 +1299,6 @@ else
     	print $langs->trans("RecordNotFound");
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php
    index ab157bf237c..a1f2ce6d26c 100644
    --- a/htdocs/projet/class/api_projects.class.php
    +++ b/htdocs/projet/class/api_projects.class.php
    @@ -98,7 +98,8 @@ class Projects extends DolibarrApi
          * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
          * @return  array                               Array of project objects
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -214,7 +215,8 @@ class Projects extends DolibarrApi
          *
          * @url	GET {id}/tasks
          */
    -    function getLines($id, $includetimespent=0) {
    +    function getLines($id, $includetimespent=0)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->lire) {
     		  	throw new RestException(401);
     		  }
    @@ -256,7 +258,8 @@ class Projects extends DolibarrApi
          *
          * @return int
          */
    -    function getRoles($id, $userid=0) {
    +    function getRoles($id, $userid=0)
    +    {
             global $db;
     
             if(! DolibarrApiAccess::$user->rights->projet->lire) {
    @@ -300,7 +303,8 @@ class Projects extends DolibarrApi
          * @return int
          */
         /*
    -    function postLine($id, $request_data = null) {
    +    function postLine($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -362,7 +366,8 @@ class Projects extends DolibarrApi
          * @return object
          */
         /*
    -    function putLine($id, $lineid, $request_data = null) {
    +    function putLine($id, $lineid, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -418,7 +423,8 @@ class Projects extends DolibarrApi
          *
          * @return int
          */
    -    function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -477,7 +483,6 @@ class Projects extends DolibarrApi
                     'message' => 'Project deleted'
                 )
             );
    -
         }
     
         /**
    @@ -535,7 +540,8 @@ class Projects extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -592,7 +598,6 @@ class Projects extends DolibarrApi
                 if (!isset($data[$field]))
                     throw new RestException(400, "$field field missing");
                 $object[$field] = $data[$field];
    -
             }
             return $object;
         }
    diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php
    index 3125546c10a..050e7313e95 100644
    --- a/htdocs/projet/class/api_tasks.class.php
    +++ b/htdocs/projet/class/api_tasks.class.php
    @@ -106,7 +106,8 @@ class Tasks extends DolibarrApi
          * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
          * @return  array                               Array of project objects
          */
    -    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
             global $db, $conf;
     
             $obj_ret = array();
    @@ -221,7 +222,8 @@ class Tasks extends DolibarrApi
          * @url	GET {id}/tasks
          */
         /*
    -    function getLines($id, $includetimespent=0) {
    +    function getLines($id, $includetimespent=0)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->lire) {
     		  	throw new RestException(401);
     		  }
    @@ -263,7 +265,8 @@ class Tasks extends DolibarrApi
          *
          * @return int
          */
    -    function getRoles($id, $userid=0) {
    +    function getRoles($id, $userid=0)
    +    {
             global $db;
     
             if(! DolibarrApiAccess::$user->rights->projet->lire) {
    @@ -305,7 +308,8 @@ class Tasks extends DolibarrApi
          * @return int
          */
         /*
    -    function postLine($id, $request_data = null) {
    +    function postLine($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -367,7 +371,8 @@ class Tasks extends DolibarrApi
          * @return object
          */
         /*
    -    function putLine($id, $lineid, $request_data = null) {
    +    function putLine($id, $lineid, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -422,7 +427,8 @@ class Tasks extends DolibarrApi
          *
          * @return int
          */
    -    function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
           if(! DolibarrApiAccess::$user->rights->projet->creer) {
     		  	throw new RestException(401);
     		  }
    @@ -481,7 +487,6 @@ class Tasks extends DolibarrApi
                     'message' => 'Task deleted'
                 )
             );
    -
         }
     
     
    @@ -550,7 +555,8 @@ class Tasks extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
             $object = parent::_cleanObjectDatas($object);
     
    @@ -604,7 +610,6 @@ class Tasks extends DolibarrApi
                 if (!isset($data[$field]))
                     throw new RestException(400, "$field field missing");
                 $object[$field] = $data[$field];
    -
             }
             return $object;
         }
    diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
    index 8aa867458ee..514abd4c5ec 100644
    --- a/htdocs/projet/class/project.class.php
    +++ b/htdocs/projet/class/project.class.php
    @@ -33,11 +33,32 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
     class Project extends CommonObject
     {
     
    -    public $element = 'project';    //!< Id that identify managed objects
    -    public $table_element = 'projet';  //!< Name of table without prefix where object is stored
    -    public $table_element_line = 'projet_task';
    -    public $fk_element = 'fk_projet';
    -    public $ismultientitymanaged = 1;  // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element = 'project';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element = 'projet';
    +
    +    /**
    +	 * @var int    Name of subtable line
    +	 */
    +	public $table_element_line = 'projet_task';
    +
    +    /**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
    +	public $fk_element = 'fk_projet';
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +    public $ismultientitymanaged = 1;
    +
         public $picto = 'projectpub';
     
         /**
    @@ -45,38 +66,43 @@ class Project extends CommonObject
          */
         protected $table_ref_field = 'ref';
     
    -    var $description;
    +    /**
    +	 * @var string description
    +	 */
    +	public $description;
    +
     	/**
     	 * @var string
     	 * @deprecated
     	 * @see title
     	 */
     	public $titre;
    -    var $title;
    -    var $date_start;
    -    var $date_end;
    -    var $date_close;
     
    -    var $socid;             // To store id of thirdparty
    -    var $thirdparty_name;   // To store name of thirdparty (defined only in some cases)
    +    public $title;
    +    public $date_start;
    +    public $date_end;
    +    public $date_close;
     
    -    var $user_author_id;    //!< Id of project creator. Not defined if shared project.
    -	var $user_close_id;
    -    var $public;      //!< Tell if this is a public or private project
    -    var $budget_amount;
    -    var $bill_time;			// Is the time spent on project must be invoiced or not
    +    public $socid;             // To store id of thirdparty
    +    public $thirdparty_name;   // To store name of thirdparty (defined only in some cases)
     
    -    var $statuts_short;
    -    var $statuts_long;
    +    public $user_author_id;    //!< Id of project creator. Not defined if shared project.
    +	public $user_close_id;
    +    public $public;      //!< Tell if this is a public or private project
    +    public $budget_amount;
    +    public $bill_time;			// Is the time spent on project must be invoiced or not
     
    -    var $statut;			// 0=draft, 1=opened, 2=closed
    -    var $opp_status;		// opportunity status, into table llx_c_lead_status
    -	var $opp_percent;		// opportunity probability
    +    public $statuts_short;
    +    public $statuts_long;
     
    -    var $oldcopy;
    +    public $statut;			// 0=draft, 1=opened, 2=closed
    +    public $opp_status;		// opportunity status, into table llx_c_lead_status
    +	public $opp_percent;		// opportunity probability
     
    -    var $weekWorkLoad;			// Used to store workload details of a projet
    -    var $weekWorkLoadPerTask;	// Used to store workload details of tasks of a projet
    +    public $oldcopy;
    +
    +    public $weekWorkLoad;			// Used to store workload details of a projet
    +    public $weekWorkLoadPerTask;	// Used to store workload details of tasks of a projet
     
     	/**
     	 * @var int Creation date
    @@ -84,16 +110,19 @@ class Project extends CommonObject
     	 * @see date_c
     	 */
     	public $datec;
    +
     	/**
     	 * @var int Creation date
     	 */
     	public $date_c;
    +
     	/**
     	 * @var int Modification date
     	 * @deprecated
     	 * @see date_m
     	 */
     	public $datem;
    +
     	/**
     	 * @var int Modification date
     	 */
    @@ -108,10 +137,12 @@ class Project extends CommonObject
     	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
    +
     	/**
     	 * Open/Validated status
     	 */
     	const STATUS_VALIDATED = 1;
    +
     	/**
     	 * Closed status
     	 */
    @@ -468,6 +499,7 @@ class Project extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Return list of projects
          *
    @@ -476,6 +508,7 @@ class Project extends CommonObject
          */
         function liste_array($socid='')
         {
    +        // phpcs:enable
             global $conf;
     
             $projects = array();
    @@ -509,6 +542,7 @@ class Project extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Return list of elements for type, linked to a project
          *
    @@ -517,10 +551,12 @@ class Project extends CommonObject
          * 	@param		string		$datefieldname	name of date field for filter
          *  @param		int			$dates			Start date
          *  @param		int			$datee			End date
    +	 *	@param		string		$projectkey		Equivalent key  to fk_projet for actual type
          * 	@return		mixed						Array list of object ids linked to project, < 0 or string if error
          */
    -    function get_element_list($type, $tablename, $datefieldname='', $dates='', $datee='')
    +    function get_element_list($type, $tablename, $datefieldname='', $dates='', $datee='', $projectkey='fk_projet')
         {
    +        // phpcs:enable
             $elements = array();
     
             if ($this->id <= 0) return $elements;
    @@ -549,7 +585,7 @@ class Project extends CommonObject
     		}
             else
     		{
    -            $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . $tablename." WHERE fk_projet IN (". $ids .") AND entity IN (".getEntity($type).")";
    +            $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . $tablename." WHERE ".$projectkey." IN (". $ids .") AND entity IN (".getEntity($type).")";
     		}
     
     		if ($dates > 0)
    @@ -626,9 +662,10 @@ class Project extends CommonObject
     
             // Set fk_projet into elements to null
             $listoftables=array(
    -        		'facture'=>'fk_projet','propal'=>'fk_projet','commande'=>'fk_projet',
    -                'facture_fourn'=>'fk_projet','commande_fournisseur'=>'fk_projet','supplier_proposal'=>'fk_projet',
    -        		'expensereport_det'=>'fk_projet','contrat'=>'fk_projet','fichinter'=>'fk_projet','don'=>'fk_projet'
    +        		'propal'=>'fk_projet', 'commande'=>'fk_projet', 'facture'=>'fk_projet',
    +        		'supplier_proposal'=>'fk_projet', 'commande_fournisseur'=>'fk_projet', 'facture_fourn'=>'fk_projet',
    +        		'expensereport_det'=>'fk_projet', 'contrat'=>'fk_projet', 'fichinter'=>'fk_projet', 'don'=>'fk_projet',
    +        		'actioncomm'=>'fk_project'
             		);
             foreach($listoftables as $key => $value)
             {
    @@ -896,6 +933,7 @@ class Project extends CommonObject
             return $this->LibStatut($this->statut, $mode);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Renvoi status label for a status
          *
    @@ -905,6 +943,7 @@ class Project extends CommonObject
          */
         function LibStatut($statut, $mode=0)
         {
    +        // phpcs:enable
             global $langs;
     
             if ($mode == 0)
    @@ -1462,7 +1501,6 @@ class Project extends CommonObject
     							$tab_conv_child_parent[$tasktoclone->id] =  $new_task_id;
     						}
     				    }
    -
     			    }
     
     			    //Parse all clone node to be sure to update new parent
    @@ -1568,15 +1606,17 @@ class Project extends CommonObject
     	}
     
     
    -	 /**
    -	  *    Associate element to a project
    -	  *
    -	  *    @param	string	$tableName			Table of the element to update
    -	  *    @param	int		$elementSelectId	Key-rowid of the line of the element to update
    -	  *    @return	int							1 if OK or < 0 if KO
    -	  */
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
    +	 *    Associate element to a project
    +	 *
    +	 *    @param	string	$tableName			Table of the element to update
    +	 *    @param	int		$elementSelectId	Key-rowid of the line of the element to update
    +	 *    @return	int							1 if OK or < 0 if KO
    +     */
     	function update_element($tableName, $elementSelectId)
     	{
    +        // phpcs:enable
     		$sql="UPDATE ".MAIN_DB_PREFIX.$tableName;
     
     		if ($tableName == "actioncomm")
    @@ -1598,9 +1638,9 @@ class Project extends CommonObject
     		}else {
     			return 1;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Associate element to a project
     	 *
    @@ -1610,6 +1650,7 @@ class Project extends CommonObject
     	 */
     	function remove_element($tableName, $elementSelectId)
     	{
    +        // phpcs:enable
     		$sql="UPDATE ".MAIN_DB_PREFIX.$tableName;
     
     		if ($TableName=="actioncomm")
    @@ -1631,7 +1672,6 @@ class Project extends CommonObject
     		}else {
     			return 1;
     		}
    -
     	}
     
     	/**
    @@ -1732,6 +1772,7 @@ class Project extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
    @@ -1740,6 +1781,7 @@ class Project extends CommonObject
          */
         function load_board($user)
         {
    +        // phpcs:enable
             global $conf, $langs;
     
             // For external user, no check is done on company because readability is managed by public status of project and assignement.
    @@ -1816,6 +1858,7 @@ class Project extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb pour le tableau de bord
     	 *
    @@ -1823,6 +1866,7 @@ class Project extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     	    global $user;
     
     	    $this->nb=array();
    @@ -1914,7 +1958,6 @@ class Project extends CommonObject
     	        }
     
     	        $this->db->free($result);
    -
     	    }
     	    else
     	    {
    @@ -1930,6 +1973,7 @@ class Project extends CommonObject
     	 * Existing categories are left untouch.
     	 *
     	 * @param int[]|int $categories Category or categories IDs
    +     * @return void
     	 */
     	public function setCategories($categories)
     	{
    @@ -1996,6 +2040,4 @@ class Project extends CommonObject
     
     	    $this->lines = $taskstatic->getTasksArray(0, $user, $this->id, 0, 0);
     	}
    -
     }
    -
    diff --git a/htdocs/projet/class/projectstats.class.php b/htdocs/projet/class/projectstats.class.php
    index 22793fd844e..9766935d4d0 100644
    --- a/htdocs/projet/class/projectstats.class.php
    +++ b/htdocs/projet/class/projectstats.class.php
    @@ -29,7 +29,12 @@ class ProjectStats extends Stats
     	public $socid;
     	public $year;
     
    -	function __construct($db)
    +    /**
    +     * Constructor
    +     *
    +     * @param   DoliDB $db     Database handler
    +     */
    +    function __construct($db)
     	{
     		global $conf, $user;
     
    @@ -493,7 +498,6 @@ class ProjectStats extends Stats
     			} else {
     				$res[$key]=array($total_row[0],0);
     			}
    -
     		}
     		// var_dump($res);print '<br>';
     		return $res;
    diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
    index a0477461b4e..c5a7a334eb0 100644
    --- a/htdocs/projet/class/task.class.php
    +++ b/htdocs/projet/class/task.class.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2008-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2010-2012	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2014       Marcos García       <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -31,46 +32,84 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
      */
     class Task extends CommonObject
     {
    -	public $element='project_task';		//!< Id that identify managed objects
    -	public $table_element='projet_task';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='project_task';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='projet_task';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_task';
    +
     	public $picto = 'task';
     	protected $childtables=array('projet_task_time');    // To test if we can delete object
     
    -	var $fk_task_parent;
    -	var $label;
    -	var $description;
    -	var $duration_effective;		// total of time spent on this task
    -	var $planned_workload;
    -	var $date_c;
    -	var $date_start;
    -	var $date_end;
    -	var $progress;
    -	var $fk_statut;
    -	var $priority;
    -	var $fk_user_creat;
    -	var $fk_user_valid;
    -	var $rang;
    +	/**
    +     * @var int ID parent task
    +     */
    +    public $fk_task_parent;
     
    -	var $timespent_min_date;
    -	var $timespent_max_date;
    -	var $timespent_total_duration;
    -	var $timespent_total_amount;
    -	var $timespent_nblinesnull;
    -	var $timespent_nblines;
    +    /**
    +     * @var string Label of task
    +     */
    +    public $label;
    +
    +	/**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +	public $duration_effective;		// total of time spent on this task
    +	public $planned_workload;
    +	public $date_c;
    +	public $date_start;
    +	public $date_end;
    +	public $progress;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_statut;
    +
    +	public $priority;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_user_valid;
    +
    +	public $rang;
    +
    +	public $timespent_min_date;
    +	public $timespent_max_date;
    +	public $timespent_total_duration;
    +	public $timespent_total_amount;
    +	public $timespent_nblinesnull;
    +	public $timespent_nblines;
     	// For detail of lines of timespent record, there is the property ->lines in common
     
     	// Var used to call method addTimeSpent(). Bad practice.
    -	var $timespent_id;
    -	var $timespent_duration;
    -	var $timespent_old_duration;
    -	var $timespent_date;
    -	var $timespent_datehour;		// More accurate start date (same than timespent_date but includes hours, minutes and seconds)
    -	var $timespent_withhour;		// 1 = we entered also start hours for timesheet line
    -	var $timespent_fk_user;
    -	var $timespent_note;
    +	public $timespent_id;
    +	public $timespent_duration;
    +	public $timespent_old_duration;
    +	public $timespent_date;
    +	public $timespent_datehour;		// More accurate start date (same than timespent_date but includes hours, minutes and seconds)
    +	public $timespent_withhour;		// 1 = we entered also start hours for timesheet line
    +	public $timespent_fk_user;
    +	public $timespent_note;
     
    -	var $comments = array();
    +	public $comments = array();
     
     	public $oldcopy;
     
    @@ -302,7 +341,7 @@ class Task extends CommonObject
     		// Clean parameters
     		if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project);
     		if (isset($this->ref)) $this->ref=trim($this->ref);
    -		if (isset($this->fk_task_parent)) $this->fk_task_parent=trim($this->fk_task_parent);
    +		if (isset($this->fk_task_parent)) $this->fk_task_parent = (int) $this->fk_task_parent;
     		if (isset($this->label)) $this->label=trim($this->label);
     		if (isset($this->description)) $this->description=trim($this->description);
     		if (isset($this->duration_effective)) $this->duration_effective=trim($this->duration_effective);
    @@ -667,12 +706,12 @@ class Task extends CommonObject
     
     		$this->fk_projet='';
     		$this->ref='TK01';
    -		$this->fk_task_parent='';
    +		$this->fk_task_parent=null;
     		$this->label='Specimen task TK01';
     		$this->duration_effective='';
    -		$this->fk_user_creat='';
    +		$this->fk_user_creat=null;
     		$this->progress='25';
    -		$this->fk_statut='';
    +		$this->fk_statut=null;
     		$this->note='This is a specimen task not';
     	}
     
    @@ -1529,7 +1568,6 @@ class Task extends CommonObject
     			{
     				$clone_task->date_end			= $now + $clone_task->date_end - $orign_project_dt_start;
     			}
    -
     		}
     
     		if (!$clone_prog)
    @@ -1698,6 +1736,7 @@ class Task extends CommonObject
     		return $this->LibStatut($this->fk_statut, $mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Return status label for an object
     	 *
    @@ -1707,6 +1746,7 @@ class Task extends CommonObject
     	 */
     	function LibStatut($statut, $mode=0)
     	{
    +        // phpcs:enable
     		// list of Statut of the task
     		$this->statuts[0]='Draft';
     		$this->statuts[1]='ToDo';
    @@ -1725,59 +1765,59 @@ class Task extends CommonObject
     		{
     			return $langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			return $langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
    -			if ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
    +			elseif ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5').' '.$langs->trans($this->statuts_short[$statut]);
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
    -			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
    -			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
    -			if ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    -			if ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    -			if ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
    +			elseif ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
    +			elseif ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
    -			if ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
    +			elseif ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]);
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			/*if ($statut==0) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
    -			if ($statut==1) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
    -			if ($statut==2) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
    -			if ($statut==3) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    -			if ($statut==4) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    -			if ($statut==5) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
    +			elseif ($statut==1) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
    +			elseif ($statut==2) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
    +			elseif ($statut==3) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==4) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==5) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
     			*/
    -			//return $this->progress.' %';
    +			//else return $this->progress.' %';
     			return '&nbsp;';
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			/*if ($statut==0) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
    -			if ($statut==1) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
    -			if ($statut==2) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
    -			if ($statut==3) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    -			if ($statut==4) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    -			if ($statut==5) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
    +			elseif ($statut==1) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
    +			elseif ($statut==2) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
    +			elseif ($statut==3) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==4) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
    +			elseif ($statut==5) return $langs->trans($this->statuts[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
     			*/
    -			//return $this->progress.' %';
    +			//else return $this->progress.' %';
     			return '&nbsp;';
     		}
     	}
    @@ -1815,6 +1855,7 @@ class Task extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
     	 *
    @@ -1823,6 +1864,7 @@ class Task extends CommonObject
     	 */
     	function load_board($user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		// For external user, no check is done on company because readability is managed by public status of project and assignement.
    @@ -1888,6 +1930,7 @@ class Task extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb de tableau de bord
     	 *
    @@ -1895,6 +1938,7 @@ class Task extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $user;
     
     		$mine=0; $socid=$user->societe_id;
    @@ -1955,4 +1999,4 @@ class Task extends CommonObject
     
     		return ($datetouse > 0 && ($datetouse < ($now - $conf->projet->task->warning_delay)));
     	}
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/projet/class/taskstats.class.php b/htdocs/projet/class/taskstats.class.php
    index 20a3a67d1d3..4164c1427b6 100644
    --- a/htdocs/projet/class/taskstats.class.php
    +++ b/htdocs/projet/class/taskstats.class.php
    @@ -29,10 +29,13 @@ class TaskStats extends Stats
     	public $socid;
     	public $year;
     
    +    /**
    +     * Constructor of the class
    +     *
    +     * @param   DoliDb  $db     Database handler
    +     */
     	function __construct($db)
     	{
    -		global $conf, $user;
    -
     		$this->db = $db;
     
     		require_once 'task.class.php';
    diff --git a/htdocs/projet/comment.php b/htdocs/projet/comment.php
    index 3dfd0bb3ca4..f6cd6ac0005 100644
    --- a/htdocs/projet/comment.php
    +++ b/htdocs/projet/comment.php
    @@ -184,6 +184,6 @@ print '<br>';
     // Include comment tpl view
     include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_comment.tpl.php';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/contact.php b/htdocs/projet/contact.php
    index 2f4ee0fba06..4b9aaf58b8b 100644
    --- a/htdocs/projet/contact.php
    +++ b/htdocs/projet/contact.php
    @@ -240,6 +240,14 @@ if ($id > 0 || ! empty($ref))
         print nl2br($object->description);
         print '</td></tr>';
     
    +    // Bill time
    +    if (! empty($conf->global->PROJECT_BILL_TIME_SPENT))
    +    {
    +    	print '<tr><td>'.$langs->trans("BillTime").'</td><td>';
    +    	print yn($object->bill_time);
    +    	print '</td></tr>';
    +    }
    +
         // Categories
         if ($conf->categorie->enabled) {
             print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>';
    @@ -268,6 +276,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php
    index 9ac1b74f604..af9f7c2d8fc 100644
    --- a/htdocs/projet/document.php
    +++ b/htdocs/projet/document.php
    @@ -152,13 +152,12 @@ if ($object->id > 0)
     	$permission = ($userWrite > 0);
     	$permtoedit = ($userWrite > 0);
     	include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
     	dol_print_error('','NoRecordFound');
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php
    index d2b1948b5ec..b8017b45048 100644
    --- a/htdocs/projet/element.php
    +++ b/htdocs/projet/element.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2010 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2012-2016 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2015-2017 Alexandre Spangaro	<aspangaro@zendsi.com>
    + * Copyright (C) 2015-2018 Alexandre Spangaro   <aspangaro@zendsi.com>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2016      Josep Lluís Amador   <joseplluis@lliuretic.cat>
      *
    @@ -43,7 +43,7 @@ if (! empty($conf->fournisseur->enabled))	require_once DOL_DOCUMENT_ROOT.'/fourn
     if (! empty($conf->fournisseur->enabled))	require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
     if (! empty($conf->contrat->enabled))		require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
     if (! empty($conf->ficheinter->enabled))	require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
    -if (! empty($conf->expedition->enabled))    require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
    +if (! empty($conf->expedition->enabled))	require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
     if (! empty($conf->deplacement->enabled))	require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
     if (! empty($conf->expensereport->enabled))	require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
     if (! empty($conf->agenda->enabled))		require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
    @@ -52,17 +52,19 @@ if (! empty($conf->loan->enabled))			require_once DOL_DOCUMENT_ROOT.'/loan/class
     if (! empty($conf->stock->enabled))			require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
     if (! empty($conf->tax->enabled))			require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
     if (! empty($conf->banque->enabled))		require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
    +if (! empty($conf->salaries->enabled))		require_once DOL_DOCUMENT_ROOT.'/compta/salaries/class/paymentsalary.class.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array('projects', 'companies', 'suppliers', 'compta'));
    -if (! empty($conf->facture->enabled))  	    $langs->load("bills");
    -if (! empty($conf->commande->enabled)) 	    $langs->load("orders");
    -if (! empty($conf->propal->enabled))   	    $langs->load("propal");
    +if (! empty($conf->facture->enabled))		$langs->load("bills");
    +if (! empty($conf->commande->enabled))		$langs->load("orders");
    +if (! empty($conf->propal->enabled))		$langs->load("propal");
     if (! empty($conf->ficheinter->enabled))	$langs->load("interventions");
     if (! empty($conf->deplacement->enabled))	$langs->load("trips");
     if (! empty($conf->expensereport->enabled)) $langs->load("trips");
     if (! empty($conf->don->enabled))			$langs->load("donations");
     if (! empty($conf->loan->enabled))			$langs->load("loan");
    +if (! empty($conf->salaries->enabled))		$langs->load("salaries");
     
     $id=GETPOST('id','int');
     $ref=GETPOST('ref','alpha');
    @@ -215,6 +217,14 @@ print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
     print nl2br($object->description);
     print '</td></tr>';
     
    +// Bill time
    +if (! empty($conf->global->PROJECT_BILL_TIME_SPENT))
    +{
    +	print '<tr><td>'.$langs->trans("BillTime").'</td><td>';
    +	print yn($object->bill_time);
    +	print '</td></tr>';
    +}
    +
     // Categories
     if($conf->categorie->enabled) {
         print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>';
    @@ -439,6 +449,19 @@ $listofreferent=array(
     	'datefieldname'=>'datem',
     	'disableamount'=>0,
     	'test'=>($conf->stock->enabled && $user->rights->stock->mouvement->lire && ! empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))),
    +'salaries'=>array(
    +	'name'=>"Salaries",
    +	'title'=>"ListSalariesAssociatedProject",
    +	'class'=>'PaymentSalary',
    +	'table'=>'payment_salary',
    +	'datefieldname'=>'datev',
    +	'margin'=>'minus',
    +	'disableamount'=>0,
    +	'urlnew'=>DOL_URL_ROOT.'/compta/salaries/card.php?action=create&projectid='.$id,
    +	'lang'=>'salaries',
    +	'buttonnew'=>'AddSalaryPayment',
    +	'testnew'=>$user->rights->salaries->write,
    +	'test'=>$conf->salaries->enabled && $user->rights->salaries->read),
     'variouspayment'=>array(
     	'name'=>"VariousPayments",
     	'title'=>"ListVariousPaymentsAssociatedProject",
    @@ -474,7 +497,6 @@ $resHook = $hookmanager->executeHooks('completeListOfReferent', $parameters, $ob
     if(!empty($hookmanager->resArray)) {
     
     	$listofreferent = array_merge($listofreferent, $hookmanager->resArray);
    -
     }
     
     if ($action=="addelement")
    @@ -514,10 +536,10 @@ if (! $showdatefilter)
     	print '<input type="hidden" name="action" value="view">';
     	print '<table class="center"><tr>';
     	print '<td>'.$langs->trans("From").' ';
    -	print $form->select_date($dates,'dates',0,0,1,'',1,0,1);
    +	print $form->selectDate($dates, 'dates', 0, 0, 1, '', 1, 0);
     	print '</td>';
     	print '<td>'.$langs->trans("to").' ';
    -	print $form->select_date($datee,'datee',0,0,1,'',1,0,1);
    +	print $form->selectDate($datee, 'datee', 0, 0, 1, '', 1, 0);
     	print '</td>';
     	print '<td>';
     	print '<input type="submit" name="refresh" value="'.$langs->trans("Refresh").'" class="button">';
    @@ -533,11 +555,8 @@ if (! $showdatefilter)
     
     // Show balance for whole project
     
    -$langs->load("suppliers");
    -$langs->load("bills");
    -$langs->load("orders");
    -$langs->load("proposals");
    -$langs->load("margins");
    +$langs->loadLangs(array("suppliers", "bills", "orders", "proposals", "margins"));
    +
     if (!empty($conf->stock->enabled)) $langs->load('stocks');
     
     print load_fiche_titre($langs->trans("Profit"), '', 'title_accountancy');
    @@ -559,11 +578,12 @@ foreach ($listofreferent as $key => $value)
     	$datefieldname=$value['datefieldname'];
     	$qualified=$value['test'];
     	$margin = $value['margin'];
    +	$project_field = $value['project_field'];
     	if ($qualified && isset($margin))		// If this element must be included into profit calculation ($margin is 'minus' or 'plus')
     	{
     		$element = new $classname($db);
     
    -		$elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee);
    +		$elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field)?$project_field:'fk_projet');
     
     		if (count($elementarray)>0 && is_array($elementarray))
     		{
    @@ -674,8 +694,8 @@ foreach ($listofreferent as $key => $value)
     // and the final balance
     print '<tr class="liste_total">';
     print '<td align="right" colspan=2 >'.$langs->trans("Profit").'</td>';
    -print '<td align="right" >'.price($balance_ht).'</td>';
    -print '<td align="right" >'.price($balance_ttc).'</td>';
    +print '<td align="right" >'.price(price2num($balance_ht, 'MT')).'</td>';
    +print '<td align="right" >'.price(price2num($balance_ttc, 'MT')).'</td>';
     print '</tr>';
     
     print "</table>";
    @@ -698,10 +718,11 @@ foreach ($listofreferent as $key => $value)
     	$urlnew=$value['urlnew'];
     	$buttonnew=$value['buttonnew'];
         $testnew=$value['testnew'];
    +	$project_field=$value['project_field'];
    +
     	$exclude_select_element = array('payment_various');
     	if (!empty($value['exclude_select_element'])) $exclude_select_element[] = $value['exclude_select_element'];
     
    -
     	if ($qualified)
     	{
     		// If we want the project task array to have details of users
    @@ -723,7 +744,7 @@ foreach ($listofreferent as $key => $value)
     
            	if (empty($conf->global->PROJECT_LINK_ON_OVERWIEW_DISABLED) && $idtofilterthirdparty && !in_array($tablename,$exclude_select_element))
            	{
    -			$selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300');
    +			$selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300',-2,!empty($project_field)?$project_field:'fk_projet');
     			if (! $selectList || ($selectList<0))
     			{
     				setEventMessages($formproject->error,$formproject->errors,'errors');
    @@ -774,7 +795,7 @@ foreach ($listofreferent as $key => $value)
     		print '<td>';
     		if (in_array($tablename, array('projet_task')) && $key == 'project_task') print '';		// if $key == 'project_task', we don't want details per user
     		elseif (in_array($tablename, array('payment_various'))) print '';						// if $key == 'payment_various', we don't have any thirdparty
    -		elseif (in_array($tablename, array('expensereport_det','don','projet_task','stock_mouvement'))) print $langs->trans("User");
    +		elseif (in_array($tablename, array('expensereport_det','don','projet_task','stock_mouvement','payment_salary'))) print $langs->trans("User");
     		else print $langs->trans("ThirdParty");
     		print '</td>';
     		// Amount HT
    @@ -791,7 +812,7 @@ foreach ($listofreferent as $key => $value)
     		else print '<td align="right" width="200">'.$langs->trans("Status").'</td>';
     		print '</tr>';
     
    -		$elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee);
    +		$elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee,!empty($project_field)?$project_field:'fk_projet');
     		if (is_array($elementarray) && count($elementarray)>0)
     		{
     			$total_ht = 0;
    @@ -859,7 +880,9 @@ foreach ($listofreferent as $key => $value)
     				{
     					if (empty($conf->global->PROJECT_DISABLE_UNLINK_FROM_OVERVIEW) || $user->admin)		// PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by defaut, so this test true
     					{
    -						print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $projectid . '&action=unlink&tablename=' . $tablename . '&elementselect=' . $element->id . '">' . img_picto($langs->trans('Unlink'), 'editdelete') . '</a>';
    +						print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $projectid . '&action=unlink&tablename=' . $tablename . '&elementselect=' . $element->id . '" class="reposition">';
    +						print img_picto($langs->trans('Unlink'), 'unlink');
    +						print '</a>';
     					}
     				}
     				print "</td>\n";
    @@ -872,7 +895,7 @@ foreach ($listofreferent as $key => $value)
     				}
     				else
     				{
    -				    // Show ref with link
    +					// Show ref with link
     					if ($element instanceof Task)
     					{
     						print $element->getNomUrl(1,'withproject','time');
    @@ -907,6 +930,7 @@ foreach ($listofreferent as $key => $value)
     				$date=''; $total_time_by_line = null;
     				if ($tablename == 'expensereport_det') $date = $element->date;      // No draft status on lines
     				elseif ($tablename == 'stock_mouvement') $date = $element->datem;
    +				elseif ($tablename == 'payment_salary') $date = $element->datev;
     				elseif ($tablename == 'payment_various') $date = $element->datev;
     				elseif ($tablename == 'chargesociales') $date = $element->date_ech;
     				elseif (! empty($element->status) || ! empty($element->statut) || ! empty($element->fk_status))
    @@ -952,6 +976,12 @@ foreach ($listofreferent as $key => $value)
                     	$tmpuser->fetch($expensereport->fk_user_author);
                     	print $tmpuser->getNomUrl(1,'',48);
                     }
    +				else if ($tablename == 'payment_salary')
    +				{
    +					$tmpuser=new User($db);
    +					$tmpuser->fetch($element->fk_user);
    +					print $tmpuser->getNomUrl(1,'',48);
    +				}
     				else if ($tablename == 'don' || $tablename == 'stock_mouvement')
                     {
                     	if ($element->fk_user_author > 0)
    @@ -973,7 +1003,7 @@ foreach ($listofreferent as $key => $value)
     				{
     				    $total_ht_by_line=null;
     				    $othermessage='';
    -					if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various') $total_ht_by_line=$element->amount;
    +					if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'payment_salary') $total_ht_by_line=$element->amount;
     					else if($tablename == 'fichinter') $total_ht_by_line=$element->getAmount();
     					elseif ($tablename == 'stock_mouvement') $total_ht_by_line=$element->price*abs($element->qty);
     					elseif (in_array($tablename, array('projet_task')))
    @@ -1014,7 +1044,7 @@ foreach ($listofreferent as $key => $value)
     				if (empty($value['disableamount']))
     				{
     				    $total_ttc_by_line=null;
    -					if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various') $total_ttc_by_line=$element->amount;
    +					if ($tablename == 'don' || $tablename == 'chargesociales' || $tablename == 'payment_various' || $tablename == 'payment_salary') $total_ttc_by_line=$element->amount;
     					else if($tablename == 'fichinter') $total_ttc_by_line=$element->getAmount();
     					elseif ($tablename == 'stock_mouvement') $total_ttc_by_line=$element->price*abs($element->qty);
     					elseif ($tablename == 'projet_task')
    @@ -1163,10 +1193,8 @@ if ($conf->use_javascript_ajax)
     	print $comboenhancement;
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
     
     
    diff --git a/htdocs/projet/ganttchart.inc.php b/htdocs/projet/ganttchart.inc.php
    index bc85e5bae78..dc76e098b59 100644
    --- a/htdocs/projet/ganttchart.inc.php
    +++ b/htdocs/projet/ganttchart.inc.php
    @@ -271,8 +271,6 @@ function constructGanttLine($tarr, $task, $task_dependencies, $level=0, $project
     
         $s.= "g.AddTaskItem(new JSGantt.TaskItem('".$taskid."', '".dol_escape_js(trim($name))."', '".$start_date."', '".$end_date."', '".$css."', '".$link."', ".$task['task_milestone'].", '".dol_escape_js($resources)."', ".($percent >= 0 ? $percent : 0).", ".$line_is_auto_group.", '".$parent."', 1, '".$dependency."', '".(empty($task["task_is_group"]) ? (($percent >= 0 && $percent != '') ? $percent.'%' : '') : '')."', '".dol_escape_js($note)."', g));";
         echo $s;
    -
    -
     }
     
     /**
    diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php
    index e49eaa2700d..00f568271e0 100644
    --- a/htdocs/projet/ganttview.php
    +++ b/htdocs/projet/ganttview.php
    @@ -23,7 +23,7 @@
      *	\brief      Gantt diagramm of a project
      */
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -365,7 +365,6 @@ else
     	print '<div class="opacitymedium">'.$langs->trans("NoTasks").'</div>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php
    index 906cb3783f1..50143057205 100644
    --- a/htdocs/projet/index.php
    +++ b/htdocs/projet/index.php
    @@ -318,7 +318,6 @@ if (! empty($conf->global->PROJECT_SHOW_PROJECT_LIST_ON_PROJECT_AREA))
     
     print '</div></div></div>';
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php
    index 4c30fd6c451..7aa0dccd67d 100644
    --- a/htdocs/projet/info.php
    +++ b/htdocs/projet/info.php
    @@ -192,6 +192,6 @@ if (!empty($object->id))
         show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters, $sortfield, $sortorder);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php
    index aa0c4b0d8fe..5a13b16560d 100644
    --- a/htdocs/projet/list.php
    +++ b/htdocs/projet/list.php
    @@ -352,6 +352,7 @@ if ($search_opp_status)
     	if (is_numeric($search_opp_status) && $search_opp_status > 0) $sql .= " AND p.fk_opp_status = ".$db->escape($search_opp_status);
     	if ($search_opp_status == 'all') $sql .= " AND p.fk_opp_status IS NOT NULL";
     	if ($search_opp_status == 'openedopp') $sql .= " AND p.fk_opp_status IS NOT NULL AND p.fk_opp_status NOT IN (SELECT rowid FROM ".MAIN_DB_PREFIX."c_lead_status WHERE code IN ('WON','LOST'))";
    +	if ($search_opp_status == 'notopenedopp') $sql .= " AND (p.fk_opp_status IS NULL OR p.fk_opp_status IN (SELECT rowid FROM ".MAIN_DB_PREFIX."c_lead_status WHERE code IN ('WON')))";
     	if ($search_opp_status == 'none') $sql .= " AND p.fk_opp_status IS NULL";
     }
     if ($search_public!='') $sql .= " AND p.public = ".$db->escape($search_public);
    @@ -424,7 +425,7 @@ if ($search_ref != '') 			$param.='&search_ref='.$search_ref;
     if ($search_label != '') 		$param.='&search_label='.$search_label;
     if ($search_societe != '') 		$param.='&search_societe='.$search_societe;
     if ($search_status >= 0) 		$param.='&search_status='.$search_status;
    -if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all','openedopp','none'))) 	    $param.='&search_opp_status='.urlencode($search_opp_status);
    +if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all','openedopp','notopenedopp','none'))) 	    $param.='&search_opp_status='.urlencode($search_opp_status);
     if ($search_opp_percent != '') 	$param.='&search_opp_percent='.urlencode($search_opp_percent);
     if ($search_public != '') 		$param.='&search_public='.$search_public;
     if ($search_project_user != '')   $param.='&search_project_user='.$search_project_user;
    @@ -538,18 +539,21 @@ print '<div class="div-table-responsive">';
     print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
     
     print '<tr class="liste_titre_filter">';
    +// Project ref
     if (! empty($arrayfields['p.ref']['checked']))
     {
     	print '<td class="liste_titre">';
     	print '<input type="text" class="flat" name="search_ref" value="'.dol_escape_htmltag($search_ref).'" size="6">';
     	print '</td>';
     }
    +// Project label
     if (! empty($arrayfields['p.title']['checked']))
     {
     	print '<td class="liste_titre">';
     	print '<input type="text" class="flat" name="search_label" size="8" value="'.dol_escape_htmltag($search_label).'">';
     	print '</td>';
     }
    +// Third party
     if (! empty($arrayfields['s.nom']['checked']))
     {
     	print '<td class="liste_titre">';
    @@ -592,6 +596,7 @@ if (! empty($arrayfields['p.public']['checked']))
     	print $form->selectarray('search_public',$array,$search_public);
     	print '</td>';
     }
    +// Opp status
     if (! empty($arrayfields['p.fk_opp_status']['checked']))
     {
     	print '<td class="liste_titre nowrap center">';
    @@ -883,7 +888,6 @@ while ($i < min($num,$limit))
     		if (! $i) $totalarray['nbfield']++;
     
     		print "</tr>\n";
    -
     	}
     
     	$i++;
    @@ -919,7 +923,6 @@ print "</table>\n";
     print '</div>';
     print "</form>\n";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php
    index 7a7db5141f4..4d455bdcbc7 100644
    --- a/htdocs/projet/note.php
    +++ b/htdocs/projet/note.php
    @@ -119,6 +119,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/stats/index.php b/htdocs/projet/stats/index.php
    index 38e9bc327bc..831917a76f6 100644
    --- a/htdocs/projet/stats/index.php
    +++ b/htdocs/projet/stats/index.php
    @@ -302,6 +302,7 @@ print '</table>';
     print '</form>';
     print '<br><br>';
     
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -348,6 +349,7 @@ foreach ($data_all_year as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     
    @@ -373,6 +375,6 @@ print $stringtoshow;
     print '</div></div></div>';
     print '<div style="clear:both"></div>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php
    index 94a51ef3d01..31f860dbf9b 100644
    --- a/htdocs/projet/tasks.php
    +++ b/htdocs/projet/tasks.php
    @@ -23,7 +23,7 @@
      *	\brief      List all tasks of a project
      */
     
    -require ("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -91,13 +91,14 @@ $planned_workload=$planned_workloadhour*3600+$planned_workloadmin*60;
     $userAccess=0;
     
     
    -$parameters=array('id'=>$id);
    -$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');
     /*
      * Actions
      */
     
    +$parameters=array('id'=>$id);
    +$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');
    +
     // Purge search criteria
     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
     {
    @@ -404,6 +405,14 @@ if ($id > 0 || ! empty($ref))
         print nl2br($object->description);
         print '</td></tr>';
     
    +    // Bill time
    +    if (! empty($conf->global->PROJECT_BILL_TIME_SPENT))
    +    {
    +    	print '<tr><td>'.$langs->trans("BillTime").'</td><td>';
    +    	print yn($object->bill_time);
    +    	print '</td></tr>';
    +    }
    +
         // Categories
         if($conf->categorie->enabled) {
             print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>';
    @@ -480,12 +489,12 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
     
     	// Date start
     	print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
    -	print $form->select_date(($date_start?$date_start:''),'dateo',1,1,0,'',1,1,1);
    +	print $form->selectDate(($date_start?$date_start:''), 'dateo', 1, 1, 0, '', 1, 1);
     	print '</td></tr>';
     
     	// Date end
     	print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
    -	print $form->select_date(($date_end?$date_end:-1),'datee',-1,1,0,'',1,1,1);
    +	print $form->selectDate(($date_end?$date_end:-1),'datee', -1, 1, 0, '', 1, 1);
     	print '</td></tr>';
     
     	// Planned workload
    @@ -525,7 +534,6 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third
     	print '</div>';
     
     	print '</form>';
    -
     }
     else if ($id > 0 || ! empty($ref))
     {
    @@ -726,6 +734,6 @@ else if ($id > 0 || ! empty($ref))
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/tasks/comment.php b/htdocs/projet/tasks/comment.php
    index cb4888f6335..ba54b35a59e 100644
    --- a/htdocs/projet/tasks/comment.php
    +++ b/htdocs/projet/tasks/comment.php
    @@ -23,7 +23,7 @@
      *	\brief      Page of a project task
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -275,10 +275,9 @@ if ($id > 0 || ! empty($ref))
     
     		// Include comment tpl view
     		include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_comment.tpl.php';
    -
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/tasks/contact.php b/htdocs/projet/tasks/contact.php
    index 21cd32f4514..d86c8b469ae 100644
    --- a/htdocs/projet/tasks/contact.php
    +++ b/htdocs/projet/tasks/contact.php
    @@ -23,7 +23,7 @@
      *	\brief      Actors of a task
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
    @@ -354,8 +354,6 @@ if ($id > 0 || ! empty($ref))
     			print '<td colspan="3">&nbsp;</td>';
     			print "</tr>\n";
     
    -			$var = false;
    -
     			print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$id.'" method="POST">';
     			print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     			print '<input type="hidden" name="action" value="addcontact">';
    @@ -438,7 +436,6 @@ if ($id > 0 || ! empty($ref))
     		print "</tr>\n";
     
     		$companystatic = new Societe($db);
    -		$var = true;
     
     		foreach(array('internal','external') as $source)
     		{
    @@ -448,9 +445,7 @@ if ($id > 0 || ! empty($ref))
     			$i = 0;
     			while ($i < $num)
     			{
    -				$var = !$var;
    -
    -				print '<tr '.$bc[$var].' valign="top">';
    +				print '<tr class="oddeven" valign="top">';
     
     				// Source
     				print '<td align="left">';
    @@ -523,7 +518,6 @@ if ($id > 0 || ! empty($ref))
     			}
     		}
     		print "</table>";
    -
     	}
     	else
     	{
    @@ -538,7 +532,6 @@ if (is_object($hookmanager))
     	$reshook=$hookmanager->executeHooks('formContactTpl',$parameters,$object,$action);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/tasks/document.php b/htdocs/projet/tasks/document.php
    index d1e11a196d2..a186c89988f 100644
    --- a/htdocs/projet/tasks/document.php
    +++ b/htdocs/projet/tasks/document.php
    @@ -294,7 +294,6 @@ else
     	exit;
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php
    index 14703f6d3eb..2366ccc738b 100644
    --- a/htdocs/projet/tasks/list.php
    +++ b/htdocs/projet/tasks/list.php
    @@ -24,7 +24,7 @@
      *	\brief      List all task of a project
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -841,5 +841,6 @@ print '</div>';
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php
    index 568114ca3b4..668c2a96d83 100644
    --- a/htdocs/projet/tasks/note.php
    +++ b/htdocs/projet/tasks/note.php
    @@ -21,7 +21,7 @@
      *	\brief      Page to show information on a task
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -249,6 +249,6 @@ if ($object->id > 0)
     	dol_fiche_end();
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/tasks/stats/index.php b/htdocs/projet/tasks/stats/index.php
    index fa9ebcf3b52..020a7969a64 100644
    --- a/htdocs/projet/tasks/stats/index.php
    +++ b/htdocs/projet/tasks/stats/index.php
    @@ -167,6 +167,8 @@ print '</table>';
     print '</form>';
     print '<br><br>';
     
    +
    +print '<div class="div-table-responsive-no-min">';
     print '<table class="noborder" width="100%">';
     print '<tr class="liste_titre" height="24">';
     print '<td align="center">'.$langs->trans("Year").'</td>';
    @@ -195,6 +197,7 @@ foreach ($data_all_year as $val)
     }
     
     print '</table>';
    +print '</div>';
     
     print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
     
    @@ -212,6 +215,6 @@ print $stringtoshow;
     print '</div></div></div>';
     print '<div style="clear:both"></div>';
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php
    index 706d0f640de..fa9796449db 100644
    --- a/htdocs/projet/tasks/task.php
    +++ b/htdocs/projet/tasks/task.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2005		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
      * Copyright (C) 2006-2017	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2010-2012	Regis Houssin			<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -23,7 +24,7 @@
      *	\brief      Page of a project task
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
    @@ -390,12 +391,12 @@ if ($id > 0 || ! empty($ref))
     
     			// Date start
     			print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
    -			print $form->select_date($object->date_start,'dateo',1,1,0,'',1,0,1);
    +			print $form->selectDate($object->date_start, 'dateo', 1, 1, 0, '', 1, 0);
     			print '</td></tr>';
     
     			// Date end
     			print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
    -			print $form->select_date($object->date_end?$object->date_end:-1,'datee',1,1,0,'',1,0,1);
    +			print $form->selectDate($object->date_end?$object->date_end:-1, 'datee', 1, 1, 0, '', 1, 0);
     			print '</td></tr>';
     
     			// Planned workload
    @@ -628,6 +629,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php
    index ca53c373184..7ff93c7b4da 100644
    --- a/htdocs/projet/tasks/time.php
    +++ b/htdocs/projet/tasks/time.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2010-2012	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2011		Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2018		Ferran Marcet			<fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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,7 +161,7 @@ if ($action == 'addtimespent' && $user->rights->projet->lire)
     			$object->timespent_note = $_POST["timespent_note"];
     			if (GETPOST('progress', 'int') > 0) $object->progress = GETPOST('progress', 'int');		// If progress is -1 (not defined), we do not change value
     			$object->timespent_duration = $_POST["timespent_durationhour"]*60*60;	// We store duration in seconds
    -			$object->timespent_duration+= $_POST["timespent_durationmin"]*60;		// We store duration in seconds
    +			$object->timespent_duration+= ($_POST["timespent_durationmin"]?$_POST["timespent_durationmin"]:0)*60;   // We store duration in seconds
     	        if (GETPOST("timehour") != '' && GETPOST("timehour") >= 0)	// If hour was entered
     	        {
     				$object->timespent_date = dol_mktime(GETPOST("timehour"),GETPOST("timemin"),0,GETPOST("timemonth"),GETPOST("timeday"),GETPOST("timeyear"));
    @@ -398,8 +399,16 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
                 print nl2br($projectstatic->description);
                 print '</td></tr>';
     
    +            // Bill time
    +            if (! empty($conf->global->PROJECT_BILL_TIME_SPENT))
    +            {
    +	            print '<tr><td>'.$langs->trans("BillTime").'</td><td>';
    +	            print yn($projectstatic->bill_time);
    +	            print '</td></tr>';
    +            }
    +
                 // Categories
    -            if($conf->categorie->enabled) {
    +            if ($conf->categorie->enabled) {
                     print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>';
                     print $form->showCategories($projectstatic->id,'project',1);
                     print "</td></tr>";
    @@ -580,7 +589,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
     			print '<td class="maxwidthonsmartphone">';
     			//$newdate=dol_mktime(12,0,0,$_POST["timemonth"],$_POST["timeday"],$_POST["timeyear"]);
     			$newdate='';
    -			print $form->select_date($newdate, 'time', ($conf->browser->layout == 'phone'?2:1), 1, 2, "timespent_date", 1, 0, 1);
    +			print $form->selectDate($newdate, 'time', ($conf->browser->layout == 'phone'?2:1), 1, 2, "timespent_date", 1, 0);
     			print '</td>';
     
     			// Contributor
    @@ -759,7 +768,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
     			print '<td class="maxwidthonsmartphone">';
     			//$newdate=dol_mktime(12,0,0,$_POST["timemonth"],$_POST["timeday"],$_POST["timeyear"]);
     			$newdate='';
    -			print $form->select_date($newdate, 'time', ($conf->browser->layout == 'phone'?2:1), 1, 2, "timespent_date", 1, 0, 1);
    +			print $form->selectDate($newdate, 'time', ($conf->browser->layout == 'phone'?2:1), 1, 2, "timespent_date", 1, 0);
     			print '</td>';
     
     			// Task
    @@ -965,9 +974,9 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
         			{
         				if (empty($task_time->task_date_withhour))
         				{
    -    					print $form->select_date(($date2?$date2:$date1),'timeline',3,3,2,"timespent_date",1,0,1);
    +    					print $form->selectDate(($date2?$date2:$date1), 'timeline', 3, 3, 2, "timespent_date", 1, 0);
         				}
    -    				else print $form->select_date(($date2?$date2:$date1),'timeline',1,1,2,"timespent_date",1,0,1);
    +    				else print $form->selectDate(($date2?$date2:$date1), 'timeline', 1, 1, 2, "timespent_date", 1, 0);
         			}
         			else
         			{
    @@ -1089,7 +1098,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
                 	if (isset($task_time->total_ht)) print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency);
                 	print '</td>';
                 	if (! $i) $totalarray['nbfield']++;
    -            	if (! $i) $totalarray['totalvaluefield']=$totalarray['nbfield'];
    +            	if (! $i) $totalarray['totalvaluebilledfield']=$totalarray['nbfield'];
                 	$totalarray['totalvaluebilled'] += $valuebilled;
                 }
     
    @@ -1151,6 +1160,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
     		        }
     		        elseif ($totalarray['totaldurationfield'] == $i) print '<td align="right">'.convertSecondToTime($totalarray['totalduration'],'allhourmin').'</td>';
     		        elseif ($totalarray['totalvaluefield'] == $i) print '<td align="right">'.price($totalarray['totalvalue']).'</td>';
    +		        elseif ($totalarray['totalvaluebilledfield'] == $i) print '<td align="right">'.price($totalarray['totalvaluebilled']).'</td>';
     		        else print '<td></td>';
     		    }
     		    print '</tr>';
    @@ -1164,6 +1174,6 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/public/agenda/agendaexport.php b/htdocs/public/agenda/agendaexport.php
    index 72f1a6b9242..6e08f06d630 100644
    --- a/htdocs/public/agenda/agendaexport.php
    +++ b/htdocs/public/agenda/agendaexport.php
    @@ -42,13 +42,19 @@ if (! defined('NOCSRFCHECK'))    define("NOCSRFCHECK",1);	// We accept to go on
      *
      * @return	void
      */
    -function llxHeaderVierge() { print '<html><title>Export agenda cal</title><body>'; }
    +function llxHeaderVierge()
    +{
    +    print '<html><title>Export agenda cal</title><body>';
    +}
     /**
      * Footer function
      *
      * @return	void
      */
    -function llxFooterVierge() { print '</body></html>'; }
    +function llxFooterVierge()
    +{
    +    print '</body></html>';
    +}
     
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
    diff --git a/htdocs/public/cron/cron_run_jobs.php b/htdocs/public/cron/cron_run_jobs.php
    index 4edcbbf14ee..df207e87d85 100644
    --- a/htdocs/public/cron/cron_run_jobs.php
    +++ b/htdocs/public/cron/cron_run_jobs.php
    @@ -36,11 +36,7 @@ if (is_numeric($entity)) define("DOLENTITY", $entity);
     
     // librarie core
     // Dolibarr environment
    -$res = @include("../../main.inc.php"); // From htdocs directory
    -if (! $res) {
    -	$res = @include("../../../main.inc.php"); // From "custom" directory
    -}
    -if (! $res) die("Include of master.inc.php fails");
    +require '../../main.inc.php';
     
     // librarie jobs
     dol_include_once("/cron/class/cronjob.class.php");
    @@ -48,12 +44,7 @@ dol_include_once("/cron/class/cronjob.class.php");
     global $langs, $conf;
     
     // Language Management
    -$langs->load("admin");
    -$langs->load("cron");
    -
    -
    -
    -
    +$langs->loadLangs(array("admin", "cron"));
     
     /*
      * View
    @@ -178,7 +169,6 @@ if (is_array($qualifiedjobs) && (count($qualifiedjobs)>0))
     				dol_syslog("cron_run_jobs.php::reprogram_jobs Error".$cronjob->error, LOG_ERR);
     				exit;
     			}
    -
     		}
     	}
     	echo "Result: ".($nbofjobs)." jobs - ".($nbofjobslaunchedok+$nbofjobslaunchedko)." launched = ".$nbofjobslaunchedok." OK + ".$nbofjobslaunchedko." KO";
    diff --git a/htdocs/public/demo/demo.css b/htdocs/public/demo/demo.css
    index c4624f2d943..d137b7be456 100644
    --- a/htdocs/public/demo/demo.css
    +++ b/htdocs/public/demo/demo.css
    @@ -16,19 +16,19 @@ a:hover {
     	border: 1px solid #bbb;
     	border-radius: 8px;
     	-moz-border-radius: 8px;
    -	box-shadow: 2px 2px 8px #BBB; 
    +	box-shadow: 2px 2px 8px #BBB;
     }
     .CTable {
     	padding: 6px;
     	font-weight: normal;
     	color: #444444 !important;
    -	
    +
     	margin: 8px 0px 8px 2px;
    -	
    +
     	/*border: 1px solid #bbb;
     	border-radius: 8px;
     	-moz-border-radius: 8px;*/
    -	
    +
     	background: -webkit-linear-gradient(bottom, rgb(255,255,255) 85%, rgb(255,255,255) 100%);
     }
     .csscolumns {
    @@ -129,4 +129,4 @@ img.demothumb {
             margin-left: 0px;
             margin-right: 0px;
         }
    -}
    \ No newline at end of file
    +}
    diff --git a/htdocs/public/demo/index.php b/htdocs/public/demo/index.php
    index 61919c54b1a..f9169bb47d2 100644
    --- a/htdocs/public/demo/index.php
    +++ b/htdocs/public/demo/index.php
    @@ -30,9 +30,7 @@ define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
     require '../../main.inc.php';
     require_once '../../core/lib/functions2.lib.php';
     
    -$langs->load("main");
    -$langs->load("install");
    -$langs->load("other");
    +$langs->loadLangs(array("main", "install", "other"));
     
     $conf->dol_hide_topmenu=GETPOST('dol_hide_topmenu','int');
     $conf->dol_hide_leftmenu=GETPOST('dol_hide_leftmenu','int');
    diff --git a/htdocs/public/donations/donateurs_code.php b/htdocs/public/donations/donateurs_code.php
    index 3d8057cbe85..86db4b089aa 100644
    --- a/htdocs/public/donations/donateurs_code.php
    +++ b/htdocs/public/donations/donateurs_code.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    +/* Copyright (C) 2002       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,19 +31,25 @@ define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
      *
      * @return	void
      */
    -function llxHeaderVierge() { print '<html><title>Export agenda cal</title><body>'; }
    +function llxHeaderVierge()
    +{
    +    print '<html><title>Export agenda cal</title><body>';
    +}
     /**
      * Header function
      *
      * @return	void
      */
    -function llxFooterVierge() { print '</body></html>'; }
    +function llxFooterVierge()
    +{
    +    print '</body></html>';
    +}
     
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT .'/don/class/don.class.php';
     
     // Security check
    -if (empty($conf->don->enabled)) accessforbidden('',0,0,1);
    +if (empty($conf->don->enabled)) accessforbidden('', 0, 0, 1);
     
     
     $langs->load("donations");
    @@ -65,13 +72,13 @@ if ($resql)
     	if ($num)
     	{
     
    -		print "<TABLE border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"4\">";
    +		print "<table border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"4\">";
     
    -		print '<TR>';
    +		print '<tr>';
     		print "<td>".$langs->trans("Name")." / ".$langs->trans("Company")."</td>";
     		print "<td>Date</td>";
    -		print "<td align=\"right\">".$langs->trans("Amount")."</TD>";
    -		print "</TR>\n";
    +		print "<td align=\"right\">".$langs->trans("Amount")."</td>";
    +		print "</tr>\n";
     
     		while ($i < $num)
     		{
    @@ -92,7 +99,6 @@ if ($resql)
     			$i++;
     		}
     		print "</table>";
    -
     	}
     	else
     	{
    diff --git a/htdocs/public/emailing/mailing-read.php b/htdocs/public/emailing/mailing-read.php
    index 4aa388ecf24..0b79f656450 100644
    --- a/htdocs/public/emailing/mailing-read.php
    +++ b/htdocs/public/emailing/mailing-read.php
    @@ -36,13 +36,17 @@ if (! defined('NOREQUIREMENU'))  define('NOREQUIREMENU','1');	// If there is no
      *
      * @return	void
      */
    -function llxHeader() { }
    +function llxHeader()
    +{
    +}
     /**
      * Footer empty
      *
      * @return	void
      */
    -function llxFooter() { }
    +function llxFooter()
    +{
    +}
     
     
     require '../../main.inc.php';
    @@ -82,7 +86,6 @@ if (! empty($tag))
     	dol_syslog("public/emailing/mailing-read.php : Mail read contact : ".$sql, LOG_DEBUG);
     
     	$resql=$db->query($sql);
    -
     }
     
     $db->close();
    diff --git a/htdocs/public/emailing/mailing-unsubscribe.php b/htdocs/public/emailing/mailing-unsubscribe.php
    index 61e8ccdb0d6..c27cb024aab 100644
    --- a/htdocs/public/emailing/mailing-unsubscribe.php
    +++ b/htdocs/public/emailing/mailing-unsubscribe.php
    @@ -35,13 +35,17 @@ if (! defined('NOREQUIREMENU'))  define('NOREQUIREMENU','1');	// If there is no
      *
      * @return	void
      */
    -function llxHeader() { }
    +function llxHeader()
    +{
    +}
     /**
      * Footer empty
      *
      * @return	void
      */
    -function llxFooter() { }
    +function llxFooter()
    +{
    +}
     
     
     require '../../main.inc.php';
    @@ -49,8 +53,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     
     global $user, $conf, $langs;
     
    -$langs->load("main");
    -$langs->load("mails");
    +$langs->loadLangs(array("main", "mails"));
     
     $tag=GETPOST('tag');
     $unsuscrib=GETPOST('unsuscrib');
    diff --git a/htdocs/public/members/new.php b/htdocs/public/members/new.php
    index 144ab64328f..f2395020bda 100644
    --- a/htdocs/public/members/new.php
    +++ b/htdocs/public/members/new.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2006-2013	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2012		Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2012		J. Fernando Lagrange    <fernando@demo-tic.org>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -99,11 +100,11 @@ function llxHeaderVierge($title, $head="", $disablejs=0, $disablehead=0, $arrayo
     
         if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small))
         {
    -        $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('thumbs/'.$mysoc->logo_small);
    +        $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
         }
         elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo))
         {
    -        $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode($mysoc->logo);
    +        $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/'.$mysoc->logo);
             $width=128;
         }
         elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png'))
    @@ -276,8 +277,9 @@ if ($action == 'add')
                 	// Set output language
                 	$outputlangs = new Translate('', $conf);
                 	$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +            	// Load traductions files requiredby by page
                 	$outputlangs->loadLangs(array("main", "members"));
    -            	// Get email content fro mtemplae
    +            	// Get email content from template
                 	$arraydefaultmessage=null;
                 	$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_AUTOREGISTER;
     
    @@ -548,7 +550,7 @@ if (empty($conf->global->MEMBER_NEWFORM_FORCETYPE))
         $isempty=1;
         if (count($listoftype)==1) { $defaulttype=$tmp[0]; $isempty=0; }
         print '<tr><td class="titlefield">'.$langs->trans("Type").' <FONT COLOR="red">*</FONT></td><td>';
    -    print $form->selectarray("type",  $adht->liste_array(), GETPOST('type')?GETPOST('type'):$defaulttype, $isempty);
    +    print $form->selectarray("type", $adht->liste_array(), GETPOST('type')?GETPOST('type'):$defaulttype, $isempty);
         print '</td></tr>'."\n";
     }
     else
    @@ -563,7 +565,7 @@ $morphys["mor"] = $langs->trans("Moral");
     if (empty($conf->global->MEMBER_NEWFORM_FORCEMORPHY))
     {
         print '<tr class="morphy"><td class="titlefield">'.$langs->trans('Nature').' <FONT COLOR="red">*</FONT></td><td>'."\n";
    -    print $form->selectarray("morphy",  $morphys, GETPOST('morphy'), 1);
    +    print $form->selectarray("morphy", $morphys, GETPOST('morphy'), 1);
         print '</td></tr>'."\n";
     }
     else
    @@ -626,7 +628,7 @@ if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
     }
     // Birthday
     print '<tr id="trbirth" class="trbirth"><td>'.$langs->trans("DateToBirth").'</td><td>';
    -print $form->select_date($birthday,'birth',0,0,1,"newmember",1,0,1);
    +print $form->selectDate($birthday, 'birth', 0, 0, 1, "newmember", 1, 0);
     print '</td></tr>'."\n";
     // Photo
     print '<tr><td>'.$langs->trans("URLPhoto").'</td><td><input type="text" name="photo" class="minwidth150" value="'.dol_escape_htmltag(GETPOST('photo')).'"></td></tr>'."\n";
    diff --git a/htdocs/public/members/public_card.php b/htdocs/public/members/public_card.php
    index 5dee0eb49a3..bc8fd0cde17 100644
    --- a/htdocs/public/members/public_card.php
    +++ b/htdocs/public/members/public_card.php
    @@ -43,10 +43,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     if (empty($conf->adherent->enabled)) accessforbidden('',0,0,1);
     
     
    -$langs->load("main");
    -$langs->load("members");
    -$langs->load("companies");
    -$langs->load("other");
    +$langs->loadLangs(array("main", "members", "companies", "other"));
     
     $id=GETPOST('id','int');
     $object = new Adherent($db);
    @@ -116,7 +113,6 @@ if ($id > 0)
     
     		print '</table>';
     	}
    -
     }
     
     
    diff --git a/htdocs/public/members/public_list.php b/htdocs/public/members/public_list.php
    index 1f9a4406028..6ba46182427 100644
    --- a/htdocs/public/members/public_list.php
    +++ b/htdocs/public/members/public_list.php
    @@ -40,10 +40,7 @@ require '../../main.inc.php';
     if (empty($conf->adherent->enabled)) accessforbidden('',0,0,1);
     
     
    -$langs->load("main");
    -$langs->load("members");
    -$langs->load("companies");
    -$langs->load("other");
    +$langs->loadLangs(array("main", "members", "companies", "other"));
     
     
     /**
    diff --git a/htdocs/public/notice.php b/htdocs/public/notice.php
    index 623baa2020a..3b25349324c 100644
    --- a/htdocs/public/notice.php
    +++ b/htdocs/public/notice.php
    @@ -19,13 +19,13 @@
      *	\file       htdocs/public/notice.php
      *	\brief      Dolibarr page to show a notice.
      *              Default notice is a message to say network connection is off.
    - *              You can also call this page with URL: 
    + *              You can also call this page with URL:
      *                /public/notice.php?lang=xx_XX&transkey=translation_key  (key must be inside file main.lang, error.lang or other.lang)
      *                /public/notice.php?transphrase=url_encoded_sentence_to_show
      */
     
     define('NOCSRFCHECK',1);
    -define('NOLOGIN',1);		
    +define('NOLOGIN',1);
     
     require '../main.inc.php';
     
    @@ -43,8 +43,8 @@ else
     {
         $langs->load("error");
         $langs->load("other");
    -    
    -    if (GETPOST('transphrase')) print GETPOST('transphrase'); 
    +
    +    if (GETPOST('transphrase')) print GETPOST('transphrase');
         if (GETPOST('transkey')) print $langs->trans(GETPOST('transkey'));
     }
     
    diff --git a/htdocs/public/onlinesign/index.html b/htdocs/public/onlinesign/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/public/onlinesign/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php
    index 6c9b4b154bf..277cd1ada78 100644
    --- a/htdocs/public/onlinesign/newonlinesign.php
    +++ b/htdocs/public/onlinesign/newonlinesign.php
    @@ -44,13 +44,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
     // Security check
     // No check on module enabled. Done later according to $validpaymentmethod
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("errors");
    -$langs->load("paybox");     // File with generic data
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "paybox"));
     
     $action=GETPOST('action','alpha');
     
    @@ -126,7 +120,6 @@ $creditor = $mysoc->name;
     if ($action == 'dosign')
     {
         // TODO
    -
     }
     
     
    @@ -147,6 +140,7 @@ if (! empty($source) && in_array($ref, array('member_ref', 'contractline_ref', '
     {
         $langs->load("errors");
         dol_print_error_email('BADREFINONLINESIGNFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
    +    // End of page
         llxFooter();
         $db->close();
         exit;
    @@ -179,11 +173,11 @@ else if (! empty($conf->global->ONLINE_SIGN_LOGO)) $logosmall=$conf->global->ONL
     $urllogo='';
     if (! empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('thumbs/'.$logosmall);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$logosmall);
     }
     elseif (! empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode($logo);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$logo);
     	$width=96;
     }
     // Output html code for logo
    @@ -261,8 +255,6 @@ if ($source == 'proposal')
     	print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">';
     	print '<input type="hidden" name="ref" value="'.$proposal->ref.'">';
     	print '</td></tr>'."\n";
    -
    -
     }
     
     
    diff --git a/htdocs/public/opensurvey/studs.php b/htdocs/public/opensurvey/studs.php
    index 32cb5f2e1ba..a9bd8a0fb70 100644
    --- a/htdocs/public/opensurvey/studs.php
    +++ b/htdocs/public/opensurvey/studs.php
    @@ -24,11 +24,11 @@
     
     define("NOLOGIN",1);		// This means this output page does not require to be logged.
     define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
    -require_once('../../main.inc.php');
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php");
    +require '../../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php";
    +require_once DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php";
     
     
     // Init vars
    diff --git a/htdocs/public/paybox/paymentko.php b/htdocs/public/paybox/paymentko.php
    index feb4070c16b..ef642a5b80b 100644
    --- a/htdocs/public/paybox/paymentko.php
    +++ b/htdocs/public/paybox/paymentko.php
    @@ -39,15 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     // Security check
     if (empty($conf->paybox->enabled)) accessforbidden('',0,0,1);
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("paybox");
    -$langs->load("paypal");
    -$langs->load("stripe");
    -
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe"));
     
     $object = new stdClass();   // For triggers
     
    diff --git a/htdocs/public/paybox/paymentok.php b/htdocs/public/paybox/paymentok.php
    index 9e711ade51b..41eef8784bc 100644
    --- a/htdocs/public/paybox/paymentok.php
    +++ b/htdocs/public/paybox/paymentok.php
    @@ -39,14 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     // Security check
     if (empty($conf->paybox->enabled)) accessforbidden('',0,0,1);
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("paybox");
    -$langs->load("paypal");
    -$langs->load("stripe");
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe"));
     
     /*$source=GETPOST('source');
     $ref=GETPOST('ref');
    diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php
    index 3afd590da53..0975186eb03 100644
    --- a/htdocs/public/payment/newpayment.php
    +++ b/htdocs/public/payment/newpayment.php
    @@ -415,10 +415,10 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
       	$vatnumber = GETPOST('vatnumber','alpha');
     	$savesource=GETPOSTISSET('savesource')?GETPOST('savesource', 'int'):1;
     
    -	dol_syslog("stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe');
    -	dol_syslog("email = ".$email, LOG_DEBUG, 0, '_stripe');
    -	dol_syslog("thirdparty_id = ".$thirdparty_id, LOG_DEBUG, 0, '_stripe');
    -	dol_syslog("vatnumber = ".$vatnumber, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST email = ".$email, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST thirdparty_id = ".$thirdparty_id, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST vatnumber = ".$vatnumber, LOG_DEBUG, 0, '_stripe');
     
     	$error = 0;
     
    @@ -443,7 +443,6 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     				$service = 'StripeLive';
     				$servicestatus = 1;
     			}
    -			$stripeacc = null;	// No Oauth/connect use for public pages
     
     			$thirdparty = new Societe($db);
     			$thirdparty->fetch($thirdparty_id);
    @@ -451,6 +450,7 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     			// Create Stripe customer
     			include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
     			$stripe = new Stripe($db);
    +            $stripeacc = $stripe->getStripeAccount($service);
     			$customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1);
     
     			// Create Stripe card from Token
    @@ -478,12 +478,12 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     					'amount'   => price2num($amountstripe, 'MU'),
     					'currency' => $currency,
     					'capture'  => true,							// Charge immediatly
    -					'description' => 'Stripe payment: '.$FULLTAG,
    +					'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref,
     					'metadata' => $metadata,
     					'customer' => $customer->id,
     					'source' => $card,
     					'statement_descriptor' => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 6, 'right', 'UTF-8', 1).' '.$FULLTAG, 22, 'right', 'UTF-8', 1)     // 22 chars that appears on bank receipt
    -				));
    +				),array("idempotency_key" => "$ref", "stripe_account" => "$stripeacc"));
     				// Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
     				if (empty($charge))
     				{
    @@ -496,19 +496,29 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     		}
     		else
     		{
    +			$vatcleaned = $vatnumber ? $vatnumber : null;
    +
    +			$taxinfo = array('type'=>'vat');
    +			if ($vatcleaned)
    +			{
    +				$taxinfo["tax_id"] = $vatcleaned;
    +			}
    +			// We force data to "null" if not defined as expected by Stripe
    +			if (empty($vatcleaned)) $taxinfo=null;
    +
     			dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_stripe');
     			$customer = \Stripe\Customer::create(array(
     				'email' => $email,
     				'description' => ($email?'Anonymous customer for '.$email:'Anonymous customer'),
     				'metadata' => $metadata,
    -				'business_vat_id' => ($vatnumber?$vatnumber:null),
    +				'tax_info' => $taxinfo,
     				'source'  => $stripeToken           // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?)
     			));
     			// Return $customer = array('id'=>'cus_XXXX', ...)
     
    -        if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    -        if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    -        if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
    +			if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    +			if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    +			if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
     
     			// The customer was just created with a source, so we can make a charge
     			// with no card defined, the source just used for customer creation will be used.
    @@ -518,10 +528,10 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     				'amount'   => price2num($amountstripe, 'MU'),
     				'currency' => $currency,
     				'capture'  => true,							// Charge immediatly
    -				'description' => 'Stripe payment: '.$FULLTAG,
    +				'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref,
     				'metadata' => $metadata,
     				'statement_descriptor' => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 6, 'right', 'UTF-8', 1).' '.$FULLTAG, 22, 'right', 'UTF-8', 1)     // 22 chars that appears on bank receipt
    -			));
    +			),array("idempotency_key" => "$ref", "stripe_account" => "$stripeacc"));
     			// Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
     			if (empty($charge))
     			{
    @@ -610,7 +620,6 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     		header("Location: ".$urlok);
     		exit;
     	}
    -
     }
     
     
    @@ -631,8 +640,9 @@ if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_r
     {
     	$langs->load("errors");
     	dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
    -	llxFooter();
    -	$db->close();
    +	// End of page
    +    llxFooter();
    +    $db->close();;
     	exit;
     }
     
    @@ -694,12 +704,12 @@ else if (! empty($conf->global->ONLINE_PAYMENT_LOGO)) $logosmall=$conf->global->
     $urllogo='';
     if (! empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('thumbs/'.$logosmall);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$logosmall);
     	$width=150;
     }
     elseif (! empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode($logo);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$logo);
     	$width=150;
     }
     // Output html code for logo
    @@ -813,7 +823,7 @@ if ($source == 'order')
     		$amount=price2num($amount);
     	}
     
    -	$fulltag='ORD='.$order->ref.'.CUS='.$order->thirdparty->id;
    +	$fulltag='ORD='.$order->id.'.CUS='.$order->thirdparty->id;
     	//$fulltag.='.NAM='.strtr($order->thirdparty->name,"-"," ");
     	if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
     	$fulltag=dol_string_unaccent($fulltag);
    @@ -933,7 +943,7 @@ if ($source == 'invoice')
     		$amount=price2num($amount);
     	}
     
    -	$fulltag='INV='.$invoice->ref.'.CUS='.$invoice->thirdparty->id;
    +	$fulltag='INV='.$invoice->id.'.CUS='.$invoice->thirdparty->id;
     	//$fulltag.='.NAM='.strtr($invoice->thirdparty->name,"-"," ");
     	if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
     	$fulltag=dol_string_unaccent($fulltag);
    @@ -1115,7 +1125,7 @@ if ($source == 'contractline')
     		$amount=price2num($amount);
     	}
     
    -	$fulltag='COL='.$contractline->ref.'.CON='.$contract->ref.'.CUS='.$contract->thirdparty->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M');
    +	$fulltag='COL='.$contractline->id.'.CON='.$contract->id.'.CUS='.$contract->thirdparty->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M');
     	//$fulltag.='.NAM='.strtr($contract->thirdparty->name,"-"," ");
     	if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
     	$fulltag=dol_string_unaccent($fulltag);
    diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php
    index bdc301a0dce..33fc1fb5101 100644
    --- a/htdocs/public/payment/paymentko.php
    +++ b/htdocs/public/payment/paymentko.php
    @@ -44,14 +44,7 @@ if (! empty($conf->paypal->enabled))
     	require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php';
     }
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("paybox");
    -$langs->load("paypal");
    -$langs->load("stripe");
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe"));
     
     if (! empty($conf->paypal->enabled))
     {
    @@ -219,12 +212,12 @@ else if (! empty($conf->global->ONLINE_PAYMENT_LOGO)) $logosmall=$conf->global->
     $urllogo='';
     if (! empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('thumbs/'.$logosmall);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$logosmall);
     	$width=150;
     }
     elseif (! empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode($logo);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/'.$logo);
     	$width=150;
     }
     // Output html code for logo
    diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php
    index 7f4e6e67a2c..36723658946 100644
    --- a/htdocs/public/payment/paymentok.php
    +++ b/htdocs/public/payment/paymentok.php
    @@ -157,12 +157,12 @@ else if (! empty($conf->global->ONLINE_PAYMENT_LOGO)) $logosmall=$conf->global->
     $urllogo='';
     if (! empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('thumbs/'.$logosmall);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$logosmall);
     	$width=150;
     }
     elseif (! empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode($logo);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('logos/'.$logo);
     	$width=150;
     }
     // Output html code for logo
    @@ -313,7 +313,7 @@ if ($ispaymentok)
     		$adht = new AdherentType($db);
     		$object = new Adherent($db);
     
    -		$result1 = $object->fetch(0, $tmptag['MEM']);
    +		$result1 = $object->fetch($tmptag['MEM']);
     		$result2 = $adht->fetch($object->typeid);
     
     		if ($result1 > 0 && $result2 > 0)
    @@ -516,8 +516,9 @@ if ($ispaymentok)
     						// Set output language
     						$outputlangs = new Translate('', $conf);
     						$outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang);
    +						// Load traductions files requiredby by page
     						$outputlangs->loadLangs(array("main", "members"));
    -						// Get email content from templae
    +						// Get email content from template
     						$arraydefaultmessage=null;
     						$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_SUBSCRIPTION;
     
    @@ -587,7 +588,7 @@ if ($ispaymentok)
     		// Record payment
     		include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     		$invoice = new Facture($db);
    -		$result = $invoice->fetch(0, $tmptag['INV']);
    +		$result = $invoice->fetch($tmptag['INV']);
     		if ($result)
     		{
     			$FinalPaymentAmt    = $_SESSION["FinalPaymentAmt"];
    @@ -628,7 +629,9 @@ if ($ispaymentok)
     				}
     				$paiement->paiementid   = $paymentTypeId;
     				$paiement->num_paiement = '';
    -				$paiement->note_public  = 'Online payment '.dol_print_date($now, 'standard').' using '.$paymentmethod.' from '.$ipaddress.' - Transaction ID = '.$TRANSACTIONID;
    +				$paiement->note_public  = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress;
    +				$paiement->ext_payment_id = $TRANSACTIONID;
    +				$paiement->ext_payment_site = $paymentmethod;
     
     				if (! $error)
     				{
    @@ -650,8 +653,8 @@ if ($ispaymentok)
     				{
     					$bankaccountid = 0;
     					if ($paymentmethod == 'paybox') $bankaccountid = $conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS;
    -					if ($paymentmethod == 'paypal') $bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
    -					if ($paymentmethod == 'stripe') $bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
    +					elseif ($paymentmethod == 'paypal') $bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
    +					elseif ($paymentmethod == 'stripe') $bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
     
     					if ($bankaccountid > 0)
     					{
    @@ -666,7 +669,7 @@ if ($ispaymentok)
     						}
     						else
     						{
    -							$postactionmessages[] = 'Bank entry of payment created';
    +							$postactionmessages[] = 'Bank transaction of payment created';
     							$ispostactionok=1;
     						}
     					}
    @@ -775,9 +778,9 @@ if ($ispaymentok)
     		}
     		elseif (in_array('INV', array_keys($tmptag)))
     		{
    -			$url=$urlwithroot."/compta/facture/card.php?ref=".$tmptag['INV'];
    +			$url=$urlwithroot."/compta/facture/card.php?id=".$tmptag['INV'];
     			$content.='<strong>'.$companylangs->trans("Payment")."</strong><br><br>\n";
    -			$content.=$companylangs->trans("Invoice").': <strong>'.$tmptag['INV']."</strong><br>\n";
    +			$content.=$companylangs->trans("InvoiceId").': <strong>'.$tmptag['INV']."</strong><br>\n";
     			//$content.=$companylangs->trans("ThirdPartyId").': '.$tmptag['CUS']."<br>\n";
     			$content.=$companylangs->trans("Link").': <a href="'.$url.'">'.$url.'</a>'."<br>\n";
     		}
    @@ -870,8 +873,8 @@ else
         if (! empty($conf->global->PAYMENTONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYMENTONLINE_SENDEMAIL;
         // TODO Remove local option to keep only the generic one ?
         if ($paymentmethod == 'paypal' && ! empty($conf->global->PAYPAL_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYPAL_PAYONLINE_SENDEMAIL;
    -    if ($paymentmethod == 'paybox' && ! empty($conf->global->PAYBOX_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYBOX_PAYONLINE_SENDEMAIL;
    -    if ($paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->STRIPE_PAYONLINE_SENDEMAIL;
    +    elseif ($paymentmethod == 'paybox' && ! empty($conf->global->PAYBOX_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYBOX_PAYONLINE_SENDEMAIL;
    +    elseif ($paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->STRIPE_PAYONLINE_SENDEMAIL;
     
         // Send an email
         if ($sendemail)
    diff --git a/htdocs/public/paypal/paymentko.php b/htdocs/public/paypal/paymentko.php
    index 3e555379849..03645244e91 100644
    --- a/htdocs/public/paypal/paymentko.php
    +++ b/htdocs/public/paypal/paymentko.php
    @@ -43,14 +43,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     // Security check
     if (empty($conf->paypal->enabled)) accessforbidden('',0,0,1);
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("paybox");
    -$langs->load("paypal");
    -$langs->load("stripe");
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe"));
     
     $PAYPALTOKEN=GETPOST('TOKEN');
     if (empty($PAYPALTOKEN)) $PAYPALTOKEN=GETPOST('token');
    diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php
    index ad6aee43bd4..45fd6489f92 100644
    --- a/htdocs/public/stripe/ipn.php
    +++ b/htdocs/public/stripe/ipn.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2018 	Thibault FOUCART        <support@ptibogxiv.net>
    +/* Copyright (C) 2018       Thibault FOUCART        <support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -21,9 +22,7 @@ define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
     $entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
     if (is_numeric($entity)) define("DOLENTITY", $entity);
     
    -$res=0;
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");		// to work if your module directory is into a subdir of root htdocs directory
    -if (! $res) die("Include of main fails");
    +require '../../main.inc.php';
     
     if (empty($conf->stripe->enabled)) accessforbidden('',0,0,1);
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    @@ -36,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
    +require_once DOL_DOCUMENT_ROOT .'/core/class/CMailFile.class.php';
     
     // You can find your endpoint's secret in your webhook settings
     if (isset($_GET['connect'])){
    @@ -43,13 +43,13 @@ if (isset($_GET['connect'])){
     	{
     		$endpoint_secret =  $conf->global->STRIPE_TEST_WEBHOOK_CONNECT_KEY;
     		$service = 'StripeTest';
    -    $servicestatus = 0;
    +        $servicestatus = 0;
     	}
     	else
     	{
     		$endpoint_secret =  $conf->global->STRIPE_LIVE_WEBHOOK_CONNECT_KEY;
     		$service = 'StripeLive';
    -    $servicestatus = 1;    
    +        $servicestatus = 1;
     	}
     }
     else {
    @@ -57,13 +57,13 @@ else {
     	{
     		$endpoint_secret =  $conf->global->STRIPE_TEST_WEBHOOK_KEY;
     		$service = 'StripeTest';
    -    $servicestatus = 0;
    +        $servicestatus = 0;
     	}
     	else
     	{
     		$endpoint_secret =  $conf->global->STRIPE_LIVE_WEBHOOK_KEY;
     		$service = 'StripeLive';
    -    $servicestatus = 1;
    +        $servicestatus = 1;
     	}
     }
     $payload = @file_get_contents("php://input");
    @@ -88,9 +88,12 @@ catch(\UnexpectedValueException $e) {
     // Do something with $event
     
     http_response_code(200); // PHP 5.4 or greater
    +
     $langs->load("main");
    +
    +// TODO Do we really need a user in setup just to have an name to fill an email topic when it is a technical system notification email
     $user = new User($db);
    -$user->fetch(5);
    +$user->fetch($conf->global->STRIPE_USER_ACCOUNT_FOR_ACTIONS);
     $user->getrights();
     
     if (! empty($conf->multicompany->enabled) && ! empty($conf->stripeconnect->enabled) && is_object($mc)) {
    @@ -115,7 +118,7 @@ if (! empty($conf->multicompany->enabled) && ! empty($conf->stripeconnect->enabl
     		$key=1;
     	}
     	$ret=$mc->switchEntity($key);
    -	if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    +	if (! $res && file_exists("../../main.inc.php")) $res=@include "../../main.inc.php";
     	if (! $res) die("Include of main fails");
     }
     
    @@ -128,12 +131,37 @@ if ($event->type == 'payout.created') {
     
     	if ($result > 0)
     	{
    -		// TODO Use CMail and translation
    -		$body = "Un virement de ".price2num($event->data->object->amount/100)." ".$event->data->object->currency." est attendu sur votre compte le ".date('d-m-Y H:i:s',$event->data->object->arrival_date);
    -		$subject = '[NOTIFICATION] Virement programmée';
    -		$headers = 'From: "'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'" <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>'; // TODO  convert in dolibarr standard
    -		mail(''.$conf->global->MAIN_INFO_SOCIETE_MAIL.'', $subject, $body, $headers);
    -		return 1;
    +        $subject = '[NOTIFICATION] Stripe payout scheduled';
    +        if (!empty($user->email)) {
    +            $sendto = dolGetFirstLastname($user->firstname, $user->lastname) . " <".$user->email.">";
    +        } else {
    +            $sendto = $conf->global->MAIN_INFO_SOCIETE_MAIL.'" <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>';
    +        }
    +        $replyto = $sendto;
    +        $sendtocc = '';
    +        if (!empty($conf->global->ONLINE_PAYMENT_SENDEMAIL)) {
    +            $sendtocc = $conf->global->ONLINE_PAYMENT_SENDEMAIL.'" <'.$conf->global->ONLINE_PAYMENT_SENDEMAIL.'>';
    +        }
    +
    +        $message = "A bank transfer of ".price2num($event->data->object->amount/100)." ".$event->data->object->currency." should arrive in your account the ".dol_print_date($event->data->object->arrival_date, 'dayhour');
    +
    +        $mailfile = new CMailFile(
    +            $subject,
    +            $sendto,
    +            $replyto,
    +            $message,
    +            array(),
    +            array(),
    +            array(),
    +            $sendtocc,
    +            '',
    +            0,
    +            -1
    +        );
    +
    +        $ret = $mailfile->sendfile();
    +
    +        return 1;
     	}
     	else
     	{
    @@ -206,61 +234,55 @@ elseif ($event->type == 'payout.paid') {
     elseif ($event->type == 'charge.succeeded') {
     
     	//TODO: create fees
    -
     }
     elseif ($event->type == 'customer.source.created') {
     
     	//TODO: save customer's source
    -
     }
     elseif ($event->type == 'customer.source.updated') {
     
     	//TODO: update customer's source
    -
     }
     elseif ($event->type == 'customer.source.delete') {
     
     	//TODO: delete customer's source
    -
     }
     elseif ($event->type == 'charge.failed') {
     
     	$subject = 'Your payment has been received: '.$event->data->object->id.'';
     	$headers = 'From: "'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'" <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>';
    -	//mail('ptibogxiv@msn.com', $subject, 'test', $headers);
    -
     }
     elseif (($event->type == 'source.chargeable') && ($event->data->object->type == 'three_d_secure') && ($event->data->object->three_d_secure->authenticated==true)) {
     
    -  $fulltag=$event->data->object->metadata->FULLTAG;
    +    $fulltag=$event->data->object->metadata->FULLTAG;
     	// Save into $tmptag all metadata
     	$tmptag=dolExplodeIntoArray($fulltag,'.','=');
    -  
    -  if (! empty($tmptag['ORD'])){
    -  $order=new Commande($db);
    -	$order->fetch('',$tmptag['ORD']);
    -  $origin='order';
    -  $item=$order->id;
    -  } elseif (! empty($tmptag['INV'])) {
    -  $invoice = new Facture($db);
    -	$invoice->fetch('',$tmptag['INV']);
    -  $origin='invoice';
    -  $item=$invoice->id;
    -  }
     
    -  $stripe=new Stripe($db); 
    -  $stripeacc = $stripe->getStripeAccount($service);								// Stripe OAuth connect account of dolibarr user (no network access here)
    -  $stripecu = $stripe->getStripeCustomerAccount($tmptag['CUS'], $servicestatus);		// Get thirdparty cu_...
    +    if (! empty($tmptag['ORD'])) {
    +        $order=new Commande($db);
    +	    $order->fetch('',$tmptag['ORD']);
    +        $origin='order';
    +        $item=$order->id;
    +    } elseif (! empty($tmptag['INV'])) {
    +        $invoice = new Facture($db);
    +	    $invoice->fetch('',$tmptag['INV']);
    +        $origin='invoice';
    +        $item=$invoice->id;
    +    }
    +
    +    $stripe=new Stripe($db);
    +    $stripeacc = $stripe->getStripeAccount($service);								// Stripe OAuth connect account of dolibarr user (no network access here)
    +    $stripecu = $stripe->getStripeCustomerAccount($tmptag['CUS'], $servicestatus);		// Get thirdparty cu_...
     	$charge=$stripe->createPaymentStripe($event->data->object->amount/100,$event->data->object->currency,$origin,$item,$event->data->object->id,$stripecu,$stripeacc,$servicestatus);
    -  
    -	if (isset($charge->id) && $charge->statut=='error'){
    +
    +	if (isset($charge->id) && $charge->statut=='error') {
     		$msg=$charge->message;
     		$code=$charge->code;
     		$error++;
    -	}              
    +	}
     	elseif (isset($charge->id) && $charge->statut=='success' && (! empty($tmptag['ORD']))) {
    -    //$order=new Commande($db);
    -	  //$order->fetch('',$tmptag['ORD']);
    +        //$order=new Commande($db);
    +	    //$order->fetch('',$tmptag['ORD']);
     		$invoice = new Facture($db);
     		$idinv=$invoice->createFromOrder($order,$user);
     
    @@ -276,17 +298,17 @@ elseif (($event->type == 'source.chargeable') && ($event->data->object->type ==
     				$ifverif=$invoice->socid;
     				$currency=$invoice->multicurrency_code;
     				$total=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
    -			}else{
    +			} else {
     				$msg=$invoice->error;
     				$error++;
     			}
    -		}else{
    +		} else {
     			$msg=$invoice->error;
     			$error++;
     		}
     	}
     
    -	if (!$error){
    +	if (!$error) {
     		$datepaye = dol_now();
     		$paymentType ="CB";
     		$amounts=array();
    @@ -302,10 +324,10 @@ elseif (($event->type == 'source.chargeable') && ($event->data->object->type ==
     		$paiement->note         = '';
     	}
     
    -	if (! $error){
    +	if (! $error) {
     		$paiement_id=$paiement->create($user, 0);
     
    -		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE) && count($invoice->lines)){
    +		if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE) && count($invoice->lines)) {
     			$outputlangs = $langs;
     			$newlang = '';
     			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
    @@ -319,17 +341,17 @@ elseif (($event->type == 'source.chargeable') && ($event->data->object->type ==
     
     			$invoice->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
     		}
    -		if ($paiement_id < 0){
    +		if ($paiement_id < 0) {
     			$msg=$paiement->errors;
     			$error++;
    -		}else{
    +		} else {
     			if ($event->data->object->metadata->source=='order') {
     				$order->classifyBilled($user);
     			}
     		}
     	}
     
    -	if (! $error){
    +	if (! $error) {
     		$label='(CustomerInvoicePayment)';
     		if (GETPOST('type') == 2) $label='(CustomerInvoicePaymentBack)';
     		$paiement->addPaymentToBank($user,'payment',$label,$conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS,'','');
    @@ -344,7 +366,6 @@ elseif (($event->type == 'source.chargeable') && ($event->data->object->type ==
     	$body = "";
     	$subject = 'Facture '.$invoice->ref;
     	$headers = 'From: "'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'" <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>';
    -	//mail('ptibogxiv@msn.com', $subject, $body, $headers); TODO  convert in dolibarr standard
     }
     elseif ($event->type == 'customer.deleted') {
     	$db->begin();
    @@ -353,4 +374,3 @@ elseif ($event->type == 'customer.deleted') {
     	$db->query($sql);
     	$db->commit();
     }
    -
    diff --git a/htdocs/public/stripe/paymentko.php b/htdocs/public/stripe/paymentko.php
    index ff1abfae9e4..be285cfc628 100644
    --- a/htdocs/public/stripe/paymentko.php
    +++ b/htdocs/public/stripe/paymentko.php
    @@ -36,14 +36,7 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("paybox");
    -$langs->load("paypal");
    -$langs->load("stripe");
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal", "stripe"));
     
     $FULLTAG=GETPOST('FULLTAG');
     if (empty($FULLTAG)) $FULLTAG=GETPOST('fulltag');
    diff --git a/htdocs/public/stripe/paymentok.php b/htdocs/public/stripe/paymentok.php
    index 52b3dac8a7f..4bce7dd62ce 100644
    --- a/htdocs/public/stripe/paymentok.php
    +++ b/htdocs/public/stripe/paymentok.php
    @@ -36,13 +36,7 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     
    -$langs->load("main");
    -$langs->load("other");
    -$langs->load("dict");
    -$langs->load("bills");
    -$langs->load("companies");
    -$langs->load("paybox");
    -$langs->load("paypal");
    +$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "paybox", "paypal"));
     
     $FULLTAG=GETPOST('FULLTAG');
     if (empty($FULLTAG)) $FULLTAG=GETPOST('fulltag');
    diff --git a/htdocs/public/test/index.html b/htdocs/public/test/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/public/test/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/public/test/test_arrays.php b/htdocs/public/test/test_arrays.php
    index 02f5786632c..e3a5f33cbeb 100644
    --- a/htdocs/public/test/test_arrays.php
    +++ b/htdocs/public/test/test_arrays.php
    @@ -174,9 +174,9 @@ if ($showbirthday)  $nav.='<input type="hidden" name="showbirthday" value="1">';
     if ($pid)    $nav.='<input type="hidden" name="projectid" value="'.$pid.'">';
     if ($type)   $nav.='<input type="hidden" name="type" value="'.$type.'">';
     if ($usergroup) $nav.='<input type="hidden" name="usergroup" value="'.$usergroup.'">';
    -$nav.=$form->select_date($dateselect, 'dateselect', 0, 0, 1, '', 1, 0, 1);
    -$nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
    -$nav.='</form>';
    +$nav.= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0);
    +$nav.= ' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
    +$nav.= '</form>';
     
     $limit=10;
     print_barre_liste('Title of my list', 12, $_SERVER["PHP_SELF"], '', '', '', 'Text in middle', 20, 500, '', 0, $nav, '', $limit);
    diff --git a/htdocs/public/test/test_forms.php b/htdocs/public/test/test_forms.php
    index 0250bb2c39f..343acab9a4a 100644
    --- a/htdocs/public/test/test_forms.php
    +++ b/htdocs/public/test/test_forms.php
    @@ -27,29 +27,29 @@ This page is a sample of page using Dolibarr HTML widget methods. It is designed
     <?php
     $form=new Form($db);
     
    -// Test1: form->select_date using tzuser date
    +// Test1: form->selectDate using tzuser date
     print "Test 1a: We must have here current date and hour for user (must match hour on browser). Note: Check your are logged so user TZ and DST are known.";
     $offsettz=(empty($_SESSION['dol_tz'])?0:$_SESSION['dol_tz'])*60*60;
     $offsetdst=(empty($_SESSION['dol_dst'])?0:$_SESSION['dol_dst'])*60*60;
     print " (dol_tz=".$offsettz." dol_dst=".$dol_dst.")<br>\n";
    -$form->select_date(dol_now(), 'test1a', 1, 1, 0);
    +print $form->selectDate(dol_now(), 'test1a', 1, 1, 0);
     
     print '<br><br>'."\n";
     
     print "Test 1b: We must have here current date with hours to 00:00.<br>";
    -$form->select_date('', 'test1b', 1, 1, 0);
    +print $form->selectDate('', 'test1b', 1, 1, 0);
     
     print '<br><br>'."\n";
     
    -// Test2: form->select_date using tzuser date
    +// Test2: form->selectDate using tzuser date
     print "Test 2: We must have here 1970-01-01 00:00:00 selected (fields can be empty)<br>\n";
    -$form->select_date(dol_get_first_day(1970,1,false), 'test2', 1, 1, 1);
    +print $form->selectDate(dol_get_first_day(1970,1,false), 'test2', 1, 1, 1);
     
     print '<br><br>'."\n";
     
    -// Test3: form->select_date for 1970-01-01 00:00:00
    +// Test3: form->selectDate for 1970-01-01 00:00:00
     print "Test 3: We must have here 1970-01-01 00:00:00 selected (fields are mandatory)<br>\n";
    -$form->select_date(dol_get_first_day(1970,1,false), 'test3', 1, 1, 0);
    +print $form->selectDate(dol_get_first_day(1970,1,false), 'test3', 1, 1, 0);
     
     print '<br><br>'."\n";
     
    @@ -94,6 +94,6 @@ $array=array(1=>'Value 1',2=>'Value 2',3=>'Value 3');
     $arrayselected=array(1,3);
     print $form->multiselectarray('testmulti', $array, $arrayselected, '', 0, '', 0, 250);
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php
    index 066471fddff..d451d96d011 100644
    --- a/htdocs/public/ticket/create_ticket.php
    +++ b/htdocs/public/ticket/create_ticket.php
    @@ -177,7 +177,7 @@ if ($action == 'create_ticket' && GETPOST('add_ticket')) {
             	$action = "infos_success";
             } else {
     	    	$object->db->rollback();
    -	    	setEventMessage($object->errors, 'errors');
    +	    	setEventMessages($object->error, $object->errors, 'errors');
     	    	$action = 'create_ticket';
     	    }
     
    @@ -226,8 +226,8 @@ if ($action == 'create_ticket' && GETPOST('add_ticket')) {
                     }
                     include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
                     $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
    -                if ($mailfile->error) {
    -                    setEventMessage($mailfile->error, 'errors');
    +                if ($mailfile->error || $mailfile->errors) {
    +                    setEventMessages($mailfile->error, $mailfile->errors, 'errors');
                     } else {
                         $result = $mailfile->sendfile();
                     }
    @@ -287,9 +287,9 @@ if ($action == 'create_ticket' && GETPOST('add_ticket')) {
     	                }
     	                include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
     	                $mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1);
    -	                if ($mailfile->error) {
    -	                    setEventMessage($mailfile->error, 'errors');
    -	                } else {
    +	                if ($mailfile->error || $mailfile->errors) {
    +                        setEventMessages($mailfile->error, $mailfile->errors, 'errors');
    +                    } else {
     	                    $result = $mailfile->sendfile();
     	                }
     	                if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
    @@ -308,10 +308,10 @@ if ($action == 'create_ticket' && GETPOST('add_ticket')) {
                 	$formmail->remove_attached_files($i);
                 }
     
    -            setEventMessage($langs->trans('YourTicketSuccessfullySaved'));
    +            setEventMessages($langs->trans('YourTicketSuccessfullySaved'), null, 'mesgs');
             }
         } else {
    -        setEventMessage($object->errors, 'errors');
    +        setEventMessages($object->error, $object->errors, 'errors');
         }
     }
     
    diff --git a/htdocs/public/ticket/img/index.html b/htdocs/public/ticket/img/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/public/ticket/img/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/public/ticket/index.php b/htdocs/public/ticket/index.php
    index bb0499f43e6..52b3b843fa1 100644
    --- a/htdocs/public/ticket/index.php
    +++ b/htdocs/public/ticket/index.php
    @@ -25,11 +25,18 @@ if (!defined('NOCSRFCHECK'))   define('NOCSRFCHECK', '1');
     if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1');
     if (!defined("NOLOGIN"))       define("NOLOGIN", '1');				// If this page is public (can be called outside logged session)
     
    +// For MultiCompany module.
    +// Do not use GETPOST here, function is not defined and define must be done before including main.inc.php
    +// TODO This should be useless. Because entity must be retreive from object ref and not from url.
    +$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
    +if (is_numeric($entity)) define("DOLENTITY", $entity);
    +
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/ticket/class/actions_ticket.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formticket.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ticket.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array('companies', 'other', 'ticket', 'errors'));
    @@ -64,5 +71,8 @@ if (!$conf->global->TICKET_ENABLE_PUBLIC_INTERFACE) {
     }
     
     // End of page
    -llxFooter();
    +htmlPrintOnlinePaymentFooter($mysoc,$langs,1,$suffix,$object);
    +
    +llxFooter('', 'public');
    +
     $db->close();
    diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php
    index d8290849f55..5ab17fedba2 100644
    --- a/htdocs/public/ticket/list.php
    +++ b/htdocs/public/ticket/list.php
    @@ -121,8 +121,8 @@ if ($action == "view_ticketlist") {
             }
         }
     
    -    if ($error) {
    -        setEventMessage($object->errors, 'errors');
    +    if ($error || $errors) {
    +        setEventMessages($object->error, $object->errors, 'errors');
             $action = '';
         }
     }
    diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php
    index 5383133c42e..b5288b97a25 100644
    --- a/htdocs/public/ticket/view.php
    +++ b/htdocs/public/ticket/view.php
    @@ -1,5 +1,6 @@
     <?php
    -/*  Copyright (C) - 2013-2016    Jean-François FERRY    <hello@librethic.io>
    +/* Copyright (C) 2013-2016  Jean-François FERRY     <hello@librethic.io>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -112,8 +113,8 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" |
             }
         }
     
    -    if ($error) {
    -        setEventMessage($object->errors, 'errors');
    +    if ($error || $errors) {
    +        setEventMessages($object->error, $object->errors, 'errors');
             $action = '';
         }
     }
    @@ -145,10 +146,7 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" |
         if ($display_ticket) {
             // Confirmation close
             if ($action == 'close') {
    -            $ret = $form->form_confirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1);
    -            if ($ret == 'html') {
    -                print '<br>';
    -            }
    +            print $form->form_confirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1);
             }
     
             print '<div id="form_view_ticket">';
    diff --git a/htdocs/public/website/index.php b/htdocs/public/website/index.php
    index b61c02e9d63..19abc48094b 100644
    --- a/htdocs/public/website/index.php
    +++ b/htdocs/public/website/index.php
    @@ -18,8 +18,7 @@
     /**
      *     	\file       htdocs/public/website/index.php
      *		\ingroup    website
    - *		\brief      Page to output pages
    - *		\author	    Laurent Destailleur
    + *		\brief      Wrapper to output pages when website is powered by Dolibarr instead of a native web server
      */
     
     if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal
    @@ -34,13 +33,17 @@ if (! defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX','1');
      *
      * @return	void
      */
    -function llxHeader() { }
    +function llxHeader()
    +{
    +}
     /**
      * Footer empty
      *
      * @return	void
      */
    -function llxFooter() { }
    +function llxFooter()
    +{
    +}
     
     require '../../master.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -55,87 +58,91 @@ $accessallowed = 1;
     $type='';
     
     
    -/*
    - * View
    - */
    +if (empty($pageid))
    +{
    +	require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
    +	require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    +
    +	$object=new Website($db);
    +	$object->fetch(0, $websitekey);
    +
    +	if (empty($object->id))
    +	{
    +		if (empty($pageid))
    +		{
    +			// Return header 404
    +			header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    +
    +			include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    +			exit;
    +		}
    +	}
    +
    +	$objectpage=new WebsitePage($db);
    +
    +	if ($pageref)
    +	{
    +		$result=$objectpage->fetch(0, $object->id, $pageref);
    +		if ($result > 0)
    +		{
    +			$pageid = $objectpage->id;
    +		}
    +		elseif($result == 0)
    +		{
    +			// Page not found from ref=pageurl, we try using alternative alias
    +			$result=$objectpage->fetch(0, $object->id, null, $pageref);
    +			if ($result > 0)
    +			{
    +				$pageid = $objectpage->id;
    +			}
    +		}
    +	}
    +	else
    +	{
    +		if ($object->fk_default_home > 0)
    +		{
    +			$result=$objectpage->fetch($object->fk_default_home);
    +			if ($result > 0)
    +			{
    +				$pageid = $objectpage->id;
    +			}
    +		}
    +
    +		if (empty($pageid))
    +		{
    +			$array=$objectpage->fetchAll($object->id);
    +			if (is_array($array) && count($array) > 0)
    +			{
    +				$firstrep=reset($array);
    +				$pageid=$firstrep->id;
    +			}
    +		}
    +	}
    +}
    +if (empty($pageid))
    +{
    +	// Return header 404
    +	header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    +
    +	$langs->load("website");
    +
    +	if (! GETPOSTISSET('pageref')) print $langs->trans("PreviewOfSiteNotYetAvailable", $websitekey);
    +
    +	include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    +	exit;
    +}
     
     $appli=constant('DOL_APPLICATION_TITLE');
     if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
     
    +
    +
    +/*
    + * View
    + */
    +
     //print 'Directory with '.$appli.' websites.<br>';
     
    -if (empty($pageid))
    -{
    -    require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
    -    require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    -
    -    $object=new Website($db);
    -    $object->fetch(0, $websitekey);
    -
    -	if (empty($object->id))
    -    {
    -        if (empty($pageid))
    -        {
    -            // Return header 404
    -            header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    -
    -            include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    -            exit;
    -        }
    -    }
    -
    -    $objectpage=new WebsitePage($db);
    -
    -    if ($pageref)
    -    {
    -    	$result=$objectpage->fetch(0, $object->id, $pageref);
    -    	if ($result > 0)
    -	    {
    -	        $pageid = $objectpage->id;
    -	    }
    -	    elseif($result == 0)
    -	    {
    -	    	// Page not found from ref=pageurl, we try using alternative alias
    -	    	$result=$objectpage->fetch(0, $object->id, null, $pageref);
    -	    	if ($result > 0)
    -	    	{
    -	    		$pageid = $objectpage->id;
    -	    	}
    -	    }
    -    }
    -    else
    -    {
    -	    if ($object->fk_default_home > 0)
    -	    {
    -	        $result=$objectpage->fetch($object->fk_default_home);
    -	        if ($result > 0)
    -	        {
    -	            $pageid = $objectpage->id;
    -	        }
    -	    }
    -
    -	    if (empty($pageid))
    -	    {
    -	        $array=$objectpage->fetchAll($object->id);
    -	        if (is_array($array) && count($array) > 0)
    -	        {
    -	            $firstrep=reset($array);
    -	            $pageid=$firstrep->id;
    -	        }
    -	    }
    -    }
    -}
    -if (empty($pageid))
    -{
    -    // Return header 404
    -    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    -
    -    $langs->load("website");
    -    print $langs->trans("PreviewOfSiteNotYetAvailable");
    -
    -    include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    -    exit;
    -}
     
     // Security: Delete string ../ into $original_file
     global $dolibarr_main_data_root;
    @@ -203,4 +210,3 @@ print '<!-- Page content '.$original_file.' rendered with DOLIBARR SERVER : Html
     include_once $original_file_osencoded;		// Note: The pageXXX.tpl.php showed here contains a formatage with dolWebsiteOutput() at end of page.
     
     if (is_object($db)) $db->close();
    -
    diff --git a/htdocs/public/website/styles.css.php b/htdocs/public/website/styles.css.php
    index 36e93d00faf..3e2462d889c 100644
    --- a/htdocs/public/website/styles.css.php
    +++ b/htdocs/public/website/styles.css.php
    @@ -33,13 +33,17 @@ if (! defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX','1');
      *
      * @return	void
      */
    -function llxHeader() { }
    +function llxHeader()
    +{
    +}
     /**
      * Footer empty
      *
      * @return	void
      */
    -function llxFooter() { }
    +function llxFooter()
    +{
    +}
     
     require '../../master.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
    @@ -81,7 +85,7 @@ if (empty($pageid))
         $objectpage=new WebsitePage($db);
         $array=$objectpage->fetchAll($object->id);
     
    -    if (count($array) > 0)
    +    if (is_array($array) && count($array) > 0)
         {
             $firstrep=reset($array);
             $pageid=$firstrep->id;
    @@ -145,4 +149,3 @@ require_once $original_file_osencoded;
     
     
     if (is_object($db)) $db->close();
    -
    diff --git a/htdocs/resource/agenda.php b/htdocs/resource/agenda.php
    new file mode 100644
    index 00000000000..442be89f923
    --- /dev/null
    +++ b/htdocs/resource/agenda.php
    @@ -0,0 +1,175 @@
    +<?php
    +/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    + * Copyright (C) 2005      Brice Davoleau       <brice.davoleau@gmail.com>
    + * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    + * Copyright (C) 2006-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2007      Patrick Raguin  		<patrick.raguin@gmail.com>
    + * Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
    + * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
    + * Copyright (C) 2018      Florain Henry        <florian.henry@open-concept.pro
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *  \file       htdocs/resource/agenda.php
    + *  \ingroup    resource
    + *  \brief      Page of resource events
    + */
    +
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/resource.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
    +
    +// Load translation files required by the page
    +$langs->load("companies");
    +
    +if (GETPOST('actioncode','array'))
    +{
    +    $actioncode=GETPOST('actioncode','array',3);
    +    if (! count($actioncode)) $actioncode='0';
    +}
    +else
    +{
    +    $actioncode=GETPOST("actioncode","alpha",3)?GETPOST("actioncode","alpha",3):(GETPOST("actioncode")=='0'?'0':(empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)?'':$conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT));
    +}
    +$search_agenda_label=GETPOST('search_agenda_label');
    +
    +// Security check
    +$id = GETPOST('id','int');
    +$ref = GETPOST('ref', 'alpha');
    +if ($user->societe_id) $id=$user->societe_id;
    +// Protection if external user
    +if ($user->socid > 0)
    +{
    +	accessforbidden();
    +}
    +
    +if( ! $user->rights->resource->read)
    +{
    +	accessforbidden();
    +}
    +
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    +$sortfield = GETPOST("sortfield",'alpha');
    +$sortorder = GETPOST("sortorder",'alpha');
    +$page = GETPOST("page",'int');
    +if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
    +$offset = $limit * $page;
    +$pageprev = $page - 1;
    +$pagenext = $page + 1;
    +if (! $sortfield) $sortfield='a.datep,a.id';
    +if (! $sortorder) $sortorder='DESC,DESC';
    +
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$hookmanager->initHooks(array('agendaresource'));
    +
    +
    +/*
    + *	Actions
    + */
    +
    +$parameters=array('id'=>$id);
    +$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))
    +{
    +    // Cancel
    +    if (GETPOST('cancel','alpha') && ! empty($backtopage))
    +    {
    +        header("Location: ".$backtopage);
    +        exit;
    +    }
    +
    +    // Purge search criteria
    +    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
    +    {
    +        $actioncode='';
    +        $search_agenda_label='';
    +    }
    +}
    +
    +
    +
    +/*
    + *	View
    + */
    +
    +$contactstatic = new Contact($db);
    +
    +$form = new Form($db);
    +
    +if ($id > 0 || $ref)
    +{
    +	require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    +	require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    +
    +	$langs->load("companies");
    +	$picto = 'resource';
    +
    +	$object = new Dolresource($db);
    +	$result = $object->fetch($id);
    +
    +	$title=$langs->trans("Agenda");
    +	if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/productnameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->ref." - ".$title;
    +	llxHeader('',$title);
    +
    +	if (! empty($conf->notification->enabled)) $langs->load("mails");
    +	$type = $langs->trans('ResourceSingular');
    +
    +	$head = resource_prepare_head($object);
    +
    +	$titre=$langs->trans("ResourceSingular");
    +	dol_fiche_head($head, 'agenda', $titre, -1, $picto);
    +
    +    $linkback = '<a href="'.DOL_URL_ROOT.'/resource/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
    +
    +    $shownav = 1;
    +    if ($user->societe_id && ! in_array('resource', explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL))) $shownav=0;
    +
    +    dol_banner_tab($object, 'id', $linkback, $shownav, 'id');
    +
    +    print '<div class="fichecenter">';
    +
    +    print '<div class="underbanner clearboth"></div>';
    +
    +	print '</div>';
    +
    +	dol_fiche_end();
    +
    +    if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) ))
    +    {
    +    	print '<br>';
    +
    +        $param='&id='.$id;
    +        if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
    +        if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
    +
    +		print_barre_liste($langs->trans("ActionsOnResource"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlcenter, '', 0, 1, 1);
    +
    +        // List of all actions
    +		$filters=array();
    +        $filters['search_agenda_label']=$search_agenda_label;
    +
    +        // TODO Replace this with same code than into list.php
    +        show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters, $sortfield, $sortorder);
    +    }
    +}
    +
    +// End of page
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/resource/card.php b/htdocs/resource/card.php
    index 832f70f4ea1..49cad87e990 100644
    --- a/htdocs/resource/card.php
    +++ b/htdocs/resource/card.php
    @@ -22,12 +22,7 @@
      */
     
     
    -// Change this following line to use the correct relative path (../, ../../, etc)
    -$res=0;
    -$res=@include("../main.inc.php");				// For root directory
    -if (! $res) $res=@include("../../main.inc.php");	// For "custom" directory
    -if (! $res) die("Include of main fails");
    -
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
     require_once DOL_DOCUMENT_ROOT.'/resource/class/html.formresource.class.php';
    @@ -176,7 +171,6 @@ if (empty($reshook))
     					setEventMessages($object->error, $object->errors, 'errors');
     					$error++;
     				}
    -
     			}
     			else
     			{
    @@ -406,8 +400,6 @@ else {
     	dol_print_error();
     }
     
    -
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/resource/class/dolresource.class.php b/htdocs/resource/class/dolresource.class.php
    index 7c3999db7c9..ad3355e3972 100644
    --- a/htdocs/resource/class/dolresource.class.php
    +++ b/htdocs/resource/class/dolresource.class.php
    @@ -19,19 +19,26 @@
      *  \file      	resource/class/resource.class.php
      *  \ingroup    resource
      *  \brief      Class file for resource object
    -
      */
     
     require_once DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php";
     require_once DOL_DOCUMENT_ROOT."/core/lib/functions2.lib.php";
     
     /**
    - *	DAO Resource object
    + *  DAO Resource object
      */
     class Dolresource extends CommonObject
     {
    -	public $element='dolresource';			//!< Id that identify managed objects
    -	public $table_element='resource';	//!< Name of table without prefix where object is stored
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='dolresource';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='resource';
    +
         public $picto = 'resource';
     
     	public $resource_id;
    @@ -40,7 +47,12 @@ class Dolresource extends CommonObject
     	public $element_type;
     	public $busy;
     	public $mandatory;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_create;
    +
     	public $type_label;
     	public $tms='';
     
    @@ -54,20 +66,19 @@ class Dolresource extends CommonObject
         function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
         /**
          *  Create object into database
          *
    -     *  @param	User	$user        User that creates
    +     *  @param	User    $user        User that creates
          *  @param  int		$notrigger   0=launch triggers after, 1=disable triggers
          *  @return int      		   	 <0 if KO, Id of created object if OK
          */
         function create($user, $notrigger=0)
         {
    -    	global $conf, $langs, $hookmanager;
    -    	$error=0;
    +        global $conf, $langs, $hookmanager;
    +        $error=0;
     
         	// Clean parameters
     
    @@ -326,6 +337,7 @@ class Dolresource extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Load object in memory from database
          *
    @@ -334,6 +346,7 @@ class Dolresource extends CommonObject
          */
         function fetch_element_resource($id)
         {
    +        // phpcs:enable
         	global $langs;
         	$sql = "SELECT";
         	$sql.= " t.rowid,";
    @@ -371,7 +384,6 @@ class Dolresource extends CommonObject
     				if($obj->element_id && $obj->element_type) {
     					$this->objelement = fetchObjectByElement($obj->element_id,$obj->element_type);
     				}
    -
         		}
         		$this->db->free($resql);
     
    @@ -470,6 +482,7 @@ class Dolresource extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Load resource objects into $this->lines
          *
    @@ -482,6 +495,7 @@ class Dolresource extends CommonObject
          */
         function fetch_all($sortorder, $sortfield, $limit, $offset, $filter='')
         {
    +        // phpcs:enable
         	global $conf;
         	$sql="SELECT ";
         	$sql.= " t.rowid,";
    @@ -491,7 +505,7 @@ class Dolresource extends CommonObject
         	$sql.= " t.fk_code_type_resource,";
         	$sql.= " t.tms,";
     
    -    	require_once(DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php');
    +    	require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
         	$extrafields=new ExtraFields($this->db);
         	$extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
         	if (is_array($extralabels) && count($extralabels)>0) {
    @@ -563,9 +577,9 @@ class Dolresource extends CommonObject
         		$this->error = $this->db->lasterror();
         		return -1;
         	}
    -
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
          /**
          *	Load all objects into $this->lines
          *
    @@ -578,6 +592,7 @@ class Dolresource extends CommonObject
          */
         function fetch_all_resources($sortorder, $sortfield, $limit, $offset, $filter='')
         {
    +        // phpcs:enable
        		global $conf;
        		$sql="SELECT ";
        		$sql.= " t.rowid,";
    @@ -630,7 +645,6 @@ class Dolresource extends CommonObject
     					if($obj->element_id && $obj->element_type)
     						$line->objelement = fetchObjectByElement($obj->element_id,$obj->element_type);
             			$this->lines[] = $line;
    -
        				}
        				$this->db->free($resql);
        			}
    @@ -641,9 +655,9 @@ class Dolresource extends CommonObject
        			$this->error = $this->db->lasterror();
        			return -1;
        		}
    -
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Load all objects into $this->lines
          *
    @@ -656,6 +670,7 @@ class Dolresource extends CommonObject
          */
         function fetch_all_used($sortorder, $sortfield, $limit, $offset=1, $filter='')
         {
    +        // phpcs:enable
         	global $conf;
     
         	if ( ! $sortorder) $sortorder="ASC";
    @@ -719,9 +734,9 @@ class Dolresource extends CommonObject
         		$this->error = $this->db->lasterror();
         		return -1;
         	}
    -
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * Fetch all resources available, declared by modules
          * Load available resource in array $this->available_resources
    @@ -730,7 +745,9 @@ class Dolresource extends CommonObject
          * @deprecated, remplaced by hook getElementResources
          * @see getElementResources()
          */
    -    function fetch_all_available() {
    +    function fetch_all_available()
    +    {
    +        // phpcs:enable
         	global $conf;
     
         	if (! empty($conf->modules_parts['resources']))
    @@ -742,6 +759,7 @@ class Dolresource extends CommonObject
         	return 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Update element resource into database
          *
    @@ -751,6 +769,7 @@ class Dolresource extends CommonObject
          */
         function update_element_resource($user=null, $notrigger=0)
         {
    +        // phpcs:enable
         	global $conf, $langs;
     		$error=0;
     
    @@ -866,10 +885,10 @@ class Dolresource extends CommonObject
                 $i++;
             }
             return $i;
    -
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *      Load in cache resource type code (setup in dictionary)
          *
    @@ -877,6 +896,7 @@ class Dolresource extends CommonObject
          */
         function load_cache_code_type_resource()
         {
    +        // phpcs:enable
         	global $langs;
     
         	if (count($this->cache_code_type_resource)) return 0;    // Cache deja charge
    @@ -956,6 +976,7 @@ class Dolresource extends CommonObject
             return $this->LibStatut($this->status,$mode);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Return the status
          *
    @@ -965,6 +986,7 @@ class Dolresource extends CommonObject
          */
         static function LibStatut($status,$mode=0)
         {
    +        // phpcs:enable
             global $langs;
     
             return '';
    diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php
    index 19bed957f74..c118643aa7d 100644
    --- a/htdocs/resource/class/html.formresource.class.php
    +++ b/htdocs/resource/class/html.formresource.class.php
    @@ -21,8 +21,8 @@
      *       \ingroup    core
      *       \brief      Class file to manage forms into resource module
      */
    -require_once(DOL_DOCUMENT_ROOT ."/core/class/html.form.class.php");
    -require_once(DOL_DOCUMENT_ROOT ."/resource/class/dolresource.class.php");
    +require_once DOL_DOCUMENT_ROOT ."/core/class/html.form.class.php";
    +require_once DOL_DOCUMENT_ROOT ."/resource/class/dolresource.class.php";
     
     
     /**
    @@ -33,12 +33,19 @@ require_once(DOL_DOCUMENT_ROOT ."/resource/class/dolresource.class.php");
      */
     class FormResource
     {
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    var $substit=array();
    -    var $param=array();
    +    public $substit=array();
     
    -    var $error;
    +    public $param=array();
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
     
     	/**
    @@ -49,11 +56,10 @@ class FormResource
         function __construct($db)
         {
             $this->db = $db;
    -
    -        return 1;
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Output html form to select a resource
          *
    @@ -71,6 +77,7 @@ class FormResource
          */
         function select_resource_list($selected='',$htmlname='fk_resource',$filter='',$showempty=0, $showtype=0, $forcecombo=0, $event=array(), $filterkey='', $outputmode=0, $limit=20)
         {
    +        // phpcs:enable
         	global $conf,$user,$langs;
     
         	$out='';
    @@ -148,20 +155,22 @@ class FormResource
         	return $out;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *      Return html list of tickets type
    +     *  Return html list of tickets type
          *
    -     *      @param	string	$selected       Id du type pre-selectionne
    -     *      @param  string	$htmlname       Nom de la zone select
    -     *      @param  string	$filtertype     To filter on field type in llx_c_ticket_type (array('code'=>xx,'label'=>zz))
    -     *      @param  int		$format         0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code
    -     *      @param  int		$empty			1=peut etre vide, 0 sinon
    -     * 		@param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
    -     *      @param  int		$maxlength      Max length of label
    -     * 		@return	void
    +     *  @param	string	$selected       Id du type pre-selectionne
    +     *  @param  string	$htmlname       Nom de la zone select
    +     *  @param  string	$filtertype     To filter on field type in llx_c_ticket_type (array('code'=>xx,'label'=>zz))
    +     *  @param  int		$format         0=id+libelle, 1=code+code, 2=code+libelle, 3=id+code
    +     *  @param  int		$empty			1=peut etre vide, 0 sinon
    +     *  @param	int		$noadmininfo	0=Add admin info, 1=Disable admin info
    +     *  @param  int		$maxlength      Max length of label
    +     * 	@return	void
          */
         function select_types_resource($selected='',$htmlname='type_resource',$filtertype='',$format=0, $empty=0, $noadmininfo=0,$maxlength=0)
         {
    +        // phpcs:enable
         	global $langs,$user;
     
         	$resourcestat = new Dolresource($this->db);
    @@ -202,8 +211,4 @@ class FormResource
         	print '</select>';
         	if ($user->admin && ! $noadmininfo) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
         }
    -
    -
    -
     }
    -
    diff --git a/htdocs/resource/contact.php b/htdocs/resource/contact.php
    index 981a07d7e73..a90d68ff94c 100644
    --- a/htdocs/resource/contact.php
    +++ b/htdocs/resource/contact.php
    @@ -2,7 +2,7 @@
     /* Copyright (C) 2005-2012  Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2007-2009  Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2012       Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2016		    Gilles Poirier		   <glgpoirier@gmail.com>
    + * Copyright (C) 2016		Gilles Poirier		 <glgpoirier@gmail.com>
     
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -47,7 +47,7 @@ $result = $object->fetch($id,$ref);
     
     
     /*
    - * Ajout d'un nouveau contact
    + * Add a new contact
      */
     
     if ($action == 'addcontact' && $user->rights->resource->write)
    @@ -72,17 +72,17 @@ if ($action == 'addcontact' && $user->rights->resource->write)
     			$mesg = $object->error;
     		}
     
    -		setEventMessage($mesg, 'errors');
    +		setEventMessages($mesg, null, 'errors');
     	}
     }
     
    -// bascule du statut d'un contact
    +// Toggle the status of a contact
     else if ($action == 'swapstatut' && $user->rights->resource->write)
     {
         $result=$object->swapContactStatus(GETPOST('ligne','int'));
     }
     
    -// Efface un contact
    +// Erase a contact
     else if ($action == 'deletecontact' && $user->rights->resource->write)
     {
     	$result = $object->delete_contact(GETPOST('lineid','int'));
    @@ -162,6 +162,6 @@ if ($id > 0 || ! empty($ref))
     	include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/resource/document.php b/htdocs/resource/document.php
    index edaf52baba3..85ec5b96c79 100644
    --- a/htdocs/resource/document.php
    +++ b/htdocs/resource/document.php
    @@ -91,7 +91,7 @@ if ($object->id)
     	dol_fiche_head($head, 'documents',  $langs->trans("ResourceSingular"), -1, 'resource');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -135,14 +135,12 @@ if ($object->id)
         $permission = $user->rights->resource->write;
     
         include_once DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php';
    -
     }
     else
     {
     	print $langs->trans("ErrorUnknown");
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php
    index 389d0236759..a83e37bc0b4 100644
    --- a/htdocs/resource/element_resource.php
    +++ b/htdocs/resource/element_resource.php
    @@ -23,11 +23,7 @@
      */
     
     
    -$res=0;
    -$res=@include("../main.inc.php");                               // For root directory
    -if (! $res) $res=@include("../../main.inc.php");        // For "custom" directory
    -if (! $res) die("Include of main fails");
    -
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/resource/class/dolresource.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
    @@ -466,7 +462,6 @@ else
     				if(file_exists(dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php')))
     				{
     					$res=@include dol_buildpath($path.'/core/tpl/resource_'.$element_prop['element'].'_view.tpl.php');
    -
     				}
     				else
     				{
    @@ -477,6 +472,6 @@ else
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php
    index 85be267613d..4492d74be65 100644
    --- a/htdocs/resource/list.php
    +++ b/htdocs/resource/list.php
    @@ -289,5 +289,6 @@ else
     print '</table>';
     print "</form>\n";
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/resource/note.php b/htdocs/resource/note.php
    index 9116cdd0387..f811d0e07ed 100644
    --- a/htdocs/resource/note.php
    +++ b/htdocs/resource/note.php
    @@ -100,5 +100,6 @@ if ($id > 0 || ! empty($ref))
     	dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/admin/contact_extrafields.php b/htdocs/societe/admin/contact_extrafields.php
    index 4facdd11ea1..5eaba3c1cb1 100644
    --- a/htdocs/societe/admin/contact_extrafields.php
    +++ b/htdocs/societe/admin/contact_extrafields.php
    @@ -28,8 +28,7 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
    -$langs->load("companies");
    -$langs->load("admin");
    +$langs->loadLangs(array("companies", "admin"));
     
     $extrafields = new ExtraFields($db);
     $form = new Form($db);
    @@ -81,7 +80,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -94,8 +93,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    @@ -113,6 +112,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/admin/societe.php b/htdocs/societe/admin/societe.php
    index ecbefe2cb1d..0166b6a233a 100644
    --- a/htdocs/societe/admin/societe.php
    +++ b/htdocs/societe/admin/societe.php
    @@ -29,8 +29,7 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     
    -$langs->load("admin");
    -$langs->load('other');
    +$langs->loadLangs(array("admin", "other"));
     
     $action=GETPOST('action','alpha');
     $value=GETPOST('value','alpha');
    @@ -182,6 +181,21 @@ if ($action=="setaddrefinlist") {
     	}
     }
     
    +//Activate Set adress in list
    +if ($action=="setaddadressinlist") {
    +	$val = GETPOST('value','int');
    +	$res = dolibarr_set_const($db, "COMPANY_SHOW_ADDRESS_SELECTLIST", $val,'yesno',0,'',$conf->entity);
    +	if (! $res > 0) $error++;
    +	if (! $error)
    +	{
    +		setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +	}
    +	else
    +	{
    +		setEventMessages($langs->trans("Error"), null, 'errors');
    +	}
    +}
    +
     //Activate Ask For Preferred Shipping Method
     if ($action=="setaskforshippingmet") {
     	$setaskforshippingmet = GETPOST('value','int');
    @@ -197,6 +211,21 @@ if ($action=="setaskforshippingmet") {
     	}
     }
     
    +//Activate "Disable prospect/customer type"
    +if ($action=="setdisableprospectcustomer") {
    +    $setdisableprospectcustomer = GETPOST('value','int');
    +    $res = dolibarr_set_const($db, "SOCIETE_DISABLE_PROSPECTSCUSTOMERS", $setdisableprospectcustomer,'yesno',0,'',$conf->entity);
    +    if (! $res > 0) $error++;
    +    if (! $error)
    +    {
    +        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        setEventMessages($langs->trans("Error"), null, 'errors');
    +    }
    +}
    +
     //Activate ProfId unique
     if ($action == 'setprofid')
     {
    @@ -759,7 +788,6 @@ if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST))
     {
     	print '<a href="'.$_SERVER['PHP_SELF'].'?action=setaddrefinlist&value=0">';
     	print img_picto($langs->trans("Activated"),'switch_on');
    -
     }
     else
     {
    @@ -769,6 +797,23 @@ else
     print '</a></td>';
     print '</tr>';
     
    +print '<tr class="oddeven">';
    +print '<td width="80%">'.$langs->trans("AddAdressInList").'</td>';
    +print '<td>&nbsp</td>';
    +print '<td align="center">';
    +if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST))
    +{
    +	print '<a href="'.$_SERVER['PHP_SELF'].'?action=setaddadressinlist&value=0">';
    +	print img_picto($langs->trans("Activated"),'switch_on');
    +}
    +else
    +{
    +	print '<a href="'.$_SERVER['PHP_SELF'].'?action=setaddadressinlist&value=1">';
    +	print img_picto($langs->trans("Disabled"),'switch_off');
    +}
    +print '</a></td>';
    +print '</tr>';
    +
     
     
     print '<tr class="oddeven">';
    @@ -779,7 +824,6 @@ if (!empty($conf->global->SOCIETE_ASK_FOR_SHIPPING_METHOD))
     {
     	print '<a href="'.$_SERVER['PHP_SELF'].'?action=setaskforshippingmet&value=0">';
     	print img_picto($langs->trans("Activated"),'switch_on');
    -
     }
     else
     {
    @@ -789,6 +833,24 @@ else
     print '</a></td>';
     print '</tr>';
     
    +// Disable Prospect/Customer thirdparty type
    +print '<tr class="oddeven">';
    +print '<td width="80%">'.$langs->trans("DisableProspectCustomerType").'</td>';
    +print '<td>&nbsp</td>';
    +print '<td align="center">';
    +if (!empty($conf->global->SOCIETE_DISABLE_PROSPECTSCUSTOMERS))
    +{
    +    print '<a href="'.$_SERVER['PHP_SELF'].'?action=setdisableprospectcustomer&value=0">';
    +    print img_picto($langs->trans("Activated"),'switch_on');
    +}
    +else
    +{
    +    print '<a href="'.$_SERVER['PHP_SELF'].'?action=setdisableprospectcustomer&value=1">';
    +    print img_picto($langs->trans("Disabled"),'switch_off');
    +}
    +print '</a></td>';
    +print '</tr>';
    +
     /*print '<tr class="oddeven">';
     print '<td width="80%">'.$langs->trans("OnSearchAndListGoOnCustomerOrSupplierCard").'</td>';
     print '<td>&nbsp</td>';
    @@ -835,7 +897,6 @@ print '</form>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/admin/societe_extrafields.php b/htdocs/societe/admin/societe_extrafields.php
    index 06dc57677f5..0835df13e22 100644
    --- a/htdocs/societe/admin/societe_extrafields.php
    +++ b/htdocs/societe/admin/societe_extrafields.php
    @@ -28,9 +28,7 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
    -$langs->load("companies");
    -$langs->load("admin");
    -$langs->load("members");
    +$langs->loadLangs(array("companies", "admin", "members"));
     
     $extrafields = new ExtraFields($db);
     $form = new Form($db);
    @@ -82,7 +80,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -95,7 +93,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    +    print '<br><div id="newattrib"></div>';
         print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -108,12 +106,12 @@ if ($action == 'create')
     /* ************************************************************************** */
     if ($action == 'edit' && ! empty($attrname))
     {
    -    print "<br>";
    +    print '<br><div id="editattrib"></div>';
         print load_fiche_titre($langs->trans("FieldEdition", $attrname));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/agenda.php b/htdocs/societe/agenda.php
    index ebd35a6575c..ffcd894e84a 100644
    --- a/htdocs/societe/agenda.php
    +++ b/htdocs/societe/agenda.php
    @@ -190,7 +190,6 @@ if ($socid > 0)
         }
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/canvas/actions_card_common.class.php b/htdocs/societe/canvas/actions_card_common.class.php
    index 37082f4140b..92d009db604 100644
    --- a/htdocs/societe/canvas/actions_card_common.class.php
    +++ b/htdocs/societe/canvas/actions_card_common.class.php
    @@ -27,7 +27,11 @@
      */
     abstract class ActionsCardCommon
     {
    -    var $db;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
         var $dirmodule;
         var $targetmodule;
         var $canvas;
    @@ -37,10 +41,17 @@ abstract class ActionsCardCommon
     	var $tpl = array();
     	//! Object container
     	var $object;
    -	//! Error string
    -	var $error;
    -	//! Error array
    -	var $errors=array();
    +
    +	/**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
    +
    +
    +	/**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
     
     
     	/**
    @@ -59,6 +70,7 @@ abstract class ActionsCardCommon
         	$this->object = $object;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Assign custom values for canvas (for example into this->tpl to be used by templates)
     	 *
    @@ -69,6 +81,7 @@ abstract class ActionsCardCommon
          */
         function assign_values(&$action, $id=0, $ref='')
         {
    +        // phpcs:enable
             global $conf, $langs, $user, $mysoc, $canvas;
             global $form, $formadmin, $formcompany;
     
    @@ -245,7 +258,6 @@ abstract class ActionsCardCommon
                         $this->tpl['localtax'].= '</td><tr>';
                     }
                 }
    -
             }
             else
             {
    @@ -358,6 +370,7 @@ abstract class ActionsCardCommon
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          *  Assign POST values into object
          *
    @@ -366,6 +379,7 @@ abstract class ActionsCardCommon
          */
         private function assign_post($action)
         {
    +        // phpcs:enable
             global $langs, $mysoc;
     
             $this->object->id					=	$_POST["socid"];
    @@ -380,7 +394,7 @@ abstract class ActionsCardCommon
             $this->object->town					=	$_POST["town"];
             $this->object->country_id			=	$_POST["country_id"]?$_POST["country_id"]:$mysoc->country_id;
             $this->object->state_id		        =	$_POST["state_id"];
    -        $this->object->phone					=	$_POST["tel"];
    +        $this->object->phone				=	$_POST["tel"];
             $this->object->fax					=	$_POST["fax"];
             $this->object->email				=	$_POST["email"];
             $this->object->url					=	$_POST["url"];
    @@ -411,5 +425,4 @@ abstract class ActionsCardCommon
                 $this->object->country_label=	$tmparray['label'];
             }
         }
    -
     }
    diff --git a/htdocs/societe/canvas/company/actions_card_company.class.php b/htdocs/societe/canvas/company/actions_card_company.class.php
    index 419a5ecb73e..09172f1ea5a 100644
    --- a/htdocs/societe/canvas/company/actions_card_company.class.php
    +++ b/htdocs/societe/canvas/company/actions_card_company.class.php
    @@ -67,6 +67,7 @@ class ActionsCardCompany extends ActionsCardCommon
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Assign custom values for canvas (for example into this->tpl to be used by templates)
     	 *
    @@ -77,6 +78,7 @@ class ActionsCardCompany extends ActionsCardCommon
     	 */
     	function assign_values(&$action, $id=0, $ref='')
     	{
    +        // phpcs:enable
     		global $conf, $langs, $user, $mysoc;
     		global $form, $formadmin, $formcompany;
     
    @@ -179,7 +181,6 @@ class ActionsCardCompany extends ActionsCardCommon
     				{
     					$this->tpl['tva_intra'] = $s;
     				}
    -
     			}
     			else
     			{
    @@ -218,6 +219,4 @@ class ActionsCardCompany extends ActionsCardCommon
     	{
     		return restrictedArea($user,$features,$objectid,$dbtablename,$feature2,$dbt_keyfield,$dbt_select);
     	}
    -
     }
    -
    diff --git a/htdocs/societe/canvas/individual/actions_card_individual.class.php b/htdocs/societe/canvas/individual/actions_card_individual.class.php
    index 78064004e37..5fd7ee01faf 100644
    --- a/htdocs/societe/canvas/individual/actions_card_individual.class.php
    +++ b/htdocs/societe/canvas/individual/actions_card_individual.class.php
    @@ -84,6 +84,7 @@ class ActionsCardIndividual extends ActionsCardCommon
     		return $return;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Assign custom values for canvas (for example into this->tpl to be used by templates)
     	 *
    @@ -94,6 +95,7 @@ class ActionsCardIndividual extends ActionsCardCommon
     	 */
     	function assign_values(&$action, $id=0, $ref='')
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     		global $form, $formcompany;
     
    @@ -134,6 +136,4 @@ class ActionsCardIndividual extends ActionsCardCommon
     	{
     		return restrictedArea($user,$features,$objectid,$dbtablename,$feature2,$dbt_keyfield,$dbt_select);
     	}
    -
     }
    -
    diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
    index d90c8f2a1f0..5935a1d01a1 100644
    --- a/htdocs/societe/card.php
    +++ b/htdocs/societe/card.php
    @@ -145,7 +145,7 @@ if (empty($reshook))
     				$object->client = $object->client | $soc_origin->client;
     				$object->fournisseur = $object->fournisseur | $soc_origin->fournisseur;
     				$listofproperties=array(
    -					'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
    +					'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'twitter', 'facebook', 'url', 'barcode',
     					'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
     					'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
     					'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
    @@ -304,13 +304,13 @@ if (empty($reshook))
         if (GETPOST('getcustomercode'))
         {
             // We defined value code_client
    -        $_POST["code_client"]="Acompleter";
    +        $_POST["customer_code"]="Acompleter";
         }
     
         if (GETPOST('getsuppliercode'))
         {
             // We defined value code_fournisseur
    -        $_POST["code_fournisseur"]="Acompleter";
    +        $_POST["supplier_code"]="Acompleter";
         }
     
         if($action=='set_localtax1')
    @@ -371,7 +371,6 @@ if (empty($reshook))
             {
                 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Supplier")), null, 'errors');
                 $error++;
    -
             }
     
             if (! $error)
    @@ -405,6 +404,8 @@ if (empty($reshook))
     	        $object->country_id				= GETPOST('country_id', 'int');
     	        $object->state_id				= GETPOST('state_id', 'int');
     	        $object->skype					= GETPOST('skype', 'alpha');
    +	        $object->twitter				= GETPOST('twitter', 'alpha');
    +	        $object->facebook				= GETPOST('facebook', 'alpha');
     	        $object->phone					= GETPOST('phone', 'alpha');
     	        $object->fax					= GETPOST('fax','alpha');
     	        $object->email					= trim(GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL));
    @@ -416,8 +417,8 @@ if (empty($reshook))
     	        $object->idprof5				= trim(GETPOST('idprof5', 'alpha'));
     	        $object->idprof6				= trim(GETPOST('idprof6', 'alpha'));
     	        $object->prefix_comm			= GETPOST('prefix_comm', 'alpha');
    -	        $object->code_client			= GETPOST('code_client', 'alpha');
    -	        $object->code_fournisseur		= GETPOST('code_fournisseur', 'alpha');
    +	        $object->code_client			= GETPOST('customer_code', 'alpha');
    +	        $object->code_fournisseur		= GETPOST('supplier_code', 'alpha');
     	        $object->capital				= GETPOST('capital', 'alpha');
     	        $object->barcode				= GETPOST('barcode', 'alpha');
     
    @@ -946,19 +947,21 @@ else
             $object->client				= GETPOST('client')?GETPOST('client'):$object->client;
     
             if(empty($duplicate_code_error)) {
    -	        $object->code_client		= GETPOST('code_client', 'alpha');
    +	        $object->code_client		= GETPOST('customer_code', 'alpha');
     	        $object->fournisseur		= GETPOST('fournisseur')?GETPOST('fournisseur'):$object->fournisseur;
             }
     		else {
     			setEventMessages($langs->trans('NewCustomerSupplierCodeProposed'),'', 'warnings');
     		}
     
    -        $object->code_fournisseur	= GETPOST('code_fournisseur', 'alpha');
    +        $object->code_fournisseur	= GETPOST('supplier_code', 'alpha');
             $object->address			= GETPOST('address', 'alpha');
             $object->zip				= GETPOST('zipcode', 'alpha');
             $object->town				= GETPOST('town', 'alpha');
             $object->state_id			= GETPOST('state_id', 'int');
             $object->skype				= GETPOST('skype', 'alpha');
    +        $object->twitter			= GETPOST('twitter', 'alpha');
    +        $object->facebook			= GETPOST('facebook', 'alpha');
             $object->phone				= GETPOST('phone', 'alpha');
             $object->fax				= GETPOST('fax', 'alpha');
             $object->email				= GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL);
    @@ -1059,6 +1062,39 @@ else
                             	$("#TypeName").html(document.formsoc.LastName.value);
                             	document.formsoc.private.value=1;
                             });
    +
    +						init_customer_categ();
    +			  			$("#customerprospect").change(function() {
    +								init_customer_categ();
    +						});
    +						function init_customer_categ() {
    +								console.log("is customer or prospect = "+jQuery("#customerprospect").val());
    +								if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || '.(empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER)?'1':'0').'))
    +								{
    +									jQuery(".visibleifcustomer").hide();
    +								}
    +								else
    +								{
    +									jQuery(".visibleifcustomer").show();
    +								}
    +						}
    +
    +						init_supplier_categ();
    +			       		$("#fournisseur").change(function() {
    +							init_supplier_categ();
    +						});
    +						function init_supplier_categ() {
    +								console.log("is supplier = "+jQuery("#fournisseur").val());
    +								if (jQuery("#fournisseur").val() == 0)
    +								{
    +									jQuery(".visibleifsupplier").hide();
    +								}
    +								else
    +								{
    +									jQuery(".visibleifsupplier").show();
    +								}
    +						}
    +
                             $("#selectcountry_id").change(function() {
                             	document.formsoc.action.value="create";
                             	document.formsoc.submit();
    @@ -1154,7 +1190,7 @@ else
             print '<table class="nobordernopadding"><tr><td>';
     		$tmpcode=$object->code_client;
             if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0);
    -        print '<input type="text" name="code_client" id="customer_code" class="maxwidthonsmartphone" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
    +        print '<input type="text" name="customer_code" id="customer_code" class="maxwidthonsmartphone" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
             print '</td><td>';
             $s=$modCodeClient->getToolTip($langs,$object,0);
             print $form->textwithpicto('',$s,1);
    @@ -1182,7 +1218,7 @@ else
     	            print '<table class="nobordernopadding"><tr><td>';
     	            $tmpcode=$object->code_fournisseur;
     	            if (empty($tmpcode) && ! empty($modCodeFournisseur->code_auto)) $tmpcode=$modCodeFournisseur->getNextValue($object,1);
    -	            print '<input type="text" name="code_fournisseur" id="supplier_code" class="maxwidthonsmartphone" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
    +	            print '<input type="text" name="supplier_code" id="supplier_code" class="maxwidthonsmartphone" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
     	            print '</td><td>';
     	            $s=$modCodeFournisseur->getToolTip($langs,$object,1);
     	            print $form->textwithpicto('',$s,1);
    @@ -1240,17 +1276,32 @@ else
                 print '</td></tr>';
             }
     
    -        // Email web
    +        // Email / Web
             print '<tr><td>'.fieldLabel('EMail','email',$conf->global->SOCIETE_EMAIL_MANDATORY).'</td>';
     	    print '<td colspan="3"><input type="text" name="email" id="email" value="'.$object->email.'"></td></tr>';
             print '<tr><td>'.fieldLabel('Web','url').'</td>';
     	    print '<td colspan="3"><input type="text" name="url" id="url" value="'.$object->url.'"></td></tr>';
     
    -        // Skype
    -        if (! empty($conf->skype->enabled))
    +        if (! empty($conf->socialnetworks->enabled))
             {
    -            print '<tr><td>'.fieldLabel('Skype','skype').'</td>';
    -	        print '<td colspan="3"><input type="text" name="skype" id="skype" value="'.$object->skype.'"></td></tr>';
    +        	// Skype
    +        	if (! empty($conf->global->SOCIALNETWORKS_SKYPE))
    +        	{
    +        		print '<tr><td>'.fieldLabel('Skype','skype').'</td>';
    +        		print '<td colspan="3"><input type="text" name="skype" class="minwidth100" maxlength="80" id="skype" value="'.dol_escape_htmltag(GETPOSTISSET("skype")?GETPOST("skype",'alpha'):$object->skype).'"></td></tr>';
    +        	}
    +        	// Twitter
    +        	if (! empty($conf->global->SOCIALNETWORKS_TWITTER))
    +        	{
    +        		print '<tr><td>'.fieldLabel('Twitter','twitter').'</td>';
    +        		print '<td colspan="3"><input type="text" name="twitter" class="minwidth100" maxlength="80" id="twitter" value="'.dol_escape_htmltag(GETPOSTISSET("twitter")?GETPOST("twitter",'alpha'):$object->twitter).'"></td></tr>';
    +        	}
    +        	// Facebook
    +        	if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK))
    +        	{
    +	        	print '<tr><td>'.fieldLabel('Facebook','facebook').'</td>';
    +	        	print '<td colspan="3"><input type="text" name="facebook" class="minwidth100" maxlength="80" id="facebook" value="'.dol_escape_htmltag(GETPOSTISSET("facebook")?GETPOST("facebook",'alpha'):$object->facebook).'"></td></tr>';
    +        	}
             }
     
             // Phone / Fax
    @@ -1325,7 +1376,6 @@ else
                 print '</td><td>'.$langs->transcountry("LocalTax2IsUsed",$mysoc->country_code).'</td><td>';
                 print $form->selectyesno('localtax2assuj_value',(isset($conf->global->THIRDPARTY_DEFAULT_USELOCALTAX2)?$conf->global->THIRDPARTY_DEFAULT_USELOCALTAX2:0),1);
                 print '</td></tr>';
    -
             }
             elseif($mysoc->localtax1_assuj=="1")
             {
    @@ -1377,11 +1427,12 @@ else
                 print '</tr>';
             }
     
    -		// Assign a Name
    +		// Assign a sale representative
     		print '<tr>';
     		print '<td>'.fieldLabel('AllocateCommercial','commercial_id').'</td>';
     		print '<td colspan="3" class="maxwidthonsmartphone">';
     		$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, '', 0, '', '', 0, 1);
    +		// Note: If user has no right to "see all thirdparties", we for selection of sale representative to him, so after creation he can see the record.
     		print $form->multiselectarray('commercial', $userlist, (count(GETPOST('commercial', 'array')) > 0?GETPOST('commercial', 'array'):(empty($user->rights->societe->client->voir)?array($user->id):array())), null, null, null, null, "90%");
     		print '</td></tr>';
     
    @@ -1401,22 +1452,20 @@ else
     			$langs->load('categories');
     
     			// Customer
    -			if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
    -				print '<tr><td class="toptd">' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td><td colspan="3">';
    -				$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, 'parent', null, null, 1);
    -				print $form->multiselectarray('custcats', $cate_arbo, GETPOST('custcats', 'array'), null, null, null,
    -					null, "90%");
    -				print "</td></tr>";
    -			}
    +			//if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
    +			print '<tr class="visibleifcustomer"><td class="toptd">' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td><td colspan="3">';
    +			$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, 'parent', null, null, 1);
    +			print $form->multiselectarray('custcats', $cate_arbo, GETPOST('custcats', 'array'), null, null, null, null, "90%");
    +			print "</td></tr>";
    +			//}
     
     			// Supplier
    -			if ($object->fournisseur) {
    -				print '<tr><td class="toptd">' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td><td colspan="3">';
    -				$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, 'parent', null, null, 1);
    -				print $form->multiselectarray('suppcats', $cate_arbo, GETPOST('suppcats', 'array'), null, null, null,
    -					null, "90%");
    -				print "</td></tr>";
    -			}
    +			//if ($object->fournisseur) {
    +			print '<tr class="visibleifsupplier"><td class="toptd">' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td><td colspan="3">';
    +			$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, 'parent', null, null, 1);
    +			print $form->multiselectarray('suppcats', $cate_arbo, GETPOST('suppcats', 'array'), null, null, null, null, "90%");
    +			print "</td></tr>";
    +			//}
     		}
     
     		// Multicurrency
    @@ -1468,11 +1517,6 @@ else
         }
         elseif ($action == 'edit')
         {
    -        /*
    -         * Edition
    -         */
    -
    -
             //print load_fiche_titre($langs->trans("EditCompany"));
     
             if ($socid)
    @@ -1526,15 +1570,17 @@ else
                     $object->name					= GETPOST('name', 'alpha');
                     $object->prefix_comm			= GETPOST('prefix_comm', 'alpha');
                     $object->client					= GETPOST('client', 'int');
    -                $object->code_client			= GETPOST('code_client', 'alpha');
    +                $object->code_client			= GETPOST('customer_code', 'alpha');
                     $object->fournisseur			= GETPOST('fournisseur', 'int');
    -                $object->code_fournisseur		= GETPOST('code_fournisseur', 'alpha');
    +                $object->code_fournisseur		= GETPOST('supplier_code', 'alpha');
                     $object->address				= GETPOST('address', 'alpha');
                     $object->zip					= GETPOST('zipcode', 'alpha');
                     $object->town					= GETPOST('town', 'alpha');
                     $object->country_id				= GETPOST('country_id')?GETPOST('country_id', 'int'):$mysoc->country_id;
                     $object->state_id				= GETPOST('state_id', 'int');
                     $object->skype					= GETPOST('skype', 'alpha');
    +                $object->twitter				= GETPOST('twitter', 'alpha');
    +                $object->facebook				= GETPOST('facebook', 'alpha');
                     $object->phone					= GETPOST('phone', 'alpha');
                     $object->fax					= GETPOST('fax', 'alpha');
                     $object->email					= GETPOST('email', 'custom', 0, FILTER_SANITIZE_EMAIL);
    @@ -1590,8 +1636,10 @@ else
                 	$sub2=0;
                 }else{$sub2=1;}
     
    -            print "\n".'<script type="text/javascript">';
    -            print '$(document).ready(function () {
    +            if ($conf->use_javascript_ajax)
    +            {
    +            	print "\n".'<script type="text/javascript">';
    +            	print '$(document).ready(function () {
         			var val='.$sub.';
         			var val2='.$sub2.';
         			if("#localtax1assuj_value".value==undefined){
    @@ -1625,19 +1673,44 @@ else
         				}
         			});
     
    -               });';
    -            print '</script>'."\n";
    +				init_customer_categ();
    +	  			$("#customerprospect").change(function() {
    +					init_customer_categ();
    +				});
    +       			function init_customer_categ() {
    +					console.log("is customer or prospect = "+jQuery("#customerprospect").val());
    +					if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || '.(empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER)?'1':'0').'))
    +					{
    +						jQuery(".visibleifcustomer").hide();
    +					}
    +					else
    +					{
    +						jQuery(".visibleifcustomer").show();
    +					}
    +				}
     
    +				init_supplier_categ();
    +	  			$("#fournisseur").change(function() {
    +					init_supplier_categ();
    +				});
    +       			function init_supplier_categ() {
    +					console.log("is supplier = "+jQuery("#fournisseur").val());
    +					if (jQuery("#fournisseur").val() == 0)
    +					{
    +						jQuery(".visibleifsupplier").hide();
    +					}
    +					else
    +					{
    +						jQuery(".visibleifsupplier").show();
    +					}
    +				};
     
    -            if ($conf->use_javascript_ajax)
    -            {
    -                print "\n".'<script type="text/javascript" language="javascript">';
    -                print '$(document).ready(function () {
    -                			$("#selectcountry_id").change(function() {
    -                				document.formsoc.action.value="edit";
    -                				document.formsoc.submit();
    -                			});
    -                       })';
    +       			$("#selectcountry_id").change(function() {
    +       				document.formsoc.action.value="edit";
    +      				document.formsoc.submit();
    +        			});
    +
    +                })';
                     print '</script>'."\n";
                 }
     
    @@ -1703,16 +1776,16 @@ else
                     $tmpcode=$object->code_client;
                     if (empty($tmpcode) && ! empty($object->oldcopy->code_client)) $tmpcode=$object->oldcopy->code_client; // When there is an error to update a thirdparty, the number for supplier and customer code is kept to old value.
                     if (empty($tmpcode) && ! empty($modCodeClient->code_auto)) $tmpcode=$modCodeClient->getNextValue($object,0);
    -                print '<input type="text" name="code_client" id="customer_code" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
    +                print '<input type="text" name="customer_code" id="customer_code" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
                 }
                 else if ($object->codeclient_modifiable())
                 {
    -            	print '<input type="text" name="code_client" id="customer_code" size="16" value="'.dol_escape_htmltag($object->code_client).'" maxlength="15">';
    +            	print '<input type="text" name="customer_code" id="customer_code" size="16" value="'.dol_escape_htmltag($object->code_client).'" maxlength="15">';
                 }
                 else
                 {
                     print $object->code_client;
    -                print '<input type="hidden" name="code_client" value="'.dol_escape_htmltag($object->code_client).'">';
    +                print '<input type="hidden" name="customer_code" value="'.dol_escape_htmltag($object->code_client).'">';
                 }
                 print '</td><td>';
                 $s=$modCodeClient->getToolTip($langs,$object,0);
    @@ -1743,16 +1816,16 @@ else
     	                    $tmpcode=$object->code_fournisseur;
     	                    if (empty($tmpcode) && ! empty($object->oldcopy->code_fournisseur)) $tmpcode=$object->oldcopy->code_fournisseur; // When there is an error to update a thirdparty, the number for supplier and customer code is kept to old value.
     	                    if (empty($tmpcode) && ! empty($modCodeFournisseur->code_auto)) $tmpcode=$modCodeFournisseur->getNextValue($object,1);
    -	                    print '<input type="text" name="code_fournisseur" id="supplier_code" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
    +	                    print '<input type="text" name="supplier_code" id="supplier_code" size="16" value="'.dol_escape_htmltag($tmpcode).'" maxlength="15">';
     	                }
     	                else if ($object->codefournisseur_modifiable())
     	                {
    -	                    print '<input type="text" name="code_fournisseur" id="supplier_code" size="16" value="'.$object->code_fournisseur.'" maxlength="15">';
    +	                    print '<input type="text" name="supplier_code" id="supplier_code" size="16" value="'.$object->code_fournisseur.'" maxlength="15">';
     	                }
     	                else
     	              {
     	                    print $object->code_fournisseur;
    -	                    print '<input type="hidden" name="code_fournisseur" value="'.$object->code_fournisseur.'">';
    +	                    print '<input type="hidden" name="supplier_code" value="'.$object->code_fournisseur.'">';
     	                }
     	                print '</td><td>';
     	                $s=$modCodeFournisseur->getToolTip($langs,$object,1);
    @@ -1816,12 +1889,27 @@ else
                 print '<tr><td>'.fieldLabel('Web','url').'</td>';
     	        print '<td colspan="3"><input type="text" name="url" id="url" size="32" value="'.$object->url.'"></td></tr>';
     
    -            // Skype
    -            if (! empty($conf->skype->enabled))
    -            {
    -                print '<tr><td>'.fieldLabel('Skype','skype').'</td>';
    -	            print '<td colspan="3"><input type="text" name="skype" id="skype" size="32" value="'.$object->skype.'"></td></tr>';
    -            }
    +	        if (! empty($conf->socialnetworks->enabled))
    +	        {
    +	        	// Skype
    +	        	if (! empty($conf->global->SOCIALNETWORKS_SKYPE))
    +	        	{
    +	        		print '<tr><td>'.fieldLabel('Skype','skype').'</td>';
    +	        		print '<td colspan="3"><input type="text" name="skype" id="skype" value="'.$object->skype.'"></td></tr>';
    +	        	}
    +	        	// Twitter
    +	        	if (! empty($conf->global->SOCIALNETWORKS_TWITTER))
    +	        	{
    +	        		print '<tr><td>'.fieldLabel('Twitter','twitter').'</td>';
    +	        		print '<td colspan="3"><input type="text" name="twitter" id="twitter" value="'.$object->twitter.'"></td></tr>';
    +	        	}
    +	        	// Facebook
    +	        	if (! empty($conf->global->SOCIALNETWORKS_FACEBOOK))
    +	        	{
    +	        		print '<tr><td>'.fieldLabel('Facebook','facebook').'</td>';
    +	        		print '<td colspan="3"><input type="text" name="facebook" id="facebook" value="'.$object->facebook.'"></td></tr>';
    +	        	}
    +	        }
     
                 // Phone / Fax
                 print '<tr><td>'.fieldLabel('Phone','phone').'</td>';
    @@ -1883,7 +1971,6 @@ else
                         print '</span>';
                     }
                     print '</td></tr>';
    -
                 }
                 elseif($mysoc->localtax1_assuj=="1" && $mysoc->localtax2_assuj!="1")
                 {
    @@ -1896,7 +1983,6 @@ else
                         print '</span>';
                     }
                     print '</td></tr>';
    -
                 }
                 elseif($mysoc->localtax2_assuj=="1" && $mysoc->localtax1_assuj!="1")
                 {
    @@ -1985,34 +2071,30 @@ else
     			if (! empty($conf->categorie->enabled)  && ! empty($user->rights->categorie->lire))
     			{
     				// Customer
    -				if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
    -					print '<tr><td>' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td>';
    -					print '<td colspan="3">';
    -					$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1);
    -					$c = new Categorie($db);
    -					$cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER);
    -					$arrayselected=array();
    -					foreach ($cats as $cat) {
    -						$arrayselected[] = $cat->id;
    -					}
    -					print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    -					print "</td></tr>";
    +				print '<tr class="visibleifcustomer"><td>' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td>';
    +				print '<td colspan="3">';
    +				$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1);
    +				$c = new Categorie($db);
    +				$cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER);
    +				$arrayselected=array();
    +				foreach ($cats as $cat) {
    +					$arrayselected[] = $cat->id;
     				}
    +				print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    +				print "</td></tr>";
     
     				// Supplier
    -				if ($object->fournisseur) {
    -					print '<tr><td>' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td>';
    -					print '<td colspan="3">';
    -					$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1);
    -					$c = new Categorie($db);
    -					$cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER);
    -					$arrayselected=array();
    -					foreach ($cats as $cat) {
    -						$arrayselected[] = $cat->id;
    -					}
    -					print $form->multiselectarray('suppcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    -					print "</td></tr>";
    +				print '<tr class="visibleifsupplier"><td>' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td>';
    +				print '<td colspan="3">';
    +				$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1);
    +				$c = new Categorie($db);
    +				$cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER);
    +				$arrayselected=array();
    +				foreach ($cats as $cat) {
    +					$arrayselected[] = $cat->id;
     				}
    +				print $form->multiselectarray('suppcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    +				print "</td></tr>";
     			}
     
     			// Multicurrency
    @@ -2294,7 +2376,6 @@ else
     			            print '<td>'.$object->localtax1_value.'</td>';
     			        }
     			        print '</tr></form>';
    -
     			    }
     			}
     			elseif($mysoc->localtax2_assuj=="1" && $mysoc->localtax1_assuj!="1")
    @@ -2317,7 +2398,6 @@ else
     			            print '<td>'.$object->localtax2_value.'</td>';
     			        }
     			        print '</tr></form>';
    -
     			    }
     			}
             }
    @@ -2643,11 +2723,9 @@ else
     		$trackid = 'thi'.$object->id;
     
     		include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
    -
         }
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/checkvat/checkVatPopup.php b/htdocs/societe/checkvat/checkVatPopup.php
    index f1e56d4a359..1222689358f 100644
    --- a/htdocs/societe/checkvat/checkVatPopup.php
    +++ b/htdocs/societe/checkvat/checkVatPopup.php
    @@ -21,7 +21,7 @@
      *		\brief      Popup screen to validate VAT
      */
     
    -require ("../../main.inc.php");
    +require "../../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once NUSOAP_PATH.'/nusoap.php';
     
    @@ -174,6 +174,6 @@ if ($messagetoshow)
     	print nl2br($messagetoshow);
     }
     
    -
    +// End of page
     llxFooter();
    -$db->close();
    +$db->close();;
    diff --git a/htdocs/societe/class/address.class.php b/htdocs/societe/class/address.class.php
    index 43e46008910..4f9915a844c 100644
    --- a/htdocs/societe/class/address.class.php
    +++ b/htdocs/societe/class/address.class.php
    @@ -33,12 +33,26 @@ class Address
     {
     	protected $db;
     
    +	/**
    +	 * @var int ID
    +	 */
     	public $id;
    +
     	public $type;
    -	public $label;
    +
    +	/**
    +     * @var string Address label
    +     */
    +    public $label;
    +
     	public $socid;
     	public $name;
    +
    +	/**
    +	 * @var string Address
    +	 */
     	public $address;
    +
     	public $zip;
     	public $town;
     	public $country_id;
    @@ -124,7 +138,6 @@ class Address
     				$this->db->rollback();
     				return -2;
     			}
    -
     		}
     		else
     		{
    @@ -228,9 +241,9 @@ class Address
     				return $result;
     			}
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge depuis la base toutes les adresses d'une societe
     	 *
    @@ -240,6 +253,7 @@ class Address
     	 */
     	function fetch_lines($socid, $user=null)
     	{
    +        // phpcs:enable
     		global $langs, $conf;
     
     		$sql = 'SELECT rowid, nom as name, client, fournisseur';
    @@ -324,6 +338,7 @@ class Address
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge depuis la base l'objet adresse
     	 *
    @@ -333,6 +348,7 @@ class Address
     	 */
     	function fetch_address($id, $user=null)
     	{
    +        // phpcs:enable
     		global $langs;
     		global $conf;
     
    @@ -479,14 +495,12 @@ class Address
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
     			dol_print_error($this->db);
     		}
     	}
    -
     }
     
     
    @@ -496,12 +510,27 @@ class Address
     class AddressLine
     {
     	protected $db;
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $id;
    +
     	public $date_creation;
     	public $date_modification;
    -	public $label;
    +
    +	/**
    +     * @var string stock movements label
    +     */
    +    public $label;
    +
     	public $name;
    +
    +	/**
    +	 * @var string Address
    +	 */
     	public $address;
    +
     	public $zip;
     	public $town;
     	public $country_id;
    diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php
    index b99257da275..9e9a6a58a80 100644
    --- a/htdocs/societe/class/api_contacts.class.php
    +++ b/htdocs/societe/class/api_contacts.class.php
    @@ -34,7 +34,7 @@ class Contacts extends DolibarrApi
     	 * @var array   $FIELDS     Mandatory fields, checked when create and update object
     	 */
     	static $FIELDS = array(
    -		'lastname'
    +		'lastname',
     	);
     
     	/**
    @@ -101,8 +101,9 @@ class Contacts extends DolibarrApi
     	 * @return array                        Array of contact objects
          *
     	 * @throws RestException
    -	 */
    -	function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +     */
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
     		global $db, $conf;
     
     		$obj_ret = array();
    @@ -195,7 +196,8 @@ class Contacts extends DolibarrApi
     	 * @param   array   $request_data   Request datas
     	 * @return  int     ID of contact
     	 */
    -	function post($request_data = null) {
    +    function post($request_data = null)
    +    {
     		if (!DolibarrApiAccess::$user->rights->societe->contact->creer)
     		{
     			throw new RestException(401, 'No permission to create/update contacts');
    @@ -220,7 +222,8 @@ class Contacts extends DolibarrApi
     	 * @param array $request_data   Datas
     	 * @return int
     	 */
    -	function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
     		if (!DolibarrApiAccess::$user->rights->societe->contact->creer)
     		{
     			throw new RestException(401, 'No permission to create/update contacts');
    @@ -255,7 +258,8 @@ class Contacts extends DolibarrApi
     	 * @param   int     $id Contact ID
     	 * @return  integer
     	 */
    -	function delete($id) {
    +    function delete($id)
    +    {
     		if (!DolibarrApiAccess::$user->rights->societe->contact->supprimer)
     		{
     			throw new RestException(401, 'No permission to delete contacts');
    @@ -283,7 +287,8 @@ class Contacts extends DolibarrApi
     	 *
     	 * @url	POST {id}/createUser
     	 */
    -	function createUser($id, $request_data = null) {
    +    function createUser($id, $request_data = null)
    +    {
     	    //if (!DolibarrApiAccess::$user->rights->user->user->creer) {
     	    //throw new RestException(401);
     	    //}
    @@ -365,7 +370,8 @@ class Contacts extends DolibarrApi
          * @param   object  $object    Object to clean
          * @return    array    Array of cleaned object properties
          */
    -    function _cleanObjectDatas($object) {
    +    function _cleanObjectDatas($object)
    +    {
     
         	$object = parent::_cleanObjectDatas($object);
     
    @@ -389,7 +395,8 @@ class Contacts extends DolibarrApi
     	 * @return  array
     	 * @throws RestException
     	 */
    -	function _validate($data) {
    +    function _validate($data)
    +    {
     		$contact = array();
     		foreach (Contacts::$FIELDS as $field)
     		{
    diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
    index 2b355b56eb7..42d1d616852 100644
    --- a/htdocs/societe/class/api_thirdparties.class.php
    +++ b/htdocs/societe/class/api_thirdparties.class.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2015   Jean-François Ferry     <jfefe@aternatik.fr>
    + * Copyright (C) 2018   Pierre Chéné            <pierre.chene44@gmail.com>
      *
      * 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
    @@ -32,7 +33,7 @@ class Thirdparties extends DolibarrApi
     	 * @var array   $FIELDS     Mandatory fields, checked when create and update object
     	 */
     	static $FIELDS = array(
    -	'name'
    +		'name'
     	);
     
     	/**
    @@ -49,7 +50,9 @@ class Thirdparties extends DolibarrApi
     		$this->db = $db;
     
     		require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
    +		require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
     		require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +		require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
     
     		$this->company = new Societe($this->db);
     
    @@ -114,7 +117,8 @@ class Thirdparties extends DolibarrApi
     	 * @param   string  $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.nom:like:'TheCompany%') and (t.date_creation:<:'20160101')"
     	 * @return  array               Array of thirdparty objects
     	 */
    -	function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode=0, $sqlfilters = '') {
    +	function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode=0, $sqlfilters = '')
    +    {
     		global $db, $conf;
     
     		$obj_ret = array();
    @@ -129,7 +133,6 @@ class Thirdparties extends DolibarrApi
     		$sql = "SELECT t.rowid";
     		if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects)
     		$sql.= " FROM ".MAIN_DB_PREFIX."societe as t";
    -		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX . "societe_extrafields as te ON te.fk_object = t.rowid";
     
     		if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
     		$sql.= ", ".MAIN_DB_PREFIX."c_stcomm as st";
    @@ -214,7 +217,7 @@ class Thirdparties extends DolibarrApi
     		if ($this->company->create(DolibarrApiAccess::$user) < 0)
     			throw new RestException(500, 'Error creating thirdparty', array_merge(array($this->company->error), $this->company->errors));
     
    -			return $this->company->id;
    +		return $this->company->id;
     	}
     
     	/**
    @@ -247,7 +250,7 @@ class Thirdparties extends DolibarrApi
     		if($this->company->update($id, DolibarrApiAccess::$user,1,'','','update'))
     			return $this->get($id);
     
    -			return false;
    +		return false;
     	}
     
     	/**
    @@ -313,12 +316,12 @@ class Thirdparties extends DolibarrApi
     		$object->client = $object->client | $soc_origin->client;
     		$object->fournisseur = $object->fournisseur | $soc_origin->fournisseur;
     		$listofproperties=array(
    -		'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
    -		'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
    -		'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
    -		'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
    -		'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
    -		'model_pdf', 'fk_projet'
    +			'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
    +			'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
    +			'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
    +			'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
    +			'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
    +			'model_pdf', 'fk_projet'
     		);
     		foreach ($listofproperties as $property)
     		{
    @@ -327,7 +330,7 @@ class Thirdparties extends DolibarrApi
     
     		// Concat some data
     		$listofproperties=array(
    -		'note_public', 'note_private'
    +			'note_public', 'note_private'
     		);
     		foreach ($listofproperties as $property)
     		{
    @@ -373,27 +376,27 @@ class Thirdparties extends DolibarrApi
     		if (! $error)
     		{
     			$objects = array(
    -			'Adherent' => '/adherents/class/adherent.class.php',
    -			'Societe' => '/societe/class/societe.class.php',
    -			'Categorie' => '/categories/class/categorie.class.php',
    -			'ActionComm' => '/comm/action/class/actioncomm.class.php',
    -			'Propal' => '/comm/propal/class/propal.class.php',
    -			'Commande' => '/commande/class/commande.class.php',
    -			'Facture' => '/compta/facture/class/facture.class.php',
    -			'FactureRec' => '/compta/facture/class/facture-rec.class.php',
    -			'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
    -			'Contact' => '/contact/class/contact.class.php',
    -			'Contrat' => '/contrat/class/contrat.class.php',
    -			'Expedition' => '/expedition/class/expedition.class.php',
    -			'Fichinter' => '/fichinter/class/fichinter.class.php',
    -			'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
    -			'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
    -			'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
    -			'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
    -			'Livraison' => '/livraison/class/livraison.class.php',
    -			'Product' => '/product/class/product.class.php',
    -			'Project' => '/projet/class/project.class.php',
    -			'User' => '/user/class/user.class.php',
    +				'Adherent' => '/adherents/class/adherent.class.php',
    +				'Societe' => '/societe/class/societe.class.php',
    +				'Categorie' => '/categories/class/categorie.class.php',
    +				'ActionComm' => '/comm/action/class/actioncomm.class.php',
    +				'Propal' => '/comm/propal/class/propal.class.php',
    +				'Commande' => '/commande/class/commande.class.php',
    +				'Facture' => '/compta/facture/class/facture.class.php',
    +				'FactureRec' => '/compta/facture/class/facture-rec.class.php',
    +				'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
    +				'Contact' => '/contact/class/contact.class.php',
    +				'Contrat' => '/contrat/class/contrat.class.php',
    +				'Expedition' => '/expedition/class/expedition.class.php',
    +				'Fichinter' => '/fichinter/class/fichinter.class.php',
    +				'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
    +				'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
    +				'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
    +				'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
    +				'Livraison' => '/livraison/class/livraison.class.php',
    +				'Product' => '/product/class/product.class.php',
    +				'Project' => '/projet/class/project.class.php',
    +				'User' => '/user/class/user.class.php',
     			);
     
     			//First, all core objects must update their tables
    @@ -413,8 +416,8 @@ class Thirdparties extends DolibarrApi
     		if (!$errors)
     		{
     			$reshook = $hookmanager->executeHooks('replaceThirdparty', array(
    -			'soc_origin' => $soc_origin->id,
    -			'soc_dest' => $object->id
    +				'soc_origin' => $soc_origin->id,
    +				'soc_dest' => $object->id
     			), $soc_dest, $action);
     
     			if ($reshook < 0)
    @@ -852,8 +855,6 @@ class Thirdparties extends DolibarrApi
     		return $result;
     	}
     
    -
    -
     	/**
     	 * Get fixed amount discount of a thirdparty (all sources: deposit, credit note, commercial offers...)
     	 *
    @@ -929,8 +930,8 @@ class Thirdparties extends DolibarrApi
     	 * @throws 404
     	 * @throws 405
     	 */
    -	function getInvoicesQualifiedForReplacement($id) {
    -
    +	function getInvoicesQualifiedForReplacement($id)
    +    {
     		if(! DolibarrApiAccess::$user->rights->facture->lire) {
     			throw new RestException(401);
     		}
    @@ -971,8 +972,8 @@ class Thirdparties extends DolibarrApi
     	 * @throws 404
     	 * @throws 405
     	 */
    -	function getInvoicesQualifiedForCreditNote($id) {
    -
    +	function getInvoicesQualifiedForCreditNote($id)
    +    {
     		if(! DolibarrApiAccess::$user->rights->facture->lire) {
     			throw new RestException(401);
     		}
    @@ -998,6 +999,632 @@ class Thirdparties extends DolibarrApi
     		return $result;
     	}
     
    +	/**
    +	 * Get CompanyBankAccount objects for thirdparty
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 *
    +	 * @return array
    +	 *
    +	 * @url GET {id}/bankaccounts
    +	 */
    +	function getCompanyBankAccount($id)
    +    {
    +		global $db, $conf;
    +
    +		if(! DolibarrApiAccess::$user->rights->facture->lire) {
    +			throw new RestException(401);
    +		}
    +		if(empty($id)) {
    +			throw new RestException(400, 'Thirdparty ID is mandatory');
    +		}
    +
    +		if( ! DolibarrApi::_checkAccessToResource('societe',$id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +		}
    +
    +		/**
    +		 * We select all the records that match the socid
    +		 */
    +
    +		$sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio,";
    +		$sql.= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."societe_rib";
    +		if ($id) $sql.= " WHERE fk_soc  = ".$id." ";
    +
    +
    +		$result = $db->query($sql);
    +
    +		if($result->num_rows == 0 ){
    +			throw new RestException(404, 'Account not found');
    +		}
    +
    +		$i=0;
    +
    +		$accounts =[];
    +
    +		if ($result)
    +		{
    +			$num = $db->num_rows($result);
    +			while ($i < $num)
    +			{
    +				$obj = $db->fetch_object($result);
    +				$account = new CompanyBankAccount($db);
    +				if($account->fetch($obj->rowid)) {
    +					$accounts[] = $account;
    +				}
    +				$i++;
    +			}
    +		}
    +		else{
    +			throw new RestException(404, 'Account not found');
    +		}
    +
    +
    +		$fields = ['socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum'];
    +
    +		$returnAccounts = [];
    +
    +		foreach($accounts as $account){
    +			$object= [];
    +			foreach($account as $key => $value)
    +				if(in_array($key, $fields)){
    +					$object[$key] = $value;
    +				}
    +			$returnAccounts[] = $object;
    +		}
    +
    +		return $returnAccounts;
    +	}
    +
    +	/**
    +	 * Create CompanyBankAccount object for thirdparty
    +	 * @param int  $id ID of thirdparty
    +	 * @param array $request_data Request data
    +	 *
    +	 * @return object  ID of thirdparty
    +	 *
    +	 * @url POST {id}/bankaccounts
    +	 */
    +	function createCompanyBankAccount($id, $request_data = null)
    +	{
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		$account = new CompanyBankAccount($this->db);
    +
    +		$account->socid = $id;
    +
    +		foreach($request_data as $field => $value) {
    +			$account->$field = $value;
    +		}
    +
    +		if ($account->create(DolibarrApiAccess::$user) < 0)
    +			throw new RestException(500, 'Error creating Company Bank account');
    +
    +
    +		if ($account->update(DolibarrApiAccess::$user) < 0)
    +			throw new RestException(500, 'Error updating values');
    +
    +		return $account;
    +	}
    +
    +	/**
    +	 * Update CompanyBankAccount object for thirdparty
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 * @param int  $bankaccount_id ID of CompanyBankAccount
    +	 * @param array $request_data Request data
    +	 *
    +	 * @return object  ID of thirdparty
    +	 *
    +	 * @url PUT {id}/bankaccounts/{bankaccount_id}
    +	 */
    +	function updateCompanyBankAccount($id, $bankaccount_id, $request_data = null)
    +	{
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		$account = new CompanyBankAccount($this->db);
    +
    +		$account->fetch($bankaccount_id, $id, -1, '');
    +
    +		if($account->socid != $id){
    +			throw new RestException(401);
    +		}
    +
    +
    +		foreach($request_data as $field => $value) {
    +			$account->$field = $value;
    +		}
    +
    +		if ($account->update(DolibarrApiAccess::$user) < 0)
    +			throw new RestException(500, 'Error updating values');
    +
    +		return $account;
    +	}
    +
    +	/**
    +	 * Delete a bank account attached to a thirdparty
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 * @param int $bankaccount_id ID of CompanyBankAccount
    +	 *
    +	 * @return int -1 if error 1 if correct deletion
    +	 *
    +	 * @url DELETE {id}/bankaccounts/{bankaccount_id}
    +	 */
    +	function deleteCompanyBankAccount($id, $bankaccount_id)
    +    {
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		$account = new CompanyBankAccount($this->db);
    +
    +		$account->fetch($bankaccount_id);
    +
    +		if(!$account->socid == $id)
    +			throw new RestException(401);
    +
    +		return $account->delete(DolibarrApiAccess::$user);
    +	}
    +
    +	/**
    +	 * Generate a Document from a bank account record (like SEPA mandate)
    +	 *
    +	 * @param int 		$id 			Thirdparty id
    +	 * @param int 		$companybankid 	Companybank id
    +	 * @param string 	$model 			Model of document to generate
    +	 * @return void
    +	 *
    +	 * @url GET {id}/generateBankAccountDocument/{companybankid}/{model}
    +	 */
    +	public function generateBankAccountDocument($id, $companybankid = null, $model = 'sepamandate')
    +	{
    +		global $conf;
    +
    +		$this->langs->loadLangs(array("main","dict","commercial","products","companies","banks","bills","withdrawals"));
    +
    +		$this->company->fetch($id);
    +
    +		$action = 'builddoc';
    +		if(! DolibarrApiAccess::$user->rights->societe->creer)
    +			throw new RestException(401);
    +
    +		$this->company->setDocModel(DolibarrApiAccess::$user, $model);
    +
    +		$this->company->fk_bank = $this->company->fk_account;
    +
    +		$outputlangs = $this->langs;
    +		$newlang='';
    +
    +		if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang=GETPOST('lang_id','aZ09');
    +		if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->company->thirdparty->default_lang)) $newlang=$this->company->thirdparty->default_lang;  // for proposal, order, invoice, ...
    +		if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->company->default_lang)) $newlang=$this->company->default_lang;                  // for thirdparty
    +		if (! empty($newlang)) {
    +			$outputlangs = new Translate("",$conf);
    +			$outputlangs->setDefaultLang($newlang);
    +		}
    +
    +		// To be sure vars is defined
    +		$hidedetails = $hidedesc = $hideref = 0;
    +		$moreparams=null;
    +		if (empty($hidedetails)) $hidedetails=0;
    +		if (empty($hidedesc)) $hidedesc=0;
    +		if (empty($hideref)) $hideref=0;
    +		if (empty($moreparams)) $moreparams=null;
    +
    +
    +		$sql = "SELECT rowid";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."societe_rib";
    +		if ($id) $sql.= " WHERE fk_soc  = ".$id." ";
    +		if ($companybankid) $sql.= " AND id = ".$companybankid."";
    +
    +		$i=0;
    +		$accounts=array();
    +
    +		$result = $this->db->query($sql);
    +		if ($result)
    +		{
    +			if ($result->num_rows == 0) {
    +				throw new RestException(404, 'Bank account not found');
    +			}
    +
    +			$num = $this->db->num_rows($result);
    +			while ($i < $num)
    +			{
    +				$obj = $this->db->fetch_object($result);
    +
    +				$account = new CompanyBankAccount($this->db);
    +				if ($account->fetch($obj->rowid)) {
    +					$accounts[] = $account;
    +				}
    +				$i++;
    +			}
    +		}
    +		else
    +		{
    +			throw new RestException(404, 'Bank account not found');
    +		}
    +
    +		$moreparams = array(
    +			'use_companybankid'=>$accounts[0]->id,
    +			'force_dir_output'=>$this->conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName($this->company->id)
    +		);
    +
    +		$result = 0;
    +
    +		$result = $this->company->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
    +
    +		if ($result > 0)
    +		{
    +			return array("success" => $result);
    +		}
    +		else
    +		{
    +			throw new RestException(500);
    +		}
    +    }
    +
    +  /**
    +	 * Get a specific gateway attached to a thirdparty (by specifying the site key)
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 * @param string $site Site key
    +	 *
    +	 * @return SocieteAccount[]
    +	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
    +	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
    +	 *
    +	 * @url GET {id}/gateways/
    +	 */
    +	function getSocieteAccounts($id, $site=null)
    +    {
    +		global $db, $conf;
    +
    +		if(!DolibarrApiAccess::$user->rights->societe->lire) {
    +			throw new RestException(401);
    +		}
    +
    +		if(!DolibarrApi::_checkAccessToResource('societe',$id)) {
    +			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
    +		}
    +
    +		/**
    +		 * We select all the records that match the socid
    +		 */
    +		$sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
    +		$sql.= " WHERE fk_soc = $id";
    +		if($site) $sql .= " AND site ='$site'";
    +
    +		$result = $db->query($sql);
    +
    +		if($result->num_rows == 0){
    +			throw new RestException(404, 'This thirdparty does not have any gateway attached or does not exist.');
    +		}
    +
    +		$i=0;
    +
    +		$accounts =[];
    +
    +		$num = $db->num_rows($result);
    +		while ($i < $num)
    +		{
    +			$obj = $db->fetch_object($result);
    +			$account = new SocieteAccount($db);
    +
    +			if($account->fetch($obj->rowid)) {
    +				$accounts[] = $account;
    +			}
    +			$i++;
    +		}
    +
    +		$fields = ['id', 'fk_soc', 'key_account', 'site', 'date_creation', 'tms'];
    +
    +		$returnAccounts = [];
    +
    +		foreach($accounts as $account){
    +			$object= [];
    +			foreach($account as $key => $value)
    +				if(in_array($key, $fields)){
    +					$object[$key] = $value;
    +				}
    +			$returnAccounts[] = $object;
    +		}
    +
    +		return $returnAccounts;
    +	}
    +
    +	/**
    +	 * Create and attach a new gateway to an existing thirdparty
    +	 *
    +	 * Possible fields for request_data (request body) are specified in <code>llx_societe_account</code> table.<br>
    +	 * See <a href="https://wiki.dolibarr.org/index.php/Table_llx_societe_account">Table llx_societe_account</a> wiki page for more information<br><br>
    +	 * <u>Example body payload :</u> <pre>{"key_account": "cus_DAVkLSs1LYyYI", "site": "stripe"}</pre>
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 * @param array $request_data Request data
    +	 *
    +	 * @return SocieteAccount
    +	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
    +	 * @throws 409 Conflict: A SocieteAccount entity (gateway) already exists for this company and site.
    +	 * @throws 422 Unprocessable Entity: You must pass the site attribute in your request data !
    +	 * @throws 500 Internal Server Error: Error creating SocieteAccount account
    +	 * @status 201
    +	 *
    +	 * @url POST {id}/gateways
    +	 */
    +	function createSocieteAccount($id, $request_data = null)
    +	{
    +		global $db;
    +
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		if(!isset($request_data['site'])) {
    +			throw new RestException(422, 'Unprocessable Entity: You must pass the site attribute in your request data !');
    +		}
    +
    +		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = ".$id." AND site = '". $request_data['site']."' ";
    +		$result = $db->query($sql);
    +
    +		if($result->num_rows == 0 ){
    +			$account = new SocieteAccount($this->db);
    +			if(!isset($request_data['login'])) {
    +				$account->login = "";
    +			}
    +			$account->fk_soc = $id;
    +
    +			foreach($request_data as $field => $value) {
    +				$account->$field = $value;
    +			}
    +
    +			if ($account->create(DolibarrApiAccess::$user) < 0)
    +				throw new RestException(500, 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!');
    +
    +			$this->_cleanObjectDatas($account);
    +
    +			return $account;
    +		} else {
    +			throw new RestException(409, 'A SocieteAccount entity already exists for this company and site.');
    +		}
    +	}
    +
    +	/**
    +	 * Create and attach a new (or replace an existing) specific site gateway to a thirdparty
    +	 *
    +	 * You <strong>MUST</strong> pass all values to keep (otherwise, they will be deleted) !<br>
    +	 * If you just need to update specific fields prefer <code>PATCH /thirdparties/{id}/gateways/{site}</code> endpoint.<br><br>
    +	 * When a <strong>SocieteAccount</strong> entity does not exist for the <code>id</code> and <code>site</code>
    +	 * supplied, a new one will be created. In that case <code>fk_soc</code> and <code>site</code> members form
    +	 * request body payload will be ignored and <code>id</code> and <code>site</code> query strings parameters
    +	 * will be used instead.
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 * @param string $site Site key
    +	 * @param array $request_data Request data
    +	 *
    +	 * @return SocieteAccount
    +	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
    +	 * @throws 422 Unprocessable Entity: You must pass the site attribute in your request data !
    +	 * @throws 500 Internal Server Error: Error updating SocieteAccount entity
    +	 *
    +	 * @throws RestException
    +	 * @url PUT {id}/gateways/{site}
    +	 */
    +	function putSocieteAccount($id, $site, $request_data = null)
    +	{
    +		global $db;
    +
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		$sql = "SELECT rowid, fk_user_creat, date_creation FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = $id AND site = '$site' ";
    +		$result = $db->query($sql);
    +
    +		// We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
    +		if($result->num_rows == 0 ){
    +			if(!isset($request_data['key_account'])) {
    +				throw new RestException(422, 'Unprocessable Entity: You must pass the key_account attribute in your request data !');
    +			}
    +			$account = new SocieteAccount($this->db);
    +			if(!isset($request_data['login'])) {
    +				$account->login = "";
    +			}
    +
    +			foreach($request_data as $field => $value) {
    +				$account->$field = $value;
    +			}
    +
    +			$account->fk_soc = $id;
    +			$account->site = $site;
    +
    +			if ($account->create(DolibarrApiAccess::$user) < 0)
    +				throw new RestException(500, 'Error creating SocieteAccount entity.');
    +		// We found an existing SocieteAccount entity, we are replacing it
    +		} else {
    +
    +			if(isset($request_data['site']) && $request_data['site'] !== $site) {
    +				$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = ".$id." AND site = '". $request_data['site']."' ";
    +				$result = $db->query($sql);
    +
    +				if($result->num_rows !== 0)
    +					throw new RestException(409, "You are trying to update this thirdparty SocieteAccount (gateway record) from $site to ".$request_data['site'] . " but another SocieteAccount entity already exists with this site key.");
    +			}
    +
    +			$obj = $db->fetch_object($result);
    +
    +			$account = new SocieteAccount($this->db);
    +			$account->id = $obj->rowid;
    +			$account->fk_soc = $id;
    +			$account->site = $site;
    +			if(!isset($request_data['login'])) {
    +				$account->login = "";
    +			}
    +			$account->fk_user_creat = $obj->fk_user_creat;
    +			$account->date_creation = $obj->date_creation;
    +
    +			foreach($request_data as $field => $value) {
    +				$account->$field = $value;
    +			}
    +
    +			if ($account->update(DolibarrApiAccess::$user) < 0)
    +				throw new RestException(500, 'Error updating SocieteAccount entity.');
    +		}
    +
    +		$this->_cleanObjectDatas($account);
    +
    +		return $account;
    +	}
    +
    +	/**
    +	 * Update specified values of a specific site gateway attached to a thirdparty
    +	 *
    +	 * @param int $id Id of thirdparty
    +	 * @param string  $site Site key
    +	 * @param array $request_data Request data
    +	 *
    +	 * @return SocieteAccount
    +	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
    +	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
    +	 * @throws 409 Conflict: Another SocieteAccount entity already exists for this thirdparty with this site key.
    +	 * @throws 500 Internal Server Error: Error updating SocieteAccount entity
    +	 *
    +	 * @url PATCH {id}/gateways/{site}
    +	 */
    +	function patchSocieteAccount($id, $site, $request_data = null)
    +	{
    +		global $db;
    +
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = $id AND site = '$site' ";
    +		$result = $db->query($sql);
    +
    +		if($result->num_rows == 0 ){
    +			throw new RestException(404, "This thirdparty does not have $site gateway attached or does not exist.");
    +		} else {
    +
    +			// If the user tries to edit the site member, we check first if
    +			if(isset($request_data['site']) && $request_data['site'] !== $site) {
    +				$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = ".$id." AND site = '". $request_data['site']."' ";
    +				$result = $db->query($sql);
    +
    +				if($result->num_rows !== 0)
    +					throw new RestException(409, "You are trying to update this thirdparty SocieteAccount (gateway record) site member from $site to ".$request_data['site'] . " but another SocieteAccount entity already exists for this thirdparty with this site key.");
    +			}
    +
    +			$obj = $db->fetch_object($result);
    +			$account = new SocieteAccount($this->db);
    +			$account->fetch($obj->rowid);
    +
    +			foreach($request_data as $field => $value) {
    +				$account->$field = $value;
    +			}
    +
    +			if ($account->update(DolibarrApiAccess::$user) < 0)
    +				throw new RestException(500, 'Error updating SocieteAccount account');
    +
    +			$this->_cleanObjectDatas($account);
    +
    +			return $account;
    +		}
    +	}
    +
    +	/**
    +	 * Delete a specific site gateway attached to a thirdparty (by gateway id)
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 * @param int $site Site key
    +	 *
    +	 * @return void
    +	 * @throws 401 Unauthorized: User does not have permission to delete thirdparties gateways
    +	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
    +	 * @throws 500 Internal Server Error: Error deleting SocieteAccount entity
    +	 *
    +	 * @url DELETE {id}/gateways/{site}
    +	 */
    +	function deleteSocieteAccount($id, $site)
    +    {
    +		global /** @var Database $db */
    +		$db;
    +
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = $id AND site = '$site' ";
    +		$result = $db->query($sql);
    +
    +		if($result->num_rows == 0 ){
    +			throw new RestException(404);
    +		} else {
    +			$obj = $db->fetch_object($result);
    +			$account = new SocieteAccount($this->db);
    +			$account->fetch($obj->rowid);
    +
    +			if($account->delete(DolibarrApiAccess::$user) < 0) {
    +				throw new RestException(500, "Error while deleting $site gateway attached to this third party");
    +			}
    +		}
    +	}
    +
    +	/**
    +	 * Delete all gateways attached to a thirdparty
    +	 *
    +	 * @param int $id ID of thirdparty
    +	 *
    +	 * @return void
    +	 * @throws 401 Unauthorized: User does not have permission to delete thirdparties gateways
    +	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
    +	 * @throws 500 Internal Server Error: Error deleting SocieteAccount entity
    +	 *
    +	 * @url DELETE {id}/gateways
    +	 */
    +	function deleteSocieteAccounts($id)
    +    {
    +		global /** @var Database $db */
    +		$db;
    +
    +		if(! DolibarrApiAccess::$user->rights->societe->creer) {
    +			throw new RestException(401);
    +		}
    +
    +		/**
    +		 * We select all the records that match the socid
    +		 */
    +
    +		$sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms";
    +		$sql.= " FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = $id ";
    +
    +		$result = $db->query($sql);
    +
    +		if($result->num_rows == 0 ){
    +			throw new RestException(404, 'This third party does not have any gateway attached or does not exist.');
    +		} else {
    +			$i=0;
    +
    +			$num = $db->num_rows($result);
    +			while ($i < $num)
    +			{
    +				$obj = $db->fetch_object($result);
    +				$account = new SocieteAccount($db);
    +				$account->fetch($obj->rowid);
    +
    +				if($account->delete(DolibarrApiAccess::$user) < 0) {
    +					throw new RestException(500, 'Error while deleting gateways attached to this third party');
    +				}
    +				$i++;
    +			}
    +		}
    +	}
     
     	/**
     	 * Clean sensible object datas
    @@ -1005,8 +1632,8 @@ class Thirdparties extends DolibarrApi
     	 * @param   object  $object    Object to clean
     	 * @return    array    Array of cleaned object properties
     	 */
    -	function _cleanObjectDatas($object) {
    -
    +	function _cleanObjectDatas($object)
    +    {
     		$object = parent::_cleanObjectDatas($object);
     
     		unset($object->nom);	// ->name already defined and nom deprecated
    @@ -1037,7 +1664,7 @@ class Thirdparties extends DolibarrApi
     		foreach (Thirdparties::$FIELDS as $field) {
     			if (!isset($data[$field]))
     				throw new RestException(400, "$field field missing");
    -				$thirdparty[$field] = $data[$field];
    +			$thirdparty[$field] = $data[$field];
     		}
     		return $thirdparty;
     	}
    diff --git a/htdocs/societe/class/client.class.php b/htdocs/societe/class/client.class.php
    index 59eea72c2c7..400dc65b0c2 100644
    --- a/htdocs/societe/class/client.class.php
    +++ b/htdocs/societe/class/client.class.php
    @@ -47,6 +47,7 @@ class Client extends Societe
             $this->fournisseur = 0;
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *  Load indicators into this->nb for board
          *
    @@ -54,6 +55,7 @@ class Client extends Societe
          */
         function load_state_board()
         {
    +        // phpcs:enable
             global $user;
     
             $this->nb=array("customers" => 0,"prospects" => 0);
    @@ -88,7 +90,6 @@ class Client extends Societe
                 $this->error=$this->db->lasterror();
                 return -1;
             }
    -
         }
     
     	/**
    @@ -114,5 +115,4 @@ class Client extends Societe
     		}
     		return 1;
         }
    -
     }
    diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php
    index 187f7c5ec65..73210ade104 100644
    --- a/htdocs/societe/class/companybankaccount.class.php
    +++ b/htdocs/societe/class/companybankaccount.class.php
    @@ -184,7 +184,6 @@ class CompanyBankAccount extends Account
     		{
     			return 1;
     		}
    -
     		}
     		else
     		{
    @@ -197,10 +196,12 @@ class CompanyBankAccount extends Account
     	 * 	Load record from database
     	 *
     	 *	@param	int		$id			Id of record
    -	 * 	@param	int		$socid		Id of company. If this is filled, function will return the first default RIB of company
    +	 * 	@param	int		$socid		Id of company. If this is filled, function will return the first entry found (matching $default and $type)
    +	 *  @param	int		$default	If id of company filled, we say if we want first record among all (-1), default record (1) or non default record (0)
    +	 *  @param	int		$type		If id of company filled, we say if we want record of this type only
     	 * 	@return	int					<0 if KO, >0 if OK
     	 */
    -	function fetch($id, $socid=0)
    +	function fetch($id, $socid=0, $default=1, $type='ban')
     	{
     		if (empty($id) && empty($socid)) return -1;
     
    @@ -208,7 +209,12 @@ class CompanyBankAccount extends Account
     		$sql.= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
     		$sql.= " FROM ".MAIN_DB_PREFIX."societe_rib";
     		if ($id)    $sql.= " WHERE rowid = ".$id;
    -		if ($socid) $sql.= " WHERE fk_soc  = ".$socid." AND default_rib = 1 AND type ='ban'";
    +		if ($socid)
    +		{
    +			$sql.= " WHERE fk_soc  = ".$socid;
    +			if ($default > -1) $sql.=" AND default_rib = ".$this->db->escape($default);
    +			if ($type) $sql.= " AND type ='".$this->db->escape($type)."'";
    +		}
     
     		$resql = $this->db->query($sql);
     		if ($resql)
    @@ -408,6 +414,5 @@ class CompanyBankAccount extends Account
     
     		$this->socid = 0;
     	}
    -
     }
     
    diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php
    index 4403d5b8fde..73242c9aa32 100644
    --- a/htdocs/societe/class/companypaymentmode.class.php
    +++ b/htdocs/societe/class/companypaymentmode.class.php
    @@ -18,7 +18,7 @@
     
     /**
      * \file        class/companypaymentmode.class.php
    - * \ingroup     monmodule
    + * \ingroup     company
      * \brief       This file is a CRUD class file for CompanyPaymentMode (Create/Read/Update/Delete)
      */
     
    @@ -36,18 +36,22 @@ class CompanyPaymentMode extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'companypaymentmode';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'societe_rib';
    +
     	/**
     	 * @var int  Does companypaymentmode support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 2;
    +
     	/**
     	 * @var int  Does companypaymentmode support extrafields ? 0=No, 1=Yes
     	 */
     	public $isextrafieldmanaged = 0;
    +
     	/**
     	 * @var string String with name of icon for companypaymentmode. Must be the part after the 'object_' into object_companypaymentmode.png
     	 */
    @@ -114,9 +118,22 @@ class CompanyPaymentMode extends CommonObject
     		'import_key' =>array('type'=>'varchar(14)', 'label'=>'Import key', 'enabled'=>1, 'visible'=>-2, 'position'=>105),
     	//'aaa' =>array('type'=>'date', 'label'=>'Ending date', 'enabled'=>0, 'visible'=>-2, 'position'=>185),
     	);
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    -	public $fk_soc;
    -	public $label;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +    public $fk_soc;
    +
    +	/**
    +     * @var string company payment mode label
    +     */
    +    public $label;
    +
     	public $bank;
     	public $code_banque;
     	public $code_guichet;
    @@ -144,7 +161,12 @@ class CompanyPaymentMode extends CommonObject
     	public $preapproval_key;
     	public $total_amount_of_all_payments;
     	public $stripe_card_ref;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	public $starting_date;
     	public $ending_date;
     	public $datec;
    @@ -448,6 +470,7 @@ class CompanyPaymentMode extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -457,40 +480,35 @@ class CompanyPaymentMode extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
    -		if ($mode == 0)
    -		{
    -			$prefix='';
    -			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    -		}
    -		if ($mode == 1)
    +		if ($mode == 0 || $mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
     			if ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    @@ -543,7 +561,6 @@ class CompanyPaymentMode extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -561,5 +578,4 @@ class CompanyPaymentMode extends CommonObject
     	{
     		$this->initAsSpecimenCommon();
     	}
    -
     }
    diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
    index 4ec328e5007..dd1aada283b 100644
    --- a/htdocs/societe/class/societe.class.php
    +++ b/htdocs/societe/class/societe.class.php
    @@ -41,9 +41,21 @@ require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
      */
     class Societe extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='societe';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element = 'societe';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_soc';
    +
     	public $fieldsforcombobox='nom,name_alias';
     	protected $childtables=array("supplier_proposal"=>'SupplierProposal',"propal"=>'Proposal',"commande"=>'Order',"facture"=>'Invoice',"facture_rec"=>'RecurringInvoiceTemplate',"contrat"=>'Contract',"fichinter"=>'Fichinter',"facture_fourn"=>'SupplierInvoice',"commande_fournisseur"=>'SupplierOrder',"projet"=>'Project',"expedition"=>'Shipment',"prelevement_lignes"=>'DirectDebitRecord');    // To test if we can delete object
     	protected $childtablesoncascade=array("societe_prices", "societe_log", "societe_address", "product_fournisseur_price", "product_customer_price_log", "product_customer_price", "socpeople", "adherent", "societe_rib", "societe_remise", "societe_remise_except", "societe_commerciaux", "categorie", "notify", "notify_def", "actioncomm");
    @@ -54,6 +66,7 @@ class Societe extends CommonObject
     	 * @var int
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
     	 * @var integer
    @@ -67,9 +80,9 @@ class Societe extends CommonObject
     	 */
     	public $fields=array(
     		'rowid'         =>array('type'=>'integer',      'label'=>'TechnicalID',      'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'index'=>1, 'position'=>1, 'comment'=>'Id'),
    -		'nom'           =>array('type'=>'varchar(128)', 'label'=>'Name',            'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    -		'name_alias'    =>array('type'=>'varchar(128)', 'label'=>'Name',            'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    -		'entity'        =>array('type'=>'integer',      'label'=>'Entity',           'enabled'=>1, 'visible'=>0,  'default'=>1, 'notnull'=>1,  'index'=>1, 'position'=>20),
    +		'nom'           =>array('type'=>'varchar(128)', 'label'=>'Name',             'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    +		'name_alias'    =>array('type'=>'varchar(128)', 'label'=>'Name',             'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    +		'entity'        =>array('type'=>'integer',      'label'=>'Entity',           'enabled'=>1, 'visible'=>0,  'default'=>1,  'notnull'=>1,  'index'=>1, 'position'=>20),
     		'note_public'   =>array('type'=>'text',			'label'=>'NotePublic',		 'enabled'=>1, 'visible'=>0,  'position'=>60),
     		'note_private'  =>array('type'=>'text',			'label'=>'NotePrivate',		 'enabled'=>1, 'visible'=>0,  'position'=>61),
     		'date_creation' =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>500),
    @@ -82,6 +95,9 @@ class Societe extends CommonObject
     	);
     
     
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
     
     	/**
    @@ -92,6 +108,11 @@ class Societe extends CommonObject
     	 */
     	public $nom;
     
    +	/**
    +	 * @var string name
    +	 */
    +	public $name;
    +
     	/**
     	 * Alias names (commercial, trademark or alias names)
     	 * @var string
    @@ -99,7 +120,12 @@ class Societe extends CommonObject
     	public $name_alias;
     
     	public $particulier;
    +
    +	/**
    +	 * @var string Address
    +	 */
     	public $address;
    +
     	public $zip;
     	public $town;
     
    @@ -166,6 +192,16 @@ class Societe extends CommonObject
     	 * @var string
     	 */
     	public $skype;
    +	/**
    +	 * Twitter username
    +	 * @var string
    +	 */
    +	public $twitter;
    +	/**
    +	 * Facebook username
    +	 * @var string
    +	 */
    +	public $facebook;
     	/**
     	 * Webpage
     	 * @var string
    @@ -245,7 +281,12 @@ class Societe extends CommonObject
     	public $remise_supplier_percent;
     	public $mode_reglement_supplier_id;
     	public $cond_reglement_supplier_id;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_prospectlevel;
    +
     	public $name_bis;
     
     	//Log data
    @@ -308,6 +349,12 @@ class Societe extends CommonObject
     	 */
     	public $code_compta;
     
    +    /**
    +     * Accounting code for client
    +     * @var string
    +     */
    +    public $code_compta_client;
    +
     	/**
     	 * Accounting code for suppliers
     	 * @var string
    @@ -366,7 +413,11 @@ class Societe extends CommonObject
     	 */
     	public $default_lang;
     
    +	/**
    +	 * @var string Ref
    +	 */
     	public $ref;
    +
     	public $ref_int;
     	/**
     	 * External user reference.
    @@ -403,12 +454,20 @@ class Societe extends CommonObject
     	public $array_options;
     
     	// Incoterms
    +	/**
    +     * @var int ID
    +     */
     	public $fk_incoterms;
    +
     	public $location_incoterms;
     	public $libelle_incoterms;  //Used into tooltip
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     
     
    @@ -510,7 +569,7 @@ class Societe extends CommonObject
     					$this->add_commercial($user, $this->commercial_id);
     				}
     				// si un commercial cree un client il lui est affecte automatiquement
    -				else if (empty($user->rights->societe->client->voir))
    +				elseif (empty($user->rights->societe->client->voir))
     				{
     					$this->add_commercial($user, $user->id);
     				}
    @@ -552,7 +611,6 @@ class Societe extends CommonObject
     				$this->db->rollback();
     				return $result;
     			}
    -
     		}
     		else
     		{
    @@ -563,6 +621,7 @@ class Societe extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Create a contact/address from thirdparty
     	 *
    @@ -571,6 +630,7 @@ class Societe extends CommonObject
     	 */
     	function create_individual(User $user)
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     		$contact=new Contact($this->db);
     
    @@ -631,15 +691,15 @@ class Societe extends CommonObject
     				{
     					$this->errors[] = 'ErrorBadCustomerCodeSyntax';
     				}
    -				if ($rescode == -2)
    +				elseif ($rescode == -2)
     				{
     					$this->errors[] = 'ErrorCustomerCodeRequired';
     				}
    -				if ($rescode == -3)
    +				elseif ($rescode == -3)
     				{
     					$this->errors[] = 'ErrorCustomerCodeAlreadyUsed';
     				}
    -				if ($rescode == -4)
    +				elseif ($rescode == -4)
     				{
     					$this->errors[] = 'ErrorPrefixRequired';
     				}
    @@ -656,15 +716,15 @@ class Societe extends CommonObject
     				{
     					$this->errors[] = 'ErrorBadSupplierCodeSyntax';
     				}
    -				if ($rescode == -2)
    +				elseif ($rescode == -2)
     				{
     					$this->errors[] = 'ErrorSupplierCodeRequired';
     				}
    -				if ($rescode == -3)
    +				elseif ($rescode == -3)
     				{
     					$this->errors[] = 'ErrorSupplierCodeAlreadyUsed';
     				}
    -				if ($rescode == -5)
    +				elseif ($rescode == -5)
     				{
     					$this->errors[] = 'ErrorprefixRequired';
     				}
    @@ -785,6 +845,8 @@ class Societe extends CommonObject
     		$this->fax			= preg_replace("/\./","",$this->fax);
     		$this->email		= trim($this->email);
     		$this->skype		= trim($this->skype);
    +		$this->twitter		= trim($this->twitter);
    +		$this->facebook		= trim($this->facebook);
     		$this->url			= $this->url?clean_url($this->url,0):'';
     		$this->note_private = trim($this->note_private);
     		$this->note_public  = trim($this->note_public);
    @@ -908,6 +970,8 @@ class Societe extends CommonObject
     			$sql .= ",fax = ".(! empty($this->fax)?"'".$this->db->escape($this->fax)."'":"null");
     			$sql .= ",email = ".(! empty($this->email)?"'".$this->db->escape($this->email)."'":"null");
     			$sql .= ",skype = ".(! empty($this->skype)?"'".$this->db->escape($this->skype)."'":"null");
    +			$sql .= ",twitter = ".(! empty($this->twitter)?"'".$this->db->escape($this->twitter)."'":"null");
    +			$sql .= ",facebook = ".(! empty($this->facebook)?"'".$this->db->escape($this->facebook)."'":"null");
     			$sql .= ",url = ".(! empty($this->url)?"'".$this->db->escape($this->url)."'":"null");
     
     			$sql .= ",parent = " . ($this->parent > 0 ? $this->parent : "null");
    @@ -936,7 +1000,6 @@ class Societe extends CommonObject
     					$sql .=",localtax1_value =".$this->localtax1_value;
     				}
     				else $sql .=",localtax1_value =0.000";
    -
     			}
     			else $sql .=",localtax1_value =0.000";
     
    @@ -947,7 +1010,6 @@ class Societe extends CommonObject
     					$sql .=",localtax2_value =".$this->localtax2_value;
     				}
     				else $sql .=",localtax2_value =0.000";
    -
     			}
     			else $sql .=",localtax2_value =0.000";
     
    @@ -1006,10 +1068,26 @@ class Societe extends CommonObject
     			$resql=$this->db->query($sql);
     			if ($resql)
     			{
    -				unset($this->country_code);		// We clean this because it may have been changed after an update of country_id
    -				unset($this->country);
    -				unset($this->state_code);
    -				unset($this->state);
    +				if (is_object($this->oldcopy))	// If we have information on old values
    +				{
    +					if ($this->oldcopy->country_id != $this->country_id)
    +					{
    +						unset($this->country_code);
    +						unset($this->country);
    +					}
    +					if ($this->oldcopy->state_id != $this->state_id)
    +					{
    +						unset($this->state_code);
    +						unset($this->state);
    +					}
    +				}
    +				else
    +				{
    +					unset($this->country_code);	// We clean this, in the doubt, because it may have been changed after an update of country_id
    +					unset($this->country);
    +					unset($this->state_code);
    +					unset($this->state);
    +				}
     
     				$nbrowsaffected = $this->db->affected_rows($resql);
     
    @@ -1033,6 +1111,8 @@ class Societe extends CommonObject
     							$lmember->address=$this->address;
     							$lmember->email=$this->email;
     							$lmember->skype=$this->skype;
    +							$lmember->twitter=$this->twitter;
    +							$lmember->facebook=$this->facebook;
     							$lmember->phone=$this->phone;
     
     							$result=$lmember->update($user,0,1,1,1);	// Use nosync to 1 to avoid cyclic updates
    @@ -1043,7 +1123,7 @@ class Societe extends CommonObject
     								$error++;
     							}
     						}
    -						else if ($result < 0)
    +						elseif ($result < 0)
     						{
     							$this->error=$lmember->error;
     							$error++;
    @@ -1136,7 +1216,7 @@ class Societe extends CommonObject
     		$sql .= ', s.status';
     		$sql .= ', s.price_level';
     		$sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif';
    -		$sql .= ', s.phone, s.fax, s.email, s.skype, s.url, s.zip, s.town, s.note_private, s.note_public, s.model_pdf, s.client, s.fournisseur';
    +		$sql .= ', s.phone, s.fax, s.email, s.skype, s.twitter, s.facebook, s.url, s.zip, s.town, s.note_private, s.note_public, s.model_pdf, s.client, s.fournisseur';
     		$sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6';
     		$sql .= ', s.capital, s.tva_intra';
     		$sql .= ', s.fk_typent as typent_id';
    @@ -1229,6 +1309,8 @@ class Societe extends CommonObject
     
     				$this->email = $obj->email;
     				$this->skype = $obj->skype;
    +				$this->twitter = $obj->twitter;
    +				$this->facebook = $obj->facebook;
     				$this->url = $obj->url;
     				$this->phone = $obj->phone;
     				$this->fax = $obj->fax;
    @@ -1340,114 +1422,6 @@ class Societe extends CommonObject
     		return $result;
     	}
     
    -	/**
    -	 * 	Search and fetch thirparties by name
    -	 *
    -	 * 	@param		string		$name		Name
    -	 * 	@param		int			$type		Type of thirdparties (0=any, 1=customer, 2=prospect, 3=supplier)
    -	 * 	@param		array		$filters	Array of couple field name/value to filter the companies with the same name
    -	 * 	@param		boolean		$exact		Exact string search (true/false)
    -	 * 	@param		boolean		$case		Case sensitive (true/false)
    -	 * 	@param		boolean		$similar	Add test if string inside name into database, or name into database inside string. Do not use this: Not compatible with other database.
    -	 * 	@param		string		$clause		Clause for filters
    -	 * 	@return		array|int				<0 if KO, array of thirdparties object if OK
    -	 */
    -	function searchByName($name, $type='0', $filters = array(), $exact = false, $case = false, $similar = false, $clause = 'AND')
    -	{
    -		$thirdparties = array();
    -
    -		dol_syslog("searchByName name=".$name." type=".$type." exact=".$exact);
    -
    -		// Check parameter
    -		if (empty($name))
    -		{
    -			$this->errors[]='ErrorBadValueForParameter';
    -			return -1;
    -		}
    -
    -		// Generation requete recherche
    -		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe";
    -		$sql.= " WHERE entity IN (".getEntity('societe').")";
    -		if (! empty($type))
    -		{
    -			if ($type == 1 || $type == 2)
    -				$sql.= " AND client = ".$type;
    -			elseif ($type == 3)
    -				$sql.= " AND fournisseur = 1";
    -		}
    -		if (! empty($name))
    -		{
    -			if (! $exact)
    -			{
    -				if (preg_match('/^([\*])?[^*]+([\*])?$/', $name, $regs) && count($regs) > 1)
    -				{
    -					$name = str_replace('*', '%', $name);
    -				}
    -				else
    -				{
    -					$name = '%'.$name.'%';
    -				}
    -			}
    -			$sql.= " AND ";
    -			if (is_array($filters) && ! empty($filters))
    -				$sql.= "(";
    -			if ($similar)
    -			{
    -				// For test similitude (string inside name into database, or name into database inside string)
    -				// Do not use this. Not compatible with other database.
    -				$sql.= "(LOCATE('".$this->db->escape($name)."', nom) > 0 OR LOCATE(nom, '".$this->db->escape($name)."') > 0)";
    -			}
    -			else
    -			{
    -				if (! $case)
    -					$sql.= "nom LIKE '".$this->db->escape($name)."'";
    -				else
    -					$sql.= "nom LIKE BINARY '".$this->db->escape($name)."'";
    -			}
    -		}
    -		if (is_array($filters) && ! empty($filters))
    -		{
    -			foreach($filters as $field => $value)
    -			{
    -				if (! $exact)
    -				{
    -					if (preg_match('/^([\*])?[^*]+([\*])?$/', $value, $regs) && count($regs) > 1)
    -					{
    -						$value = str_replace('*', '%', $value);
    -					}
    -					else
    -					{
    -						$value = '%'.$value.'%';
    -					}
    -				}
    -				if (! $case)
    -					$sql.= " ".$clause." ".$field." LIKE '".$this->db->escape($value)."'";
    -				else
    -					$sql.= " ".$clause." ".$field." LIKE BINARY '".$this->db->escape($value)."'";
    -			}
    -			if (! empty($name))
    -				$sql.= ")";
    -		}
    -
    -		$res  = $this->db->query($sql);
    -		if ($res)
    -		{
    -			while ($rec = $this->db->fetch_array($res))
    -			{
    -				$soc = new Societe($this->db);
    -				$soc->fetch($rec['rowid']);
    -				$thirdparties[] = $soc;
    -			}
    -
    -			return $thirdparties;
    -		}
    -		else
    -		{
    -			$this->error=$this->db->lasterror();
    -			return -1;
    -		}
    -	}
    -
     	/**
     	 *    Delete a third party from database and all its dependencies (contacts, rib...)
     	 *
    @@ -1574,6 +1548,7 @@ class Societe extends CommonObject
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Define third party as a customer
     	 *
    @@ -1581,6 +1556,7 @@ class Societe extends CommonObject
     	 */
     	function set_as_client()
     	{
    +        // phpcs:enable
     		if ($this->id)
     		{
     			$newclient=1;
    @@ -1600,6 +1576,7 @@ class Societe extends CommonObject
     		return 0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Definit la societe comme un client
     	 *
    @@ -1610,6 +1587,7 @@ class Societe extends CommonObject
     	 */
     	function set_remise_client($remise, $note, User $user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		// Nettoyage parametres
    @@ -1661,6 +1639,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Definit la societe comme un client
     	 *
    @@ -1671,6 +1650,7 @@ class Societe extends CommonObject
     	 */
     	function set_remise_supplier($remise, $note, User $user)
     	{
    +        // phpcs:enable
     		global $conf, $langs;
     
     		// Nettoyage parametres
    @@ -1722,6 +1702,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Add a discount for third party
     	 *
    @@ -1734,6 +1715,7 @@ class Societe extends CommonObject
     	 */
     	function set_remise_except($remise, User $user, $desc, $tva_tx=0, $discount_type=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		// Clean parameters
    @@ -1869,6 +1851,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Set the price level
     	 *
    @@ -1878,6 +1861,7 @@ class Societe extends CommonObject
     	 */
     	function set_price_level($price_level, User $user)
     	{
    +        // phpcs:enable
     		if ($this->id)
     		{
     			$now=dol_now();
    @@ -1906,6 +1890,7 @@ class Societe extends CommonObject
     		return -1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Add link to sales representative
     	 *
    @@ -1915,6 +1900,10 @@ class Societe extends CommonObject
     	 */
     	function add_commercial(User $user, $commid)
     	{
    +        // phpcs:enable
    +		$error=0;
    +
    +
     		if ($this->id > 0 && $commid > 0)
     		{
     			$sql = "DELETE FROM  ".MAIN_DB_PREFIX."societe_commerciaux";
    @@ -1930,9 +1919,16 @@ class Societe extends CommonObject
     			{
     				dol_syslog(get_class($this)."::add_commercial Erreur");
     			}
    +			else {
    +				$this->context=array('commercial_modified'=>$commid);
    +
    +				$result=$this->call_trigger('COMPANY_LINK_SALE_REPRESENTATIVE',$user);
    +                if ($result < 0) $error++;
    +			}
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Add link to sales representative
     	 *
    @@ -1942,6 +1938,13 @@ class Societe extends CommonObject
     	 */
     	function del_commercial(User $user, $commid)
     	{
    +        // phpcs:enable
    +		$error=0;
    +		$this->context=array('commercial_modified'=>$commid);
    +
    +		$result=$this->call_trigger('COMPANY_UNLINK_SALE_REPRESENTATIVE',$user);
    +        if ($result < 0) $error++;
    +
     		if ($this->id > 0 && $commid > 0)
     		{
     			$sql  = "DELETE FROM  ".MAIN_DB_PREFIX."societe_commerciaux ";
    @@ -2030,37 +2033,37 @@ class Societe extends CommonObject
     		   $label.= '<u>' . $langs->trans("ShowCustomer") . '</u>';
     		   $linkstart = '<a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id;
     		}
    -		else if ($option == 'prospect' && empty($conf->global->SOCIETE_DISABLE_PROSPECTS))
    +		elseif ($option == 'prospect' && empty($conf->global->SOCIETE_DISABLE_PROSPECTS))
     		{
     			$label.= '<u>' . $langs->trans("ShowProspect") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id;
     		}
    -		else if ($option == 'supplier')
    +		elseif ($option == 'supplier')
     		{
     			$label.= '<u>' . $langs->trans("ShowSupplier") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/fourn/card.php?socid='.$this->id;
     		}
    -		else if ($option == 'agenda')
    +		elseif ($option == 'agenda')
     		{
     			$label.= '<u>' . $langs->trans("ShowAgenda") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/agenda.php?socid='.$this->id;
     		}
    -		else if ($option == 'project')
    +		elseif ($option == 'project')
     		{
     			$label.= '<u>' . $langs->trans("ShowProject") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/project.php?socid='.$this->id;
     		}
    -		else if ($option == 'margin')
    +		elseif ($option == 'margin')
     		{
     			$label.= '<u>' . $langs->trans("ShowMargin") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/margin/tabs/thirdpartyMargins.php?socid='.$this->id.'&type=1';
     		}
    -		else if ($option == 'contact')
    +		elseif ($option == 'contact')
     		{
     			$label.= '<u>' . $langs->trans("ShowContacts") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/contact.php?socid='.$this->id;
     		}
    -		else if ($option == 'ban')
    +		elseif ($option == 'ban')
     		{
     			$label.= '<u>' . $langs->trans("ShowBan") . '</u>';
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$this->id;
    @@ -2081,13 +2084,22 @@ class Societe extends CommonObject
     		}
     		if (! empty($this->country_code))
     			$label.= '<br><b>' . $langs->trans('Country') . ':</b> '. $this->country_code;
    -		if (! empty($this->tva_intra))
    +		if (! empty($this->tva_intra) || (! empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP) && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false))
     			$label.= '<br><b>' . $langs->trans('VATIntra') . ':</b> '. $this->tva_intra;
    -		if (! empty($this->code_client) && $this->client)
    +		if (! empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP))
    +		{
    +			if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false) $label.= '<br><b>' . $langs->trans('ProfId1'.$this->country_code) . ':</b> '. $this->idprof1;
    +			if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false) $label.= '<br><b>' . $langs->trans('ProfId2'.$this->country_code) . ':</b> '. $this->idprof2;
    +			if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false) $label.= '<br><b>' . $langs->trans('ProfId3'.$this->country_code) . ':</b> '. $this->idprof3;
    +			if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false) $label.= '<br><b>' . $langs->trans('ProfId4'.$this->country_code) . ':</b> '. $this->idprof4;
    +			if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false) $label.= '<br><b>' . $langs->trans('ProfId5'.$this->country_code) . ':</b> '. $this->idprof5;
    +			if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false) $label.= '<br><b>' . $langs->trans('ProfId6'.$this->country_code) . ':</b> '. $this->idprof6;
    +		}
    +		if (! empty($this->code_client) && ($this->client == 1 || $this->client == 3))
     			$label.= '<br><b>' . $langs->trans('CustomerCode') . ':</b> '. $this->code_client;
     		if (! empty($this->code_fournisseur) && $this->fournisseur)
     			$label.= '<br><b>' . $langs->trans('SupplierCode') . ':</b> '. $this->code_fournisseur;
    -		if (! empty($conf->accounting->enabled) && $this->client)
    +		if (! empty($conf->accounting->enabled) && ($this->client == 1 || $this->client == 3))
     			$label.= '<br><b>' . $langs->trans('CustomerAccountancyCode') . ':</b> '. ($this->code_compta ? $this->code_compta : $this->code_compta_client);
     		if (! empty($conf->accounting->enabled) && $this->fournisseur)
     			$label.= '<br><b>' . $langs->trans('SupplierAccountancyCode') . ':</b> '. $this->code_compta_fournisseur;
    @@ -2156,6 +2168,7 @@ class Societe extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -2165,46 +2178,48 @@ class Societe extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('companies');
     
     		if ($mode == 0)
     		{
     			if ($statut==0) return $langs->trans("ActivityCeased");
    -			if ($statut==1) return $langs->trans("InActivity");
    +			elseif ($statut==1) return $langs->trans("InActivity");
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut==0) return $langs->trans("ActivityCeased");
    -			if ($statut==1) return $langs->trans("InActivity");
    +			elseif ($statut==1) return $langs->trans("InActivity");
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
    -			if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
    +			elseif ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
    -			if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
    +			elseif ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
    -			if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
    +			elseif ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans("ActivityCeased").'</span> '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
    -			if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans("InActivity").'</span> '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
    +			elseif ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans("InActivity").'</span> '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans("ActivityCeased").'</span> '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
    -			if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans("InActivity").'</span> '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
    +			elseif ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans("InActivity").'</span> '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return list of contacts emails existing for third party
     	 *
    @@ -2213,6 +2228,7 @@ class Societe extends CommonObject
     	 */
     	function thirdparty_and_contact_email_array($addthirdparty=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$contact_emails = $this->contact_property_array('email',1);
    @@ -2225,6 +2241,7 @@ class Societe extends CommonObject
     		return $contact_emails;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Return list of contacts mobile phone existing for third party
     	 *
    @@ -2232,6 +2249,7 @@ class Societe extends CommonObject
     	 */
     	function thirdparty_and_contact_phone_array()
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$contact_phone = $this->contact_property_array('mobile');
    @@ -2245,6 +2263,7 @@ class Societe extends CommonObject
     		return $contact_phone;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return list of contacts emails or mobile existing for third party
     	 *
    @@ -2254,6 +2273,7 @@ class Societe extends CommonObject
     	 */
     	function contact_property_array($mode='email', $hidedisabled=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$contact_property = array();
    @@ -2313,6 +2333,7 @@ class Societe extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Renvoie la liste des contacts de cette societe
     	 *
    @@ -2320,6 +2341,7 @@ class Societe extends CommonObject
     	 */
     	function contact_array()
     	{
    +        // phpcs:enable
     		$contacts = array();
     
     		$sql = "SELECT rowid, lastname, firstname FROM ".MAIN_DB_PREFIX."socpeople WHERE fk_soc = ".$this->id;
    @@ -2345,6 +2367,7 @@ class Societe extends CommonObject
     		return $contacts;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Renvoie la liste des contacts de cette societe
     	 *
    @@ -2352,6 +2375,7 @@ class Societe extends CommonObject
     	 */
     	function contact_array_objects()
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
     		$contacts = array();
     
    @@ -2380,6 +2404,7 @@ class Societe extends CommonObject
     		return $contacts;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return property of contact from its id
     	 *
    @@ -2389,6 +2414,7 @@ class Societe extends CommonObject
     	 */
     	function contact_get_property($rowid,$mode)
     	{
    +        // phpcs:enable
     		$contact_property='';
     
     		if (empty($rowid)) return '';
    @@ -2415,10 +2441,10 @@ class Societe extends CommonObject
     		{
     			dol_print_error($this->db);
     		}
    -
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return bank number property of thirdparty (label or rum)
     	 *
    @@ -2427,6 +2453,7 @@ class Societe extends CommonObject
     	 */
     	function display_rib($mode='label')
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
     
     		$bac = new CompanyBankAccount($this->db);
    @@ -2455,6 +2482,7 @@ class Societe extends CommonObject
     		return 'BadParameterToFunctionDisplayRib';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return Array of RIB
     	 *
    @@ -2462,6 +2490,7 @@ class Societe extends CommonObject
     	 */
     	function get_all_rib()
     	{
    +        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib WHERE type='ban' AND fk_soc = ".$this->id;
     		$result = $this->db->query($sql);
    @@ -2483,6 +2512,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Attribut un code client a partir du module de controle des codes.
     	 *  Return value is stored into this->code_client
    @@ -2493,6 +2523,7 @@ class Societe extends CommonObject
     	 */
     	function get_codeclient($objsoc=0,$type=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
     		{
    @@ -2513,6 +2544,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Attribut un code fournisseur a partir du module de controle des codes.
     	 *  Return value is stored into this->code_fournisseur
    @@ -2523,6 +2555,7 @@ class Societe extends CommonObject
     	 */
     	function get_codefournisseur($objsoc=0,$type=1)
     	{
    +        // phpcs:enable
     		global $conf;
     		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
     		{
    @@ -2542,6 +2575,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Verifie si un code client est modifiable en fonction des parametres
     	 *    du module de controle des codes.
    @@ -2550,6 +2584,7 @@ class Societe extends CommonObject
     	 */
     	function codeclient_modifiable()
     	{
    +        // phpcs:enable
     		global $conf;
     		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
     		{
    @@ -2577,6 +2612,7 @@ class Societe extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Verifie si un code fournisseur est modifiable dans configuration du module de controle des codes
     	 *
    @@ -2584,6 +2620,7 @@ class Societe extends CommonObject
     	 */
     	function codefournisseur_modifiable()
     	{
    +        // phpcs:enable
     		global $conf;
     		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
     		{
    @@ -2611,6 +2648,7 @@ class Societe extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Check customer code
     	 *
    @@ -2622,6 +2660,7 @@ class Societe extends CommonObject
     	 */
     	function check_codeclient()
     	{
    +        // phpcs:enable
     		global $conf;
     		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
     		{
    @@ -2646,6 +2685,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Check supplier code
     	 *
    @@ -2657,6 +2697,7 @@ class Societe extends CommonObject
     	 */
     	function check_codefournisseur()
     	{
    +        // phpcs:enable
     		global $conf;
     		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
     		{
    @@ -2681,6 +2722,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Renvoie un code compta, suivant le module de code compta.
     	 *      Peut etre identique a celui saisit ou genere automatiquement.
    @@ -2691,6 +2733,7 @@ class Societe extends CommonObject
     	 */
     	function get_codecompta($type)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		if (! empty($conf->global->SOCIETE_CODECOMPTA_ADDON))
    @@ -2731,6 +2774,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Define parent commany of current company
     	 *
    @@ -2739,6 +2783,7 @@ class Societe extends CommonObject
     	 */
     	function set_parent($id)
     	{
    +        // phpcs:enable
     		if ($this->id)
     		{
     			$sql = "UPDATE ".MAIN_DB_PREFIX."societe";
    @@ -2759,6 +2804,7 @@ class Societe extends CommonObject
     		else return -1;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Returns if a profid sould be verified
     	 *
    @@ -2767,6 +2813,7 @@ class Societe extends CommonObject
     	 */
     	function id_prof_verifiable($idprof)
     	{
    +        // phpcs:enable
     		global $conf;
     
     	 	switch($idprof)
    @@ -2796,6 +2843,7 @@ class Societe extends CommonObject
     		return $ret;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Verify if a profid exists into database for others thirds
     	 *
    @@ -2806,6 +2854,7 @@ class Societe extends CommonObject
     	 */
     	function id_prof_exists($idprof, $value, $socid=0)
     	{
    +        // phpcs:enable
     		$field = $idprof;
     
     	 	switch($idprof)	// For backward compatibility
    @@ -2854,6 +2903,7 @@ class Societe extends CommonObject
     		else return false;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Verifie la validite d'un identifiant professionnel en fonction du pays de la societe (siren, siret, ...)
     	 *
    @@ -2864,6 +2914,7 @@ class Societe extends CommonObject
     	 */
     	function id_prof_check($idprof,$soc)
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$ok=1;
    @@ -3003,6 +3054,7 @@ class Societe extends CommonObject
     		return $ok;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Return an url to check online a professional id or empty string
     	 *
    @@ -3013,6 +3065,7 @@ class Societe extends CommonObject
     	 */
     	function id_prof_url($idprof,$thirdparty)
     	{
    +        // phpcs:enable
     		global $conf,$langs,$hookmanager;
     
     		$url='';
    @@ -3055,6 +3108,7 @@ class Societe extends CommonObject
     		return '';
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *   Indique si la societe a des projets
     	 *
    @@ -3062,6 +3116,7 @@ class Societe extends CommonObject
     	 */
     	function has_projects()
     	{
    +        // phpcs:enable
     		$sql = 'SELECT COUNT(*) as numproj FROM '.MAIN_DB_PREFIX.'projet WHERE fk_soc = ' . $this->id;
     		$resql = $this->db->query($sql);
     		if ($resql)
    @@ -3119,7 +3174,6 @@ class Societe extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -3160,6 +3214,7 @@ class Societe extends CommonObject
     		return isInEEC($this);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Charge la liste des categories fournisseurs
     	 *
    @@ -3167,6 +3222,7 @@ class Societe extends CommonObject
     	 */
     	function LoadSupplierCateg()
     	{
    +        // phpcs:enable
     		$this->SupplierCategories = array();
     		$sql = "SELECT rowid, label";
     		$sql.= " FROM ".MAIN_DB_PREFIX."categorie";
    @@ -3187,6 +3243,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Insert link supplier - category
     	 *
    @@ -3195,6 +3252,7 @@ class Societe extends CommonObject
     	 */
     	function AddFournisseurInCategory($categorie_id)
     	{
    +        // phpcs:enable
     		if ($categorie_id > 0 && $this->id > 0)
     		{
     			$sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_fournisseur (fk_categorie, fk_soc) ";
    @@ -3210,6 +3268,7 @@ class Societe extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Create a third party into database from a member object
     	 *
    @@ -3220,6 +3279,7 @@ class Societe extends CommonObject
     	 */
     	function create_from_member(Adherent $member, $socname='', $socalias='')
     	{
    +        // phpcs:enable
     		global $user,$langs;
     
     		dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG);
    @@ -3241,6 +3301,8 @@ class Societe extends CommonObject
     		$this->phone=$member->phone;       // Prof phone
     		$this->email=$member->email;
     		$this->skype=$member->skype;
    +		$this->twitter=$member->twitter;
    +		$this->facebook=$member->facebook;
     
     		$this->client = 1;				// A member is a customer by default
     		$this->code_client = -1;
    @@ -3297,6 +3359,7 @@ class Societe extends CommonObject
     		$this->town=empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN;
     		$this->state_id=empty($conf->global->MAIN_INFO_SOCIETE_STATE)?'':$conf->global->MAIN_INFO_SOCIETE_STATE;
     		$this->region_code=empty($conf->global->MAIN_INFO_SOCIETE_REGION)?'':$conf->global->MAIN_INFO_SOCIETE_REGION;
    +		$this->object=empty($conf->global->MAIN_INFO_SOCIETE_OBJECT)?'':$conf->global->MAIN_INFO_SOCIETE_OBJECT;
     
     		$this->note_private=empty($conf->global->MAIN_INFO_SOCIETE_NOTE)?'':$conf->global->MAIN_INFO_SOCIETE_NOTE;
     
    @@ -3380,6 +3443,8 @@ class Societe extends CommonObject
     		$this->country_code='FR';
     		$this->email='specimen@specimen.com';
     		$this->skype='tom.hanson';
    +		$this->twitter='tomhanson';
    +		$this->facebook='tomhanson';
     		$this->url='http://www.specimen.com';
     
     		$this->phone='0909090901';
    @@ -3486,6 +3551,7 @@ class Societe extends CommonObject
     		return $this->LibProspLevel($this->fk_prospectlevel);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return label of prospect level
     	 *
    @@ -3494,6 +3560,7 @@ class Societe extends CommonObject
     	 */
     	function LibProspLevel($fk_prospectlevel)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		$lib=$langs->trans("ProspectLevel".$fk_prospectlevel);
    @@ -3506,6 +3573,7 @@ class Societe extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Set prospect level
     	 *
    @@ -3515,6 +3583,7 @@ class Societe extends CommonObject
     	 */
     	function set_prospect_level(User $user)
     	{
    +        // phpcs:enable
     		return $this->update($this->id, $user);
     	}
     
    @@ -3530,6 +3599,7 @@ class Societe extends CommonObject
     		return $this->LibProspCommStatut($this->stcomm_id, $mode, $label);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return label of a given status
     	 *
    @@ -3540,6 +3610,7 @@ class Societe extends CommonObject
     	 */
     	function LibProspCommStatut($statut, $mode=0, $label='')
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('customers');
     
    @@ -3583,6 +3654,7 @@ class Societe extends CommonObject
     		return "Error, mode/status not found";
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Set outstanding value
     	 *
    @@ -3592,6 +3664,7 @@ class Societe extends CommonObject
     	 */
     	function set_OutstandingBill(User $user)
     	{
    +        // phpcs:enable
     		return $this->update($this->id, $user);
     	}
     
    @@ -3748,6 +3821,7 @@ class Societe extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return amount of bill not paid
     	 *
    @@ -3756,6 +3830,7 @@ class Societe extends CommonObject
     	 */
     	function get_OutstandingBill()
     	{
    +        // phpcs:enable
     		/* Accurate value of remain to pay is to sum remaintopay for each invoice
     	     $paiement = $invoice->getSommePaiement();
     	     $creditnotes=$invoice->getSumCreditNotesUsed();
    @@ -3801,6 +3876,7 @@ class Societe extends CommonObject
     		return $this->LibCustProspStatut($this->client);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -3809,6 +3885,7 @@ class Societe extends CommonObject
     	 */
     	function LibCustProspStatut($statut)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('companies');
     
    @@ -3816,7 +3893,6 @@ class Societe extends CommonObject
     		if ($statut==1) return $langs->trans("Customer");
     		if ($statut==2) return $langs->trans("Prospect");
     		if ($statut==3) return $langs->trans("ProspectCustomer");
    -
     	}
     
     
    diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php
    index 7340a319534..78f934ecf2f 100644
    --- a/htdocs/societe/class/societeaccount.class.php
    +++ b/htdocs/societe/class/societeaccount.class.php
    @@ -39,14 +39,17 @@ class SocieteAccount extends CommonObject
     	 * @var string ID to identify managed object
     	 */
     	public $element = 'societeaccount';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'societe_account';
    +
     	/**
     	 * @var array  Does societeaccount support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 0;
    +
     	/**
     	 * @var string String with name of icon for societeaccount. Must be the part after the 'object_' into object_myobject.png
     	 */
    @@ -84,7 +87,7 @@ class SocieteAccount extends CommonObject
     		'pass_temp'    => array('type'=>'varchar(128)', 'label'=>'Temp', 'visible'=>0, 'enabled'=>0, 'position'=>32, 'notnull'=>-1,),
     		'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=>1, 'enabled'=>1, 'position'=>40, 'notnull'=>-1, 'index'=>1),
     		'site' => array('type'=>'varchar(128)', 'label'=>'Site', 'visible'=>-1, 'enabled'=>1, 'position'=>41),
    -		'fk_website' => array('type'=>'integer:Website:website/class/website.class.php', 'label'=>'WebSite', 'visible'=>1, 'enabled'=>1, 'position'=>42, 'notnull'=>1, 'index'=>1),
    +		'fk_website' => array('type'=>'integer:Website:website/class/website.class.php', 'label'=>'WebSite', 'visible'=>1, 'enabled'=>1, 'position'=>42, 'notnull'=>-1, 'index'=>1),
     		'date_last_login' => array('type'=>'datetime', 'label'=>'LastConnexion', 'visible'=>2, 'enabled'=>1, 'position'=>50, 'notnull'=>0,),
     		'date_previous_login' => array('type'=>'datetime', 'label'=>'PreviousConnexion', 'visible'=>2, 'enabled'=>1, 'position'=>51, 'notnull'=>0,),
     		//'note_public' => array('type'=>'text', 'label'=>'NotePublic', 'visible'=>-1, 'enabled'=>1, 'position'=>45, 'notnull'=>-1,),
    @@ -96,23 +99,52 @@ class SocieteAccount extends CommonObject
     		'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1, 'index'=>1,),
     		'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'default'=>1, 'arrayofkeyval'=>array('1'=>'Active','0'=>'Disabled')),
     	);
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    +
     	public $key_account;
    +	public $login;
     	public $pass_encoding;
     	public $pass_crypted;
     	public $pass_temp;
    -	public $fk_soc;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +    public $fk_soc;
    +
     	public $site;
     	public $date_last_login;
     	public $date_previous_login;
     	public $note_private;
     	public $date_creation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
     	public $import_key;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	// END MODULEBUILDER PROPERTIES
     
     
    @@ -256,8 +288,6 @@ class SocieteAccount extends CommonObject
     	 */
     	public function getCustomerAccount($id, $site, $status=0)
     	{
    -		global $conf;
    -
     		$sql = "SELECT sa.key_account as key_account, sa.entity";
     		$sql.= " FROM " . MAIN_DB_PREFIX . "societe_account as sa";
     		$sql.= " WHERE sa.fk_soc = " . $id;
    @@ -266,7 +296,7 @@ class SocieteAccount extends CommonObject
     		$sql.= " AND key_account IS NOT NULL AND key_account <> ''";
     		//$sql.= " ORDER BY sa.key_account DESC";
     
    -		dol_syslog(get_class($this) . "::getCustomerAccount Try to find the system customer id of thirdparty id=".$id." (exemple: cus_.... for stripe)", LOG_DEBUG);
    +		dol_syslog(get_class($this) . "::getCustomerAccount Try to find the first system customer id for ".$site." of thirdparty id=".$id." (exemple: cus_.... for stripe)", LOG_DEBUG);
     		$result = $this->db->query($sql);
     		if ($result) {
     			if ($this->db->num_rows($result)) {
    @@ -391,6 +421,7 @@ class SocieteAccount extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return the status
     	 *
    @@ -400,43 +431,44 @@ class SocieteAccount extends CommonObject
     	 */
     	static function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
     		{
     			$prefix='';
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    +			elseif ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
    -			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
    +			elseif ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 6)
    +		elseif ($mode == 6)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
    -			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    +			elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
     		}
     	}
     
    @@ -486,7 +518,6 @@ class SocieteAccount extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php
    index 4138bf0891c..3a3fb8507c9 100644
    --- a/htdocs/societe/consumption.php
    +++ b/htdocs/societe/consumption.php
    @@ -25,7 +25,7 @@
      *	\brief      Add a tab on thirpdarty view to list all products/services bought or sells by thirdparty
      */
     
    -require("../main.inc.php");
    +require "../main.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    @@ -554,7 +554,6 @@ if ($sql_select)
     				{
     					print (! empty($objp->description) && $objp->description!=$objp->product_label)?'<br>'.dol_htmlentitiesbr($objp->description):'';
     				}
    -
     			} else {
     
     				if (! empty($objp->label) || ! empty($objp->description))
    @@ -653,6 +652,6 @@ else {
     
     print "</form>";
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/contact.php b/htdocs/societe/contact.php
    index 37fb07eb652..24ec0026455 100644
    --- a/htdocs/societe/contact.php
    +++ b/htdocs/societe/contact.php
    @@ -171,8 +171,6 @@ if ($action != 'presend')
     	}
     }
     
    -
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/document.php b/htdocs/societe/document.php
    index e393fa64a2c..a9aae7a8654 100644
    --- a/htdocs/societe/document.php
    +++ b/htdocs/societe/document.php
    @@ -32,9 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     
    -$langs->load("companies");
    -$langs->load('other');
    -
    +$langs->loadLangs(array("companies", "other"));
     
     $action=GETPOST('action','aZ09');
     $confirm=GETPOST('confirm');
    @@ -105,7 +103,7 @@ if ($object->id)
     	dol_fiche_head($head, 'document', $langs->trans("ThirdParty"), -1, 'company');
     
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -169,6 +167,6 @@ else
     	accessforbidden('',0,0);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php
    index b15042dd017..0759008c435 100644
    --- a/htdocs/societe/index.php
    +++ b/htdocs/societe/index.php
    @@ -1,6 +1,6 @@
     <?php
     /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2014      Charles-Fr Benke	    <charles.fr@benke.fr>
      * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
    @@ -366,6 +366,6 @@ else
     //print '</td></tr></table>';
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php
    index 8ea73b73884..684f6f8c471 100644
    --- a/htdocs/societe/list.php
    +++ b/htdocs/societe/list.php
    @@ -84,10 +84,10 @@ $search_categ_cus=trim(GETPOST("search_categ_cus",'int'));
     $search_categ_sup=trim(GETPOST("search_categ_sup",'int'));
     $search_country=GETPOST("search_country",'intcomma');
     $search_type_thirdparty=GETPOST("search_type_thirdparty",'int');
    +$search_staff=GETPOST("search_staff",'int');
     $search_status=GETPOST("search_status",'int');
     $search_type=GETPOST('search_type','alpha');
    -$search_level_from = GETPOST("search_level_from","alpha");
    -$search_level_to   = GETPOST("search_level_to","alpha");
    +$search_level      = GETPOST("search_level", "array");
     $search_stcomm=GETPOST('search_stcomm','int');
     $search_import_key  = GETPOST("search_import_key","alpha");
     $search_btn=GETPOST('button_search','alpha');
    @@ -184,6 +184,7 @@ $arrayfields=array(
     	's.phone'=>array('label'=>"Phone", 'checked'=>1),
     	's.fax'=>array('label'=>"Fax", 'checked'=>0),
     	'typent.code'=>array('label'=>"ThirdPartyType", 'checked'=>$checkedtypetiers),
    +	'staff.code'=>array('label'=>"Staff", 'checked'=>0),
     	's.siren'=>array('label'=>"ProfId1Short", 'checked'=>$checkedprofid1),
     	's.siret'=>array('label'=>"ProfId2Short", 'checked'=>$checkedprofid2),
     	's.ape'=>array('label'=>"ProfId3Short", 'checked'=>$checkedprofid3),
    @@ -258,10 +259,10 @@ if (empty($reshook))
     		$search_vat='';
     		$search_type='';
     		$search_type_thirdparty='';
    +		$search_staff='';
     		$search_status=-1;
     		$search_stcomm='';
    -	 	$search_level_from='';
    -	 	$search_level_to='';
    +	 	$search_level='';
     	 	$search_import_key='';
     	 	$toselect='';
     		$search_array_options=array();
    @@ -318,80 +319,22 @@ if ($type == 'c' && (empty($search_type) || ($search_type == '1,3'))) $title=$la
     if ($type == 'p' && (empty($search_type) || ($search_type == '2,3'))) $title=$langs->trans("ListOfProspects");
     if ($type == 'f' && (empty($search_type) || ($search_type == '4'))) $title=$langs->trans("ListOfSuppliers");
     
    -// If both parameters are set, search for everything BETWEEN them
    -if ($search_level_from != '' && $search_level_to != '')
    -{
    -	// Ensure that these parameters are numbers
    -	$search_level_from = (int) $search_level_from;
    -	$search_level_to = (int) $search_level_to;
    -
    -	// If from is greater than to, reverse orders
    -	if ($search_level_from > $search_level_to)
    -	{
    -		$tmp = $search_level_to;
    -		$search_level_to = $search_level_from;
    -		$search_level_from = $tmp;
    -	}
    -
    -	// Generate the SQL request
    -	$sortwhere = '(sortorder BETWEEN '.$search_level_from.' AND '.$search_level_to.') AS is_in_range';
    -}
    -// If only "from" parameter is set, search for everything GREATER THAN it
    -else if ($search_level_from != '')
    -{
    -	// Ensure that this parameter is a number
    -	$search_level_from = (int) $search_level_from;
    -
    -	// Generate the SQL request
    -	$sortwhere = '(sortorder >= '.$search_level_from.') AS is_in_range';
    -}
    -// If only "to" parameter is set, search for everything LOWER THAN it
    -else if ($search_level_to != '')
    -{
    -	// Ensure that this parameter is a number
    -	$search_level_to = (int) $search_level_to;
    -
    -	// Generate the SQL request
    -	$sortwhere = '(sortorder <= '.$search_level_to.') AS is_in_range';
    -}
    -// If no parameters are set, dont search for anything
    -else
    -{
    -	$sortwhere = '0 as is_in_range';
    -}
    -
     // Select every potentiels, and note each potentiels which fit in search parameters
    -dol_syslog('societe/list.php',LOG_DEBUG);
    -$sql = "SELECT code, label, sortorder, ".$sortwhere;
    +$tab_level = array();
    +$sql = "SELECT code, label, sortorder";
     $sql.= " FROM ".MAIN_DB_PREFIX."c_prospectlevel";
     $sql.= " WHERE active > 0";
     $sql.= " ORDER BY sortorder";
    -
     $resql = $db->query($sql);
     if ($resql)
     {
    -	$tab_level = array();
    -	$search_levels = array();
    -
     	while ($obj = $db->fetch_object($resql))
     	{
     		// Compute level text
     		$level=$langs->trans($obj->code);
     		if ($level == $obj->code) $level=$langs->trans($obj->label);
    -
    -		// Put it in the array sorted by sortorder
    -		$tab_level[$obj->sortorder] = $level;
    -
    -		// If this potentiel fit in parameters, add its code to the $search_levels array
    -		if ($obj->is_in_range == 1)
    -		{
    -			$search_levels[] = '"'.preg_replace('[^A-Za-z0-9_-]', '', $obj->code).'"';
    -		}
    +		$tab_level[$obj->code] = $level;
     	}
    -
    -	// Implode the $search_levels array so that it can be use in a "IN (...)" where clause.
    -	// If no paramters was set, $search_levels will be empty
    -	$search_levels = implode(',', $search_levels);
     }
     else dol_print_error($db);
     
    @@ -401,6 +344,7 @@ $sql.= " s.email, s.phone, s.fax, s.url, s.siren as idprof1, s.siret as idprof2,
     $sql.= " s.tms as date_update, s.datec as date_creation,";
     $sql.= " s.code_compta,s.code_compta_fournisseur,";
     $sql.= " typent.code as typent_code,";
    +$sql.= " staff.code as staff_code,";
     $sql.= " country.code as country_code,";
     $sql.= " state.code_departement as state_code, state.nom as state_name,";
     $sql.= " region.code_region as region_code, region.nom as region_name";
    @@ -419,6 +363,7 @@ $sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
     if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields as ef on (s.rowid = ef.fk_object)";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)";
    +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_effectif as staff on (staff.id = s.fk_effectif)";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as region on (region.	code_region = state.fk_region)";
     // We'll need this table joined to the select in order to filter by categ
    @@ -452,8 +397,8 @@ if ($search_account_supplier_code) $sql.= natural_search("s.code_compta_fourniss
     if ($search_town)          $sql.= natural_search("s.town",$search_town);
     if (strlen($search_zip))   $sql.= natural_search("s.zip",$search_zip);
     if ($search_state)         $sql.= natural_search("state.nom",$search_state);
    -if ($search_region)         $sql.= natural_search("region.nom",$search_region);
    -if ($search_country)       $sql .= " AND s.fk_pays IN (".$search_country.')';
    +if ($search_region)        $sql.= natural_search("region.nom",$search_region);
    +if ($search_country && $search_country != '-1')       $sql .= " AND s.fk_pays IN (".$db->escape($search_country).')';
     if ($search_email)         $sql.= natural_search("s.email",$search_email);
     if (strlen($search_phone)) $sql.= natural_search("s.phone", $search_phone);
     if (strlen($search_fax)) $sql.= natural_search("s.phone", $search_fax);
    @@ -469,11 +414,12 @@ if (strlen($search_vat))     $sql.= natural_search("s.tva_intra",$search_vat);
     if ($search_type > 0 && in_array($search_type,array('1,3','2,3'))) $sql .= " AND s.client IN (".$db->escape($search_type).")";
     if ($search_type > 0 && in_array($search_type,array('4')))         $sql .= " AND s.fournisseur = 1";
     if ($search_type == '0') $sql .= " AND s.client = 0 AND s.fournisseur = 0";
    -if ($search_status!='' && $search_status >= 0) $sql .= " AND s.status = ".$db->escape($search_status);
    +if ($search_status!='' && $search_status >= 0) $sql .= natural_search("s.status", $search_status, 2);
     if (!empty($conf->barcode->enabled) && $search_barcode) $sql.= natural_search("s.barcode", $search_barcode);
    -if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')';
    -if ($search_levels)  $sql .= " AND s.fk_prospectlevel IN (".$search_levels.')';
    -if ($search_stcomm != '' && $search_stcomm != -2) $sql.= natural_search("s.fk_stcomm",$search_stcomm,2);
    +if ($search_type_thirdparty && $search_type_thirdparty != '-1') $sql.= natural_search("s.fk_typent", $search_type_thirdparty, 2);
    +if (! empty($search_staff) && $search_staff != '-1')            $sql.= natural_search("s.fk_effectif", $search_staff, 2);
    +if ($search_level)  $sql .= natural_search("s.fk_prospectlevel", join(',', $search_level), 3);
    +if ($search_stcomm != '' && $search_stcomm != -2) $sql.= natural_search("s.fk_stcomm", $search_stcomm, 2);
     if ($search_import_key)    $sql.= natural_search("s.import_key",$search_import_key);
     // Add where from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
    @@ -566,13 +512,12 @@ if ($search_idprof6 != '') $param.= '&search_idprof6='.urlencode($search_idprof6
     if ($search_vat != '')     $param.= '&search_vat='.urlencode($search_vat);
     if ($search_type_thirdparty != '')    $param.='&search_type_thirdparty='.urlencode($search_type_thirdparty);
     if ($search_type != '')    $param.='&search_type='.urlencode($search_type);
    -if ($optioncss != '')      $param.='&optioncss='.urlencode($optioncss);
    +if (is_array($search_level) && count($search_level)) foreach($search_level as $slevel) $param.='&search_level[]='.urlencode($slevel);
     if ($search_status != '')  $param.='&search_status='.urlencode($search_status);
     if ($search_stcomm != '')  $param.='&search_stcomm='.urlencode($search_stcomm);
    -if ($search_level_from != '') $param.='&search_level_from='.urlencode($search_level_from);
    -if ($search_level_to != '')   $param.='&search_level_to='.urlencode($search_level_to);
     if ($search_import_key != '') $param.='&search_import_key='.urlencode($search_import_key);
     if ($type != '') $param.='&type='.urlencode($type);
    +if ($optioncss != '')      $param.='&optioncss='.urlencode($optioncss);
     // Add $param from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
     
    @@ -589,7 +534,7 @@ $arrayofmassactions =  array(
     );
     //if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
     if ($user->rights->societe->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete");
    -if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
    +if (GETPOST('nomassaction','int') || in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
     $massactionbutton=$form->selectMassAction('', $arrayofmassactions);
     
     $newcardbutton='';
    @@ -611,7 +556,7 @@ if ($user->rights->societe->creer)
     	$newcardbutton.= '</a>';
     }
     
    -print '<form method="post" action="'.$_SERVER["PHP_SELF"].'" name="formfilter" autocomplete="off">';
    +print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'" name="formfilter" autocomplete="off">';
     if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
     print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
     print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    @@ -796,6 +741,13 @@ if (! empty($arrayfields['typent.code']['checked']))
     	print $form->selectarray("search_type_thirdparty", $formcompany->typent_array(0), $search_type_thirdparty, 0, 0, 0, '', 0, 0, 0, (empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT));
     	print '</td>';
     }
    +// Staff
    +if (! empty($arrayfields['staff.code']['checked']))
    +{
    +	print '<td class="liste_titre maxwidthonsmartphone" align="center">';
    +	print $form->selectarray("search_staff", $formcompany->effectif_array(0), $search_staff, 0, 0, 0, '', 0, 0, 0, $sort, 'maxwidth100');
    +	print '</td>';
    +}
     if (! empty($arrayfields['s.email']['checked']))
     {
     	// Email
    @@ -888,37 +840,16 @@ if (! empty($arrayfields['customerorsupplier']['checked']))
     	print '<option value="0"'.($search_type=='0'?' selected':'').'>'.$langs->trans('Others').'</option>';
     	print '</select></td>';
     }
    +// Prospect level
     if (! empty($arrayfields['s.fk_prospectlevel']['checked']))
     {
    -	// Prospect level
      	print '<td class="liste_titre" align="center">';
    - 	$options_from = '<option value="">&nbsp;</option>';	 	// Generate in $options_from the list of each option sorted
    - 	foreach ($tab_level as $tab_level_sortorder => $tab_level_label)
    - 	{
    - 		$options_from .= '<option value="'.$tab_level_sortorder.'"'.($search_level_from == $tab_level_sortorder ? ' selected':'').'>';
    - 		$options_from .= $langs->trans($tab_level_label);
    - 		$options_from .= '</option>';
    - 	}
    - 	array_reverse($tab_level, true);	// Reverse the list
    - 	$options_to = '<option value="">&nbsp;</option>';		// Generate in $options_to the list of each option sorted in the reversed order
    - 	foreach ($tab_level as $tab_level_sortorder => $tab_level_label)
    - 	{
    - 		$options_to .= '<option value="'.$tab_level_sortorder.'"'.($search_level_to == $tab_level_sortorder ? ' selected':'').'>';
    - 		$options_to .= $langs->trans($tab_level_label);
    - 		$options_to .= '</option>';
    - 	}
    -
    -	// Print these two select
    - 	print $langs->trans("From").' <select class="flat" name="search_level_from">'.$options_from.'</select>';
    - 	print ' ';
    - 	print $langs->trans("to").' <select class="flat" name="search_level_to">'.$options_to.'</select>';
    -
    + 	print $form->multiselectarray('search_level', $tab_level, $search_level, 0, 0, 'width75', 0, 0, '', '', '', 2);
     	print '</td>';
     }
    -
    +// Prospect status
     if (! empty($arrayfields['s.fk_stcomm']['checked']))
     {
    -	// Prospect status
     	print '<td class="liste_titre maxwidthonsmartphone" align="center">';
     	$arraystcomm=array();
     	foreach($prospectstatic->cacheprospectstatus as $key => $val)
    @@ -950,7 +881,7 @@ if (! empty($arrayfields['s.tms']['checked']))
     // Status
     if (! empty($arrayfields['s.status']['checked']))
     {
    -	print '<td class="liste_titre maxwidthonsmartphone center">';
    +	print '<td class="liste_titre center minwidth75imp">';
     	print $form->selectarray('search_status', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')), $search_status, 1);
     	print '</td>';
     }
    @@ -983,6 +914,7 @@ if (! empty($arrayfields['state.nom']['checked']))        print_liste_field_titr
     if (! empty($arrayfields['region.nom']['checked']))       print_liste_field_titre($arrayfields['region.nom']['label'],$_SERVER["PHP_SELF"],"region.nom","",$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder);
     if (! empty($arrayfields['typent.code']['checked']))      print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder);
    +if (! empty($arrayfields['staff.code']['checked']))       print_liste_field_titre($arrayfields['staff.code']['label'],$_SERVER["PHP_SELF"],"staff.code","",$param,'align="center"',$sortfield,$sortorder);
     if (! empty($arrayfields['s.email']['checked']))          print_liste_field_titre($arrayfields['s.email']['label'],$_SERVER["PHP_SELF"],"s.email","",$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['s.phone']['checked']))          print_liste_field_titre($arrayfields['s.phone']['label'],$_SERVER["PHP_SELF"],"s.phone","",$param,'',$sortfield,$sortorder);
     if (! empty($arrayfields['s.fax']['checked'])) print_liste_field_titre($arrayfields['s.fax']['label'],$_SERVER["PHP_SELF"],"s.fax","",$param,'',$sortfield,$sortorder);
    @@ -1068,13 +1000,13 @@ while ($i < min($num, $limit))
     	// Customer code
     	if (! empty($arrayfields['s.code_client']['checked']))
     	{
    -		print '<td>'.$obj->code_client.'</td>';
    +		print '<td class="nowraponall">'.$obj->code_client.'</td>';
     		if (! $i) $totalarray['nbfield']++;
     	}
     	// Supplier code
     	if (! empty($arrayfields['s.code_fournisseur']['checked']))
     	{
    -		print '<td>'.$obj->code_fournisseur.'</td>';
    +		print '<td class="nowraponall">'.$obj->code_fournisseur.'</td>';
     		if (! $i) $totalarray['nbfield']++;
     	}
     	// Account customer code
    @@ -1131,6 +1063,15 @@ while ($i < min($num, $limit))
     		print '</td>';
     		if (! $i) $totalarray['nbfield']++;
     	}
    +	// Staff
    +	if (! empty($arrayfields['staff.code']['checked']))
    +	{
    +		print '<td align="center">';
    +		if (! is_array($staffArray) || count($staffArray)==0) $staffArray = $formcompany->effectif_array(1);
    +		print $staffArray[$obj->staff_code];
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
     	if (! empty($arrayfields['s.email']['checked']))
     	{
     		print "<td>".$obj->email."</td>\n";
    @@ -1302,5 +1243,6 @@ print "</div>";
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php
    index e31a07e8e65..169d2b687e9 100644
    --- a/htdocs/societe/note.php
    +++ b/htdocs/societe/note.php
    @@ -129,6 +129,7 @@ else
     	print $langs->trans("ErrorRecordNotFound");
     }
     
    +// End of page
     llxFooter();
     $db->close();
     
    diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php
    index cd8212ae327..b5de5c77456 100644
    --- a/htdocs/societe/notify/card.php
    +++ b/htdocs/societe/notify/card.php
    @@ -30,10 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/triggers/interface_50_modNotification_Notification.class.php';
     
    -$langs->load("companies");
    -$langs->load("mails");
    -$langs->load("admin");
    -$langs->load("other");
    +$langs->loadLangs(array("companies", "mails", "admin", "other"));
     
     $socid = GETPOST("socid",'int');
     $action = GETPOST('action','aZ09');
    @@ -532,7 +529,6 @@ if ($result > 0)
     }
     else dol_print_error('','RecordNotFound');
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/notify/index.php b/htdocs/societe/notify/index.php
    index 3326e431178..129131ff5c6 100644
    --- a/htdocs/societe/notify/index.php
    +++ b/htdocs/societe/notify/index.php
    @@ -23,8 +23,7 @@
      */
     
     require '../../main.inc.php';
    -$langs->load("companies");
    -$langs->load("banks");
    +$langs->loadLangs(array("companies", "banks"));
     
     // S�curit� acc�s client
     if ($user->societe_id > 0)
    @@ -105,6 +104,6 @@ else
     	dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php
    index aabc9ae7bed..13fdf048382 100644
    --- a/htdocs/societe/paymentmodes.php
    +++ b/htdocs/societe/paymentmodes.php
    @@ -557,7 +557,7 @@ if (empty($reshook))
     			$sql.= " SET key_account = '".$db->escape(GETPOST('key_account', 'alpha'))."'";
     			$sql.= " WHERE site = 'stripe' AND fk_soc = ".$object->id." AND status = ".$servicestatus." AND entity = ".$conf->entity;	// Keep = here for entity. Only 1 record must be modified !
                     }
    -     
    +
     			$resql = $db->query($sql);
     			$num = $db->num_rows($resql);
     			if (empty($num) && !empty($newcu))
    @@ -764,10 +764,11 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     		print $form->editfieldval("StripeCustomerId", 'key_account', $stripecu, $object, $permissiontowrite, 'string', '', null, null, '', 2, '', 'socid');
     		if ($stripecu && $action != 'editkey_account')
     		{
    -			$url='https://dashboard.stripe.com/test/customers/'.$stripecu;
    +			if (! empty($conf->stripe->enabled) && !empty($stripeacc)) $connect=$stripeacc.'/';
    +			$url='https://dashboard.stripe.com/'.$connect.'test/customers/'.$stripecu;
     			if ($servicestatus)
     			{
    -				$url='https://dashboard.stripe.com/customers/'.$stripecu;
    +				$url='https://dashboard.stripe.com/'.$connect.'customers/'.$stripecu;
     			}
     			print ' <a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'object_globe').'</a>';
     		}
    @@ -830,7 +831,9 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     		print '<td></td>';
     		print '<td align="center">'.$langs->trans('Default').'</td>';
     		print '<td>'.$langs->trans('Note').'</td>';
    -		print "<td></td></tr>\n";
    +		print '<td>'.$langs->trans('DateModification').'</td>';
    +		print "<td></td>";
    +		print "</tr>\n";
     
     		$nbremote = 0;
     		$nblocal = 0;
    @@ -911,6 +914,9 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     							if (empty($companypaymentmodetemp->stripe_card_ref)) print $langs->trans("Local");
     							else print $langs->trans("LocalAndRemote");
     							print '</td>';
    +							print '<td>';
    +							print dol_print_date($companypaymentmodetemp->tms, 'dayhour');
    +							print '</td>';
     							print '<td align="right" class="nowraponall">';
     							if ($user->rights->societe->creer)
     							{
    @@ -953,9 +959,17 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     					print '<td>';
     					print '</td>';
     				}
    +				// Src ID
     				print '<td>';
    -				print $src->id;
    +				if (!empty($stripeacc)) $connect=$stripeacc.'/';
    +				$url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
    +				if ($servicestatus)
    +				{
    +					$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
    +				}
    +				print $src->id." <a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')."</a>";
     				print '</td>';
    +				// Img of credit card
     				print '<td>';
     				if ($src->object=='card')
     				{
    @@ -969,8 +983,8 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     				{
     					print '<span class="fa fa-university fa-2x fa-fw"></span>';
     				}
    -
    -				print'</td><td valign="middle">';
    +				print'</td>';
    +				print '<td valign="middle">';
     				if ($src->object=='card')
     				{
     					print '....'.$src->last4.' - '.$src->exp_month.'/'.$src->exp_year.'';
    @@ -1022,6 +1036,11 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     				print '</td>';
     				print '<td>';
     				print $langs->trans("Remote");
    +				//if ($src->cvc_check == 'fail') print ' - CVC check fail';
    +				print '</td>';
    +				print '<td>';
    +				//var_dump($src);
    +				print '';
     				print '</td>';
     				print '<td align="right" class="nowraponall">';
     				if ($user->rights->societe->creer)
    @@ -1188,7 +1207,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     					$formadmin=new FormAdmin($db);
     					$defaultlang=$codelang?$codelang:$langs->getDefaultLang();
     					$morecss='maxwidth150';
    -					if (! empty($conf->browser->phone)) $morecss='maxwidth100';
    +					if ($conf->browser->layout == 'phone') $morecss='maxwidth100';
     					$out.= $formadmin->select_language($defaultlang, 'lang_idrib'.$rib->id, 0, 0, 0, 0, 0, $morecss);
     				}
     				// Button
    @@ -1614,7 +1633,6 @@ if ($socid && ($action == 'create' || $action == 'createcard') && $user->rights-
     	print '</form>';
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php
    index e35cf186ae3..a9b280a3f47 100644
    --- a/htdocs/societe/price.php
    +++ b/htdocs/societe/price.php
    @@ -38,9 +38,7 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
     	$prodcustprice = new Productcustomerprice($db);
     }
     
    -$langs->load("products");
    -$langs->load("companies");
    -$langs->load("bills");
    +$langs->loadLangs(array("products", "companies", "bills"));
     
     $action = GETPOST('action', 'alpha');
     $search_prod = GETPOST('search_prod','alpha');
    @@ -611,10 +609,9 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
             print "</table>";
     
             print "</form>";
    -
     	}
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/project.php b/htdocs/societe/project.php
    index 08e2f593acb..f92d274fe46 100644
    --- a/htdocs/societe/project.php
    +++ b/htdocs/societe/project.php
    @@ -31,8 +31,7 @@ require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
     require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     
    -$langs->load("companies");
    -$langs->load("projects");
    +$langs->loadLangs(array("companies", "projects"));
     
     // Security check
     $socid = GETPOST('socid','int');
    @@ -147,7 +146,6 @@ if ($socid)
     	$result=show_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?socid='.$object->id, 1, $addbutton);
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/societe/societecontact.php b/htdocs/societe/societecontact.php
    index dfe78041f8a..edfa2f28d5c 100644
    --- a/htdocs/societe/societecontact.php
    +++ b/htdocs/societe/societecontact.php
    @@ -32,8 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
     
    -$langs->load("orders");
    -$langs->load("companies");
    +$langs->loadLangs(array("orders", "companies"));
     
     $id=GETPOST('id','int')?GETPOST('id','int'):GETPOST('socid','int');
     $ref=GETPOST('ref','alpha');
    @@ -343,5 +342,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/societe/website.php b/htdocs/societe/website.php
    index 3563283ba05..760bfef4d27 100644
    --- a/htdocs/societe/website.php
    +++ b/htdocs/societe/website.php
    @@ -535,7 +535,7 @@ if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nb
     	$hidegeneratedfilelistifempty=1;
     	if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty=0;
     
    -	require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     	$formfile = new FormFile($db);
     
     	// Show list of available documents
    @@ -549,8 +549,6 @@ if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nb
     	print $formfile->showdocuments('massfilesarea_mymodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'','','',null,$hidegeneratedfilelistifempty);
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/stripe/admin/stripe.php b/htdocs/stripe/admin/stripe.php
    index bd95baecd08..6a4dd8713f7 100644
    --- a/htdocs/stripe/admin/stripe.php
    +++ b/htdocs/stripe/admin/stripe.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2017		Olivier Geffroy			<jeff@jeffinfo.com>
      * Copyright (C) 2017		Saasprov				<saasprov@gmail.com>
      * Copyright (C) 2018		ptibogxiv				<support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -70,10 +71,14 @@ if ($action == 'setvalue' && $user->admin)
     	$result = dolibarr_set_const($db, "STRIPE_BANK_ACCOUNT_FOR_PAYMENTS", GETPOST('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 'int'), 'chaine', 0, '', $conf->entity);
     	if (! $result > 0)
     		$error ++;
    -	$result = dolibarr_set_const($db, "STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS", GETPOST('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 'int'), 'chaine', 0, '', $conf->entity);
    +    $result = dolibarr_set_const($db, "STRIPE_USER_ACCOUNT_FOR_ACTIONS", GETPOST('STRIPE_USER_ACCOUNT_FOR_ACTIONS', 'int'), 'chaine', 0, '', $conf->entity);
    +    if (! $result > 0) {
    +        $error ++;
    +    }
    +    $result = dolibarr_set_const($db, "STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS", GETPOST('STRIPE_BANK_ACCOUNT_FOR_BANKTRANSFERS', 'int'), 'chaine', 0, '', $conf->entity);
     	if (! $result > 0)
     		$error ++;
    -  $result = dolibarr_set_const($db, "STRIPE_MINIMAL_3DSECURE", GETPOST('STRIPE_MINIMAL_3DSECURE', 'int'), 'chaine', 0, '', $conf->entity);
    +    $result = dolibarr_set_const($db, "STRIPE_MINIMAL_3DSECURE", GETPOST('STRIPE_MINIMAL_3DSECURE', 'int'), 'chaine', 0, '', $conf->entity);
     	if (! $result > 0)
     		$error ++;
     	$result = dolibarr_set_const($db, "ONLINE_PAYMENT_CSS_URL", GETPOST('ONLINE_PAYMENT_CSS_URL', 'alpha'), 'chaine', 0, '', $conf->entity);
    @@ -116,10 +121,8 @@ if ($action == 'setvalue' && $user->admin)
     if ($action=="setlive")
     {
     	$liveenable = GETPOST('value','int');
    -	$res = dolibarr_set_const($db, "STRIPE_LIVE", $liveenable,'yesno',0,'',$conf->entity);
    -	if (! $res > 0) $error++;
    -	if (! $error)
    -	{
    +	$res = dolibarr_set_const($db, "STRIPE_LIVE", $liveenable, 'yesno', 0, '', $conf->entity);
    +	if ($res > 0) {
     		setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
     	}
     	else
    @@ -251,6 +254,11 @@ print '<input size="64" type="text" name="ONLINE_PAYMENT_CREDITOR" value="'.$con
     print ' &nbsp; '.$langs->trans("Example").': '.$mysoc->name;
     print '</td></tr>';
     
    +print '<tr class="oddeven"><td>';
    +print $langs->trans("StripeUserAccountForActions").'</td><td>';
    +print $form->select_dolusers($conf->global->STRIPE_USER_ACCOUNT_FOR_ACTIONS, 'STRIPE_USER_ACCOUNT_FOR_ACTIONS', 0);
    +print '</td></tr>';
    +
     print '<tr class="oddeven"><td>';
     print $langs->trans("BankAccount").'</td><td>';
     print $form->select_comptes($conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS, 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS', 0, '', 1);
    @@ -354,7 +362,6 @@ if (! empty($conf->use_javascript_ajax))
     	print '</script>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    -
    diff --git a/htdocs/stripe/charge.php b/htdocs/stripe/charge.php
    index 1464c9c2e6b..73c1f7b86c8 100644
    --- a/htdocs/stripe/charge.php
    +++ b/htdocs/stripe/charge.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2018 	PtibogXIV        <support@ptibogxiv.net>
    +/* Copyright (C) 2018 	Thibault FOUCART        <support@ptibogxiv.net>
      *
      * 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
    @@ -62,14 +62,16 @@ llxHeader('', $langs->trans("StripeChargeList"));
     if (! empty($conf->stripe->enabled) && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox','alpha')))
     {
     	$service = 'StripeTest';
    +	$servicestatus = '0';
     	dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
     }
     else
     {
     	$service = 'StripeLive';
    +	$servicestatus = '1';
     }
     
    -$stripeaccount = $stripe->getStripeAccount($service);
    +$stripeacc = $stripe->getStripeAccount($service);
     /*if (empty($stripeaccount))
     {
     	print $langs->trans('ErrorStripeAccountNotDefined');
    @@ -77,24 +79,24 @@ $stripeaccount = $stripe->getStripeAccount($service);
     
     if (!$rowid)
     {
    -	print '<FORM method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    -    if ($optioncss != '') print '<INPUT type="hidden" name="optioncss" value="'.$optioncss.'">';
    -    print '<INPUT type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    -	print '<INPUT type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    -    print '<INPUT type="hidden" name="action" value="list">';
    -    print '<INPUT type="hidden" name="sortfield" value="'.$sortfield.'">';
    -    print '<INPUT type="hidden" name="sortorder" value="'.$sortorder.'">';
    -    print '<INPUT type="hidden" name="page" value="'.$page.'">';
    +	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    +    if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
    +    print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +	print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    +    print '<input type="hidden" name="action" value="list">';
    +    print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
    +    print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
    +    print '<input type="hidden" name="page" value="'.$page.'">';
     
         $title=$langs->trans("StripeChargeList");
    -    $title.=($stripeaccount?' (Stripe connection with Stripe OAuth Connect account '.$stripeaccount.')':' (Stripe connection with keys from Stripe module setup)');
    +    $title.=($stripeacc?' (Stripe connection with Stripe OAuth Connect account '.$stripeacc.')':' (Stripe connection with keys from Stripe module setup)');
     
     	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, $totalnboflines, 'title_accountancy.png', 0, '', '', $limit);
     
    -    print '<DIV class="div-table-responsive">';
    -    print '<TABLE class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
    +    print '<div class="div-table-responsive">';
    +    print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
     
    -    print '<TR class="liste_titre">';
    +    print '<tr class="liste_titre">';
         print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
         print_liste_field_titre("StripeCustomerId",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
         print_liste_field_titre("Customer",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
    @@ -103,13 +105,13 @@ if (!$rowid)
         print_liste_field_titre("Type",$_SERVER["PHP_SELF"],"","","",'align="left"',$sortfield,$sortorder);
         print_liste_field_titre("Paid",$_SERVER["PHP_SELF"],"","","",'align="right"',$sortfield,$sortorder);
         print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"","","",'align="right"');
    -    print "</TR>\n";
    +    print "</tr>\n";
     
    -	print "</TR>\n";
    +	print "</tr>\n";
     
    -	if ($stripeaccount)
    +	if ($stripeacc)
     	{
    -		$list=\Stripe\Charge::all(array("limit" => $limit), array("stripe_account" => $stripeaccount));
    +		$list=\Stripe\Charge::all(array("limit" => $limit), array("stripe_account" => $stripeacc));
     	}
     	else
     	{
    @@ -125,15 +127,19 @@ if (!$rowid)
     		// Save into $tmparray all metadata
     		$tmparray = dolExplodeIntoArray($FULLTAG,'.','=');
     		// Load origin object according to metadata
    -		if (! empty($tmparray['CUS']))
    +		if (! empty($tmparray['CUS']) && $tmparray['CUS'] > 0)
     		{
     			$societestatic->fetch($tmparray['CUS']);
     		}
    +		elseif (! empty($charge->metadata->dol_thirdparty_id) && $charge->metadata->dol_thirdparty_id > 0)
    +		{
    +			$societestatic->fetch($charge->metadata->dol_thirdparty_id);
    +		}
     		else
     		{
     			$societestatic->id = 0;
     		}
    -		if (! empty($tmparray['MEM']))
    +		if (! empty($tmparray['MEM']) && $tmparray['MEM'] > 0)
     		{
     			$memberstatic->fetch($tmparray['MEM']);
     		}
    @@ -142,39 +148,60 @@ if (!$rowid)
     			$memberstatic->id = 0;
     		}
     
    -	    print '<TR class="oddeven">';
    -	    // Ref
    -		print "<TD><A href='".DOL_URL_ROOT."/stripe/charge.php?rowid=".$charge->id."'>".$charge->id."</A></TD>\n";
    +		print '<tr class="oddeven">';
    +    
    +    if (!empty($stripeacc)) $connect=$stripeacc.'/';
    +    
    +		// Ref
    +		$url='https://dashboard.stripe.com/'.$connect.'test/payments/'.$charge->id;
    +			if ($servicestatus)
    +			{
    +				$url='https://dashboard.stripe.com/'.$connect.'payments/'.$charge->id;
    +			}
    +		print "<td><a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')." ".$charge->id."</a></td>\n";
     		// Stripe customer
    -		print "<TD>".$charge->customer."</TD>\n";
    +		print "<td>";
    +
    +    if (! empty($conf->stripe->enabled) && !empty($stripeacc)) $connect=$stripeacc.'/';
    +		$url='https://dashboard.stripe.com/'.$connect.'test/customers/'.$charge->customer;
    +		if ($servicestatus)
    +		{
    +    $url='https://dashboard.stripe.com/'.$connect.'customers/'.$charge->customer;
    +		}
    +		print '<a href="'.$url.'" target="_stripe">'.img_picto($langs->trans('ShowInStripe'), 'object_globe').' '.$charge->customer.'</a>';
    +  
    +    print "</td>\n";
     		// Link
    -		print "<TD>";
    +		print "<td>";
     		if ($societestatic->id > 0)
     		{
     			print $societestatic->getNomUrl(1);
     		}
    -		if ($memberstatic->id > 0)
    +		elseif ($memberstatic->id > 0)
     		{
     			print $memberstatic->getNomUrl(1);
     		}
    -		print "</TD>\n";
    +		print "</td>\n";
     		// Origine
    -		print "<TD>";
    -		print $FULLTAG;
    -		if ($charge->metadata->source=="order"){
    +		print "<td>";
    +		if ($charge->metadata->dol_type=="order"){
     			$object = new Commande($db);
    -			$object->fetch($charge->metadata->idsource);
    -			print "<A href='".DOL_URL_ROOT."/commande/card.php?id=".$charge->metadata->idsource."'>".img_picto('', 'object_order')." ".$object->ref."</A>";
    -		} elseif ($charge->metadata->source=="invoice"){
    +			$object->fetch($charge->metadata->dol_id);
    +      if ($object->id > 0) {
    +			print "<a href='".DOL_URL_ROOT."/commande/card.php?id=".$object->id."'>".img_picto('', 'object_order')." ".$object->ref."</a>";
    +      } else print $FULLTAG;
    +		} elseif ($charge->metadata->dol_type=="invoice"){
     			$object = new Facture($db);
    -			$object->fetch($charge->metadata->idsource);
    -		    print "<A href='".DOL_URL_ROOT."/compta/facture/card.php?facid=".$charge->metadata->idsource."'>".img_picto('', 'object_invoice')." ".$object->ref."</A>";
    -		}
    -	    print "</TD>\n";
    +			$object->fetch($charge->metadata->dol_id);
    +      if ($object->id > 0) {
    +		  print "<a href='".DOL_URL_ROOT."/compta/facture/card.php?facid=".$charge->metadata->dol_id."'>".img_picto('', 'object_invoice')." ".$object->ref."</a>";
    +      } else print $FULLTAG;
    +		} else print $FULLTAG;
    +	    print "</td>\n";
     		// Date payment
    -	    print '<TD align="center">'.dol_print_date($charge->created,'%d/%m/%Y %H:%M')."</TD>\n";
    +	    print '<td align="center">'.dol_print_date($charge->created,'%d/%m/%Y %H:%M')."</td>\n";
     	    // Type
    -	    print '<TD>';
    +	    print '<td>';
     		if ($charge->source->object=='card')
     		{
     		    print $langs->trans("card");
    @@ -184,28 +211,30 @@ if (!$rowid)
     		} elseif ($charge->source->type=='three_d_secure'){
     		    print $langs->trans("card3DS");
     		}
    -	    print '</TD>';
    +	    print '</td>';
     	    // Amount
    -	    print "<TD align=\"right\">".price(($charge->amount-$charge->amount_refunded)/100)."</TD>";
    +	    print "<td align=\"right\">".price(($charge->amount-$charge->amount_refunded)/100, 0, '', 1, - 1, - 1, strtoupper($charge->currency))."</td>";
     	    // Status
    -	    print '<TD align="right">';
    +	    print '<td align="right">';
     	    if ($charge->refunded=='1'){
    -	    	print $langs->trans("refunded");
    +	    	print img_picto($langs->trans("refunded"),'statut6');
     	    } elseif ($charge->paid=='1'){
    -	    	print $langs->trans("".$charge->status."");
    +
    +        print img_picto($langs->trans("".$charge->status.""),'statut4');
     	    } else {
     	    	$label="Message: ".$charge->failure_message."<br>";
     	    	$label.="Réseau: ".$charge->outcome->network_status."<br>";
     	    	$label.="Statut: ".$langs->trans("".$charge->outcome->seller_message."");
    -	    	print $form->textwithpicto($langs->trans("".$charge->status.""),$label,1);
    +	    	print $form->textwithpicto(img_picto($langs->trans("".$charge->status.""),'statut8'),$label,1);
     	    }
    -	    print "</TD>\n";
    +	    print "</td>\n";
     
    -	    print "</TR>\n";
    +	    print "</tr>\n";
     	}
     } else {
     
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/stripe/class/actions_stripe.class.php b/htdocs/stripe/class/actions_stripe.class.php
    index 0451c1d4782..a74b2d52eef 100644
    --- a/htdocs/stripe/class/actions_stripe.class.php
    +++ b/htdocs/stripe/class/actions_stripe.class.php
    @@ -36,8 +36,10 @@ $langs->load("stripe@stripe");
      */
     class ActionsStripeconnect
     {
    -	/** @var DoliDB */
    -	var $db;
    +	/**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
     	private $config=array();
     
    @@ -63,6 +65,7 @@ class ActionsStripeconnect
     	 * @param	array	$parameters		Parameters
     	 * @param	Object	$object			Object
     	 * @param	string	$action			Action
    +     * @return bool
     	 */
     	function formObjectOptions($parameters, &$object, &$action)
     	{
    @@ -106,7 +109,6 @@ class ActionsStripeconnect
     				$this->resprints.= $langs->trans("NoStripe");
     			}
     			$this->resprints.= '</td></tr>';
    -
     		}
     		elseif (is_object($object) && $object->element == 'member'){
     			$this->resprints.= '<tr><td>';
    @@ -233,5 +235,4 @@ class ActionsStripeconnect
     		}
     		return 0;
     	}
    -
     }
    diff --git a/htdocs/stripe/class/index.html b/htdocs/stripe/class/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/stripe/class/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
    index b8472d0b821..d8e7168e5c0 100644
    --- a/htdocs/stripe/class/stripe.class.php
    +++ b/htdocs/stripe/class/stripe.class.php
    @@ -28,15 +28,39 @@ require_once DOL_DOCUMENT_ROOT.'/stripe/config.php';						// This set stripe glo
      */
     class Stripe extends CommonObject
     {
    +	/**
    +	 * @var int ID
    +	 */
     	public $rowid;
    -	public $fk_soc;
    +
    +	/**
    +	 * @var int Thirdparty ID
    +	 */
    +    public $fk_soc;
    +
    +    /**
    +     * @var int ID
    +     */
     	public $fk_key;
    +
    +	/**
    +	 * @var int ID
    +	 */
     	public $id;
    +
     	public $mode;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
    +
     	public $statut;
    +
     	public $type;
    +
     	public $code;
    +
     	public $message;
     
     	/**
    @@ -47,7 +71,6 @@ class Stripe extends CommonObject
     	public function __construct($db)
     	{
     		$this->db = $db;
    -
     	}
     
     
    @@ -99,8 +122,6 @@ class Stripe extends CommonObject
     	 */
     	public function getStripeCustomerAccount($id, $status=0)
     	{
    -		global $conf;
    -
     		include_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
     		$societeaccount = new SocieteAccount($this->db);
     		return $societeaccount->getCustomerAccount($id, 'stripe', $status);		// Get thirdparty cus_...
    @@ -166,11 +187,22 @@ class Stripe extends CommonObject
     			{
     				$dataforcustomer = array(
     					"email" => $object->email,
    -					"business_vat_id" => $object->tva_intra,
     					"description" => $object->name,
     					"metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR']))
     				);
     
    +				$vatcleaned = $object->tva_intra ? $object->tva_intra : null;
    +
    +				$taxinfo = array('type'=>'vat');
    +				if ($vatcleaned)
    +				{
    +					$taxinfo["tax_id"] = $vatcleaned;
    +				}
    +				// We force data to "null" if not defined as expected by Stripe
    +				if (empty($vatcleaned)) $taxinfo=null;
    +
    +				$dataforcustomer["tax_info"] = $taxinfo;
    +
     				//$a = \Stripe\Stripe::getApiKey();
     				//var_dump($a);var_dump($key);exit;
     				try {
    @@ -252,7 +284,6 @@ class Stripe extends CommonObject
     						$this->error = $e->getMessage();
     						dol_syslog($this->error, LOG_WARNING);
     					}
    -
     				}
     				elseif ($createifnotlinkedtostripe)
     				{
    @@ -315,18 +346,19 @@ class Stripe extends CommonObject
     	/**
     	 * Create charge with public/payment/newpayment.php, stripe/card.php, cronjobs or REST API
     	 *
    -	 * @param int 		$amount									Amount to pay
    -	 * @param string 	$currency								EUR, GPB...
    -	 * @param string 	$origin									Object type to pay (order, invoice, contract...)
    -	 * @param int 		$item									Object id to pay
    -	 * @param string 	$source									src_xxxxx or card_xxxxx
    -	 * @param string 	$customer								Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
    -	 * @param string 	$account								Stripe account ref 'acc_xxxxxxxxxxxxx' via  getStripeAccount()
    +	 * @param	int 	$amount									Amount to pay
    +	 * @param	string 	$currency								EUR, GPB...
    +	 * @param	string 	$origin									Object type to pay (order, invoice, contract...)
    +	 * @param	int 	$item									Object id to pay
    +	 * @param	string 	$source									src_xxxxx or card_xxxxx
    +	 * @param	string 	$customer								Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
    +	 * @param	string 	$account								Stripe account ref 'acc_xxxxxxxxxxxxx' via  getStripeAccount()
     	 * @param	int		$status									Status (0=test, 1=live)
     	 * @param	int		$usethirdpartyemailforreceiptemail		Use thirdparty email as receipt email
    +	 * @param	boolean	$capture								Set capture flag to true (take payment) or false (wait)
     	 * @return Stripe
     	 */
    -	public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0)
    +	public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0, $capture=true)
     	{
     		global $conf;
     
    @@ -367,18 +399,19 @@ class Stripe extends CommonObject
     			$order = new Commande($this->db);
     			$order->fetch($item);
     			$ref = $order->ref;
    -			$description = "ORD=" . $ref . ".CUS=" . $societe->id;
    +			$description = "ORD=" . $ref . ".CUS=" . $societe->id.".PM=stripe";
     		} elseif ($origin == invoice) {
     			$invoice = new Facture($this->db);
     			$invoice->fetch($item);
     			$ref = $invoice->ref;
    -			$description = "INV=" . $ref . ".CUS=" . $societe->id;
    +			$description = "INV=" . $ref . ".CUS=" . $societe->id.".PM=stripe";
     		}
     
     		$metadata = array(
     			"dol_id" => "" . $item . "",
     			"dol_type" => "" . $origin . "",
     			"dol_thirdparty_id" => "" . $societe->id . "",
    +			'dol_thirdparty_name' => $societe->name,
     			'dol_version'=>DOL_VERSION,
     			'dol_entity'=>$conf->entity,
     			'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR'])
    @@ -396,7 +429,9 @@ class Stripe extends CommonObject
     					$charge = \Stripe\Charge::create(array(
     						"amount" => "$stripeamount",
     						"currency" => "$currency",
    -						// "statement_descriptor" => " ",
    +						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
    +						"description" => "Stripe payment: ".$description,
    +						"capture"  => $capture,
     						"metadata" => $metadata,
     						"source" => "$source"
     					));
    @@ -404,8 +439,9 @@ class Stripe extends CommonObject
     					$paymentarray = array(
     						"amount" => "$stripeamount",
     						"currency" => "$currency",
    -						// "statement_descriptor" => " ",
    -						"description" => "$description",
    +						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
    +						"description" => "Stripe payment: ".$description,
    +						"capture"  => $capture,
     						"metadata" => $metadata,
     						"source" => "$source",
     						"customer" => "$customer"
    @@ -425,19 +461,26 @@ class Stripe extends CommonObject
     					$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100);
     				}
     
    -				$charge = \Stripe\Charge::create(array(
    -					"amount" => "$stripeamount",
    -					"currency" => "$currency",
    -					// "statement_descriptor" => " ",
    -					"description" => "$description",
    -					"metadata" => $metadata,
    -					"source" => "$source",
    -					"customer" => "$customer",
    -					"application_fee" => "$fee"
    -					), array(
    -					"idempotency_key" => "$ref",
    -					"stripe_account" => "$account"
    -				));
    +        		$paymentarray = array(
    +						"amount" => "$stripeamount",
    +						"currency" => "$currency",
    +						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
    +						"description" => "Stripe payment: ".$description,
    +						"capture"  => $capture,
    +						"metadata" => $metadata,
    +						"source" => "$source",
    +						"customer" => "$customer"
    +					);
    +					if ($conf->entity!=$conf->global->STRIPECONNECT_PRINCIPAL && $fee>0)
    +					{
    +						$paymentarray["application_fee"] = $fee;
    +					}
    +					if ($societe->email && $usethirdpartyemailforreceiptemail)
    +					{
    +						$paymentarray["receipt_email"] = $societe->email;
    +					}
    +
    +					$charge = \Stripe\Charge::create($paymentarray, array("idempotency_key" => "$ref","stripe_account" => "$account"));
     			}
     			if (isset($charge->id)) {}
     
    @@ -501,5 +544,4 @@ class Stripe extends CommonObject
     		}
     		return $return;
     	}
    -
     }
    diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php
    index 7aa22678d7a..6141c2a32f8 100644
    --- a/htdocs/stripe/config.php
    +++ b/htdocs/stripe/config.php
    @@ -55,4 +55,4 @@ else
     
     \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
     \Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
    -\Stripe\Stripe::setApiVersion("2018-07-27"); // force version API
    +\Stripe\Stripe::setApiVersion("2018-09-24"); // force version API
    diff --git a/htdocs/stripe/payment.php b/htdocs/stripe/payment.php
    index 1113d1428f5..9a7ecfd5470 100644
    --- a/htdocs/stripe/payment.php
    +++ b/htdocs/stripe/payment.php
    @@ -1,13 +1,15 @@
     <?php
    -/* Copyright (C) 2001-2006 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2016 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
    - * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
    - * Copyright (C) 2007      Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
    - * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
    - * Copyright (C) 2014      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) 2014      Teddy Andreotti       <125155@supinfo.com>
    - * Copyright (C) 2015      Juanjo Menent		 <jmenent@2byte.es>
    +/* Copyright (C) 2001-2006  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2007       Franky Van Liedekerke   <franky.van.liedekerke@telenet.be>
    + * Copyright (C) 2012       Cédric Salvador         <csalvador@gpcsolutions.fr>
    + * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2014       Teddy Andreotti         <125155@supinfo.com>
    + * Copyright (C) 2015       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       ThibaultFOUCART         <support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -30,8 +32,7 @@
      */
     
     // Load Dolibarr environment
    -$res=@include("../main.inc.php");                                // For root directory
    -if (! $res) $res=@include("../../main.inc.php");
    +require '../main.inc.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
     require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    @@ -47,9 +48,9 @@ $confirm	= GETPOST('confirm');
     
     $facid		= GETPOST('facid','int');
     $socname	= GETPOST('socname');
    -$source	= GETPOST('source_id');
    +$source = GETPOST('source_id');
     $accountid	= GETPOST('accountid');
    -$paymentnum	= GETPOST('num_paiement');
    +$paymentnum = GETPOST('num_paiement');
     
     $sortfield	= GETPOST('sortfield','alpha');
     $sortorder	= GETPOST('sortorder','alpha');
    @@ -218,15 +219,12 @@ if (empty($reshook))
     	/*
     	 * Action add_paiement
     	 */
    -	if ($action == 'add_paiement')
    -	{
    -	    if ($error)
    -	    {
    -      $action = 'create';
    -      if (!$source)
    -	    {
    -			setEventMessages($langs->transnoentities('NoSource'), null, 'errors');
    -	    }
    +	if ($action == 'add_paiement') {
    +	    if ($error) {
    +            $action = 'create';
    +            if (!$source) {
    +			    setEventMessages($langs->transnoentities('NoSource'), null, 'errors');
    +	        }
     	        $error++;
     	    }
     	    // Le reste propre a cette action s'affiche en bas de page.
    @@ -301,7 +299,7 @@ if (empty($reshook))
     		}
     		elseif (preg_match('/src_/i',$source))
     		{
    -	
    +
     		        $customer2 = $customerstripe=$stripe->customerStripe($facture->thirdparty, $stripeacc, $servicestatus);
     			$src = $customer2->sources->retrieve("$source");
     			if ($src->type=='card')
    @@ -352,7 +350,6 @@ if (empty($reshook))
     
     				$facture->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
     			}
    -
     		}
     
     		if (! $error)
    @@ -406,16 +403,14 @@ if (empty($reshook))
      * View
      */
     
    -$form=new Form($db);
    +$form = new Form($db);
     
     llxHeader();
     
    -if (! empty($conf->global->STRIPE_LIVE) && ! GETPOST('forcesandbox','alpha'))
    -{
    +if (! empty($conf->global->STRIPE_LIVE) && ! GETPOST('forcesandbox','alpha')) {
     	$service = 'StripeLive';
     	$servicestatus = 0;
    -}
    -else {
    +} else {
     	dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode','Stripe'),'','warning');
     }
     
    @@ -568,7 +563,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     			print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans('Invoice').'</span></td><td>'.$facture->getNomUrl(4)."</td></tr>\n";
     		}*/
     
    -		// Third party
    +        // Third party
             print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans('Company').'</span></td><td>'.$facture->thirdparty->getNomUrl(4)."</td></tr>\n";
     
             // Bank account
    @@ -583,22 +578,22 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
             }
     
             // Cheque number
    -//        print '<tr><td>'.$langs->trans('Numero');
    -//        print ' <em>('.$langs->trans("ChequeOrTransferNumber").')</em>';
    -//        print '</td>';
    -//        print '<td><input name="num_paiement" type="text" value="'.$paymentnum.'"></td></tr>';
    +        //print '<tr><td>'.$langs->trans('Numero');
    +        //print ' <em>('.$langs->trans("ChequeOrTransferNumber").')</em>';
    +        //print '</td>';
    +        //print '<td><input name="num_paiement" type="text" value="'.$paymentnum.'"></td></tr>';
     
             // Check transmitter
    -//        print '<tr><td class="'.(GETPOST('paiementcode')=='CHQ'?'fieldrequired ':'').'fieldrequireddyn">'.$langs->trans('CheckTransmitter');
    -//        print ' <em>('.$langs->trans("ChequeMaker").')</em>';
    -//        print '</td>';
    -//        print '<td><input id="fieldchqemetteur" name="chqemetteur" size="30" type="text" value="'.GETPOST('chqemetteur').'"></td></tr>';
    +        //print '<tr><td class="'.(GETPOST('paiementcode')=='CHQ'?'fieldrequired ':'').'fieldrequireddyn">'.$langs->trans('CheckTransmitter');
    +        //print ' <em>('.$langs->trans("ChequeMaker").')</em>';
    +        //print '</td>';
    +        //print '<td><input id="fieldchqemetteur" name="chqemetteur" size="30" type="text" value="'.GETPOST('chqemetteur').'"></td></tr>';
     
             // Bank name
    -//        print '<tr><td>'.$langs->trans('Bank');
    -//        print ' <em>('.$langs->trans("ChequeBank").')</em>';
    -//        print '</td>';
    -//        print '<td><input name="chqbank" size="30" type="text" value="'.GETPOST('chqbank').'"></td></tr>';
    +        //print '<tr><td>'.$langs->trans('Bank');
    +        //print ' <em>('.$langs->trans("ChequeBank").')</em>';
    +        //print '</td>';
    +        //print '<td><input name="chqbank" size="30" type="text" value="'.GETPOST('chqbank').'"></td></tr>';
     
     		// Comments
     		print '<tr><td>'.$langs->trans('Comments').'</td>';
    @@ -607,157 +602,155 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     
             print '</table>';
     
    -		dol_fiche_end();
    +        dol_fiche_end();
     
     
    -		$customerstripe=$stripe->customerStripe($facture->thirdparty, $stripeacc, $servicestatus);
    +        $customerstripe=$stripe->customerStripe($facture->thirdparty, $stripeacc, $servicestatus);
     
    -		 print '<br>';
    -		    print_barre_liste($langs->trans('StripeSourceList').' '.$typeElementString.' '.$button, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, '', '');
    +        print '<br>';
    +        print_barre_liste($langs->trans('StripeSourceList').' '.$typeElementString.' '.$button, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, '', '');
     
    -		    print '<table class="liste" width="100%">'."\n";
    -		    // Titles with sort buttons
    -		    print '<tr class="liste_titre">';
    -		    print '<td align="left"></td>';
    -		    print '<td align="left">'.$langs->trans('Type').'</td>';
    -		    print '<td align="left">'.$langs->trans('Informations').'</td>';
    -		    print '<td align="left"></td>';
    -		    print "<td></td></tr>\n";
    -		    foreach ($customerstripe->sources->data as $src) {
    -		print '<tr>';
    +        print '<table class="liste" width="100%">'."\n";
    +        // Titles with sort buttons
    +        print '<tr class="liste_titre">';
    +        print '<td align="left"></td>';
    +        print '<td align="left">'.$langs->trans('Type').'</td>';
    +        print '<td align="left">'.$langs->trans('Informations').'</td>';
    +        print '<td align="left"></td>';
    +        print "<td></td></tr>\n";
    +        foreach ($customerstripe->sources->data as $src) {
    +            print '<tr>';
     
                 print '<td align="center" width="20" ';
    -if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) { print'class="opacitymedium"';}
    -print'><input type="radio" id="source_id" class="flat" name="source_id"  value="'.$src->id.'"';
    -if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) {
    +            if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) {
    +                print'class="opacitymedium"';
    +            }
    +            print '><input type="radio" id="source_id" class="flat" name="source_id"  value="'.$src->id.'"';
    +            if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) {
                     print ' disabled';
                 } elseif (($customerstripe->default_source==$src->id && $action != 'add_paiement') or ($source==$src->id && $action == 'add_paiement')) {
                     print ' checked';
                 }
                 print '></td>';
     
    -print '<td ';
    -if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) { print'class="opacitymedium"';}
    +            print '<td ';
    +            if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) {
    +                print'class="opacitymedium"';
    +            }
     
    -print' >';
    -if ($src->object=='card'){
    -if ($src->brand == 'Visa') {$brand='cc-visa';}
    -elseif ($src->brand == 'MasterCard') {$brand='cc-mastercard';}
    -elseif ($src->brand == 'American Express') {$brand='cc-amex';}
    -elseif ($src->brand == 'Discover') {$brand='cc-discover';}
    -elseif ($src->brand == 'JCB') {$brand='cc-jcb';}
    -elseif ($src->brand == 'Diners Club') {$brand='cc-diners-club';}
    -else {$brand='credit-card-alt';}
    -print '<span class="fa fa-'.$brand.' fa-3x fa-fw"></span>';
    -}
    -elseif ($src->object=='source' && $src->type=='card'){
    -if ($src->card->brand == 'Visa') {$brand='cc-visa';}
    -elseif ($src->card->brand == 'MasterCard') {$brand='cc-mastercard';}
    -elseif ($src->card->brand == 'American Express') {$brand='cc-amex';}
    -elseif ($src->card->brand == 'Discover') {$brand='cc-discover';}
    -elseif ($src->card->brand == 'JCB') {$brand='cc-jcb';}
    -elseif ($src->card->brand == 'Diners Club') {$brand='cc-diners-club';}
    -else {$brand='credit-card-alt';}
    -
    -print '<span class="fa fa-'.$brand.' fa-3x fa-fw"></span>';
    -}
    -elseif ($src->object=='source' && $src->type=='sepa_debit'){
    -print '<span class="fa fa-university fa-3x fa-fw"></span>';
    -}
    -print '</td>';
    -print '<td ';
    -if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) { print'class="opacitymedium"';}
    -print' >';
    -if ($src->object=='card'){
    -print '**** '.$src->last4.'<br>Exp. '.$src->exp_month.'/'.$src->exp_year.'';
    -print '</td><td>';
    - if ($src->country)
    -	{
    -		$img=picto_from_langcode($src->country);
    -		print $img?$img.' ':'';
    -		print getCountry($src->country,1);
    -	}
    -	else print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyCountry")).'</font>';
    -}
    -elseif ($src->object=='source' && $src->type=='card'){
    -					print $src->owner->name.'<br>**** '.$src->card->last4.' - '.$src->card->exp_month.'/'.$src->card->exp_year.'';
    -print '</td><td>';
    - if ($src->card->country)
    -	{
    -		$img=picto_from_langcode($src->card->country);
    -		print $img?$img.' ':'';
    -		print getCountry($src->card->country,1);
    -	}
    -	else print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyCountry")).'</font>';
    -}
    -elseif ($src->object=='source' && $src->type=='sepa_debit'){
    -print 'info sepa';
    -print '</td><td>';
    - if ($src->sepa_debit->country)
    -	{
    -		$img=picto_from_langcode($src->sepa_debit->country);
    -		print $img?$img.' ':'';
    -		print getCountry($src->sepa_debit->country,1);
    -	}
    -	else print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyCountry")).'</font>';
    -}
    -print '</td>';
    +            print' >';
    +            if ($src->object=='card') {
    +                print img_credit_card($src->brand);
    +            } elseif ($src->object=='source' && $src->type=='card') {
    +                print img_credit_card($src->card->brand);
    +            } elseif ($src->object=='source' && $src->type=='sepa_debit') {
    +                print '<span class="fa fa-university fa-2x fa-fw"></span>';
    +            }
    +            print '</td>';
    +            print '<td ';
    +            if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) {
    +                print'class="opacitymedium"';
    +            }
    +            print' >';
    +            if ($src->object=='card') {
    +                print '....'.$src->last4.' - '.$src->exp_month.'/'.$src->exp_year.'';
    +                print '</td><td>';
    +                if ($src->country) {
    +                    $img = picto_from_langcode($src->country);
    +                    print $img?$img.' ':'';
    +                    print getCountry($src->country,1);
    +                } else {
    +                    print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyCountry")).'</font>';
    +                }
    +            } elseif ($src->object=='source' && $src->type=='card') {
    +                print $src->owner->name.'<br>....'.$src->card->last4.' - '.$src->card->exp_month.'/'.$src->card->exp_year.'';
    +                print '</td><td>';
    +                if ($src->card->country) {
    +                    $img = picto_from_langcode($src->card->country);
    +                    print $img?$img.' ':'';
    +                    print getCountry($src->card->country,1);
    +                } else {
    +                    print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyCountry")).'</font>';
    +                }
    +            } elseif ($src->object=='source' && $src->type=='sepa_debit') {
    +                print 'info sepa';
    +                print '</td><td>';
    +                if ($src->sepa_debit->country) {
    +                    $img = picto_from_langcode($src->sepa_debit->country);
    +                    print $img?$img.' ':'';
    +                    print getCountry($src->sepa_debit->country,1);
    +                } else {
    +                    print img_warning().' <font class="error">'.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("CompanyCountry")).'</font>';
    +                }
    +            }
    +            print '</td>';
                 // Default
                 print '<td align="center" width="50" ';
    -if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) { print'class="opacitymedium"';}
    -print'>';
    +            if (($action == 'add_paiement' && $src->id!=$source) or ($src->object=='source' && $src->card->three_d_secure=='required')) {
    +                print'class="opacitymedium"';
    +            }
    +            print'>';
                 if (($customerstripe->default_source==$src->id)) {
                     print "<SPAN class=' fa fa-star  fa-2x'></SPAN>";
                 }
                 print '</td>';
    -print '</tr>';
    -}
    -// TODO more dolibarize with new stripe function and stripeconnect
    -//if ($stripe->getStripeCustomerAccount($facture->socid)) {
    -//$account=\Stripe\Account::retrieve("".$stripe->getStripeCustomerAccount($facture->socid)."");
    -//}
    +            print '</tr>';
    +        }
    +        // TODO more dolibarize with new stripe function and stripeconnect
    +        //if ($stripe->getStripeCustomerAccount($facture->socid)) {
    +        //    $account=\Stripe\Account::retrieve("".$stripe->getStripeCustomerAccount($facture->socid)."");
    +        //}
     
    -	if (($account->type=='custom' or $account->type=='express') && $entity==1) {
    -	print '<tr class="oddeven">';
    +        if (($account->type=='custom' or $account->type=='express') && $entity==1) {
    +            print '<tr class="oddeven">';
     
    -	            print '<td align="center" width="20" ';
    -	if ($action == 'add_paiement' && $stripe->getStripeCustomerAccount($facture->socid)!=$source) { print'class="opacitymedium"';}
    -	print'><input type="radio" id="source_id" class="flat" name="source_id"  value="'.$conf->global->STRIPE_EXTERNAL_ACCOUNT.'"';
    -	            if ((empty($input) && $action != 'add_paiement') or ($source==$conf->global->STRIPE_EXTERNAL_ACCOUNT && $action == 'add_paiement')) {
    -	                print ' checked';
    -	            } elseif ($action == 'add_paiement' && $conf->global->STRIPE_EXTERNAL_ACCOUNT!=$source) {
    -	                print ' disabled';
    -	            }
    -	            print '></td><td ';
    -	if ($action == 'add_paiement' && $stripe->getStripeCustomerAccount($facture->socid)!=$source) { print'class="opacitymedium"';}
    -	            print '><span class="fa fa-cc-stripe fa-3x fa-fw"></span></td>';
    +            print '<td align="center" width="20" ';
    +            if ($action == 'add_paiement' && $stripe->getStripeCustomerAccount($facture->socid)!=$source) {
    +                print'class="opacitymedium"';
    +            }
    +            print'><input type="radio" id="source_id" class="flat" name="source_id"  value="'.$conf->global->STRIPE_EXTERNAL_ACCOUNT.'"';
    +            if ((empty($input) && $action != 'add_paiement') or ($source==$conf->global->STRIPE_EXTERNAL_ACCOUNT && $action == 'add_paiement')) {
    +                print ' checked';
    +            } elseif ($action == 'add_paiement' && $conf->global->STRIPE_EXTERNAL_ACCOUNT!=$source) {
    +                print ' disabled';
    +            }
    +            print '></td><td ';
    +            if ($action == 'add_paiement' && $stripe->getStripeCustomerAccount($facture->socid)!=$source) {
    +                print'class="opacitymedium"';
    +            }
    +            print '><span class="fa fa-cc-stripe fa-3x fa-fw"></span></td>';
     
    -	print '<td ';
    -	if ($action == 'add_paiement' && $stripe->getStripeCustomerAccount($facture->socid)!=$source) { print'class="opacitymedium"';}
    -	print'>'.$langs->trans('sold');
    -	print'</td><td ';
    -	if ($action == 'add_paiement' && $src->id!=$source) { print'class="opacitymedium"';}
    -	print'>';
    +            print '<td ';
    +            if ($action == 'add_paiement' && $stripe->getStripeCustomerAccount($facture->socid)!=$source) {
    +                print'class="opacitymedium"';
    +            }
    +            print'>'.$langs->trans('sold');
    +            print'</td><td ';
    +            if ($action == 'add_paiement' && $src->id!=$source) {
    +                print'class="opacitymedium"';
    +            }
    +            print'>';
     
    -	print '</td>';
    -	            // Default
    -	            print '<td align="center" width="50" ';
    -	if ($action == 'add_paiement' && $src->id!=$source) { print'class="opacitymedium"';}
    -	print'>';
    -	//            if (($customer->default_source!=$src->id)) {
    -	//                print img_picto($langs->trans("Disabled"),'off');
    -	//            } else {
    -	//                print img_picto($langs->trans("Default"),'on');
    -	//            }
    -	            print '</td>';
    -	print '</tr>';
    -	}
    -	if (empty($input)&&!$stripe->getStripeCustomerAccount($facture->socid))
    -	{
    -	print '<tr><td class="opacitymedium" colspan="5">'.$langs->trans("None").'</td></tr>';
    -	}
    +            print '</td>';
    +            // Default
    +            print '<td align="center" width="50" ';
    +            if ($action == 'add_paiement' && $src->id!=$source) {
    +                print'class="opacitymedium"';
    +            }
    +            print'>';
    +            //if (($customer->default_source!=$src->id)) {
    +            //    print img_picto($langs->trans("Disabled"),'off');
    +            //} else {
    +            //    print img_picto($langs->trans("Default"),'on');
    +            //}
    +            print '</td>';
    +            print '</tr>';
    +        }
    +        if (empty($input)&&!$stripe->getStripeCustomerAccount($facture->socid)) {
    +            print '<tr><td class="opacitymedium" colspan="5">'.$langs->trans("None").'</td></tr>';
    +        }
     
    -	print "</table>";
    +        print "</table>";
     
     
             /*
    @@ -768,14 +761,14 @@ print '</tr>';
             $sql.= ' f.datef as df, f.fk_soc as socid';
             $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
     
    -		if(!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS)) {
    +		if (!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS)) {
     			$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON (f.fk_soc = s.rowid)';
     		}
     
     		$sql.= ' WHERE f.entity = '.$conf->entity;
             $sql.= ' AND (f.fk_soc = '.$facture->socid;
     
    -		if(!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS) && !empty($facture->thirdparty->parent)) {
    +		if (!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS) && !empty($facture->thirdparty->parent)) {
     			$sql.= ' OR f.fk_soc IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'societe WHERE parent = '.$facture->thirdparty->parent.')';
     		}
     
    @@ -814,20 +807,24 @@ print '</tr>';
                     $i = 0;
                     //print '<tr><td colspan="3">';
                     print '<br>';
    -                 print_barre_liste($langs->trans('StripeInvoiceList').' '.$typeElementString.' '.$button, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, '', '');
    +                print_barre_liste($langs->trans('StripeInvoiceList').' '.$typeElementString.' '.$button, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, '', '');
                     print '<table class="noborder" width="100%">';
                     print '<tr class="liste_titre">';
                     print '<td>'.$arraytitle.'</td>';
                     print '<td align="center">'.$langs->trans('Date').'</td>';
    -                if (!empty($conf->multicurrency->enabled)) print '<td>'.$langs->trans('Currency').'</td>';
    -                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
    -                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$multicurrencyalreadypayedlabel.'</td>';
    -                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$multicurrencyremaindertopay.'</td>';
    +                if (!empty($conf->multicurrency->enabled)) {
    +                    print '<td>'.$langs->trans('Currency').'</td>';
    +                    print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
    +                    print '<td align="right">'.$multicurrencyalreadypayedlabel.'</td>';
    +                    print '<td align="right">'.$multicurrencyremaindertopay.'</td>';
    +                }
                     print '<td align="right">'.$langs->trans('AmountTTC').'</td>';
                     print '<td align="right">'.$alreadypayedlabel.'</td>';
                     print '<td align="right">'.$remaindertopay.'</td>';
                     print '<td align="right">'.$langs->trans('PaymentAmount').'</td>';
    -                if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyPaymentAmount').'</td>';
    +                if (!empty($conf->multicurrency->enabled)) {
    +                    print '<td align="right">'.$langs->trans('MulticurrencyPaymentAmount').'</td>';
    +                }
                     print '<td align="right">&nbsp;</td>';
                     print "</tr>\n";
     
    @@ -986,17 +983,21 @@ print '</tr>';
                         // Print total
                         print '<tr class="liste_total">';
                         print '<td colspan="2" align="left">'.$langs->trans('TotalTTC').'</td>';
    -					if (!empty($conf->multicurrency->enabled)) print '<td></td>';
    -					if (!empty($conf->multicurrency->enabled)) print '<td></td>';
    -					if (!empty($conf->multicurrency->enabled)) print '<td></td>';
    +					if (!empty($conf->multicurrency->enabled)) {
    +                        print '<td></td>';
    +					    print '<td></td>';
    +					    print '<td></td>';
    +                    }
     					print '<td align="right"><b>'.price($sign * $total_ttc).'</b></td>';
                         print '<td align="right"><b>'.price($sign * $totalrecu);
                         if ($totalrecucreditnote) print '+'.price($totalrecucreditnote);
                         if ($totalrecudeposits) print '+'.price($totalrecudeposits);
                         print '</b></td>';
    -                   print '<td align="right"><b>'.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits,'MT')).'</b></td>';
    +                    print '<td align="right"><b>'.price($sign * price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits,'MT')).'</b></td>';
                         print '<td align="right" id="result" style="font-weight: bold;"></td>';
    -					if (!empty($conf->multicurrency->enabled)) {print '<td align="right" id="multicurrency_result" style="font-weight: bold;"></td>';}
    +					if (!empty($conf->multicurrency->enabled)) {
    +                        print '<td align="right" id="multicurrency_result" style="font-weight: bold;"></td>';
    +                    }
                         print "</tr>\n";
                     }
                     print "</table>";
    @@ -1035,10 +1036,11 @@ print '</tr>';
                 $preselectedchoice=$addwarning?'no':'yes';
     
                 print '<br>';
    -            if (!empty($totalpayment)) $text=$langs->trans('ConfirmCustomerPayment',$totalpayment,$langs->trans("Currency".$conf->currency));
    -			if (!empty($multicurrency_totalpayment))
    -			{
    -				$text.='<br>'.$langs->trans('ConfirmCustomerPayment',$multicurrency_totalpayment,$langs->trans("paymentInInvoiceCurrency"));
    +            if (!empty($totalpayment)) {
    +                $text = $langs->trans('ConfirmCustomerPayment', $totalpayment, $langs->trans("Currency".$conf->currency));
    +            }
    +			if (!empty($multicurrency_totalpayment)) {
    +				$text.='<br>'.$langs->trans('ConfirmCustomerPayment', $multicurrency_totalpayment, $langs->trans("paymentInInvoiceCurrency"));
     			}
                 if (GETPOST('closepaidinvoices'))
                 {
    @@ -1114,6 +1116,6 @@ if (! GETPOST('action'))
         }
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/stripe/transaction.php b/htdocs/stripe/transaction.php
    index 1cdabffdac4..f95bde08369 100644
    --- a/htdocs/stripe/transaction.php
    +++ b/htdocs/stripe/transaction.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2018 	PtibogXIV        <support@ptibogxiv.net>
    +/* Copyright (C) 2018       Thibault FOUCART        <support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -62,14 +63,16 @@ llxHeader('', $langs->trans("StripeTransactionList"));
     if (! empty($conf->stripe->enabled) && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox','alpha')))
     {
     	$service = 'StripeTest';
    +	$servicestatus = '0';
     	dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
     }
     else
     {
     	$service = 'StripeLive';
    +	$servicestatus = '1';
     }
     
    -$stripeaccount = $stripe->getStripeAccount($service);
    +$stripeacc = $stripe->getStripeAccount($service);
     /*if (empty($stripeaccount))
     {
     	print $langs->trans('ErrorStripeAccountNotDefined');
    @@ -77,55 +80,55 @@ $stripeaccount = $stripe->getStripeAccount($service);
     
     if (! $rowid) {
     
    -	print '<FORM method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
    +	print '<form method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
     	if ($optioncss != '')
    -		print '<INPUT type="hidden" name="optioncss" value="' . $optioncss . '">';
    -	print '<INPUT type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
    -	print '<INPUT type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    -	print '<INPUT type="hidden" name="action" value="list">';
    -	print '<INPUT type="hidden" name="sortfield" value="' . $sortfield . '">';
    -	print '<INPUT type="hidden" name="sortorder" value="' . $sortorder . '">';
    -	print '<INPUT type="hidden" name="page" value="' . $page . '">';
    +		print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
    +	print '<input type="hidden" name="token" value="' . $_SESSION['newtoken'] . '">';
    +	print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    +	print '<input type="hidden" name="action" value="list">';
    +	print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
    +	print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
    +	print '<input type="hidden" name="page" value="' . $page . '">';
     
     	$title=$langs->trans("StripeTransactionList");
    -	$title.=($stripeaccount?' (Stripe connection with Stripe OAuth Connect account '.$stripeaccount.')':' (Stripe connection with keys from Stripe module setup)');
    +	$title.=($stripeaccount?' (Stripe connection with Stripe OAuth Connect account '.$stripeacc.')':' (Stripe connection with keys from Stripe module setup)');
     
     	print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $totalnboflines, 'title_accountancy.png', 0, '', '', $limit);
     
    -	print '<DIV class="div-table-responsive">';
    -	print '<TABLE class="tagtable liste' . ($moreforfilter ? " listwithfilterbefore" : "") . '">' . "\n";
    +	print '<div class="div-table-responsive">';
    +	print '<table class="tagtable liste' . ($moreforfilter ? " listwithfilterbefore" : "") . '">' . "\n";
     
    -	print '<TR class="liste_titre">';
    +	print '<tr class="liste_titre">';
     	print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
     	//print_liste_field_titre("StripeCustomerId",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
     	//print_liste_field_titre("CustomerId", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
    -	print_liste_field_titre("Origin", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
    +	//print_liste_field_titre("Origin", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
     	print_liste_field_titre("DatePayment", $_SERVER["PHP_SELF"], "", "", "", 'align="center"', $sortfield, $sortorder);
     	print_liste_field_titre("Type", $_SERVER["PHP_SELF"], "", "", "", 'align="left"', $sortfield, $sortorder);
     	print_liste_field_titre("Paid", $_SERVER["PHP_SELF"], "", "", "", 'align="right"', $sortfield, $sortorder);
     	print_liste_field_titre("Fee", $_SERVER["PHP_SELF"], "", "", "", 'align="right"', $sortfield, $sortorder);
     	print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", "", 'align="right"');
    -	print "</TR>\n";
    +	print "</tr>\n";
     
    -	print "</TR>\n";
    +	print "</tr>\n";
     
    -	if ($stripeaccount)
    +	if ($stripeacc)
     	{
    -		$txn = \Stripe\BalanceTransaction::all(array("limit" => $limit), array("stripe_account" => $stripeaccount));
    +		$txn = \Stripe\BalanceTransaction::all(array("limit" => $limit), array("stripe_account" => $stripeacc));
     	}
     	else
     	{
     		$txn = \Stripe\BalanceTransaction::all(array("limit" => $limit));
     	}
     
    -	foreach ($txn->data as $txn) 
    +	foreach ($txn->data as $txn)
     	{
     		//$charge = $txn;
     		//var_dump($txn);
    -		
    +
     		// The metadata FULLTAG is defined by the online payment page
     		/*$FULLTAG=$charge->metadata->FULLTAG;
    -		
    +
     		// Save into $tmparray all metadata
     		$tmparray = dolExplodeIntoArray($FULLTAG,'.','=');
     		// Load origin object according to metadata
    @@ -145,7 +148,7 @@ if (! $rowid) {
     		{
     			$memberstatic->id = 0;
     		}*/
    -		
    +
     		$societestatic->fetch($charge->metadata->idcustomer);
     		$societestatic->id = $charge->metadata->idcustomer;
     		$societestatic->lastname = $obj->lastname;
    @@ -155,14 +158,34 @@ if (! $rowid) {
     		$societestatic->email = $obj->email;
     		$societestatic->societe_id = $obj->fk_soc;
     
    -		print '<TR class="oddeven">';
    -		
    +		print '<tr class="oddeven">';
    +
     		// Ref
    -		print "<TD><A href='" . DOL_URL_ROOT . "/stripe/transaction.php?rowid=" . $txn->source . "'>" . $txn->source . "</A></TD>\n";
    +        if (!empty($stripeacc)) $connect=$stripeacc.'/';
    +    
    +		// Ref
    +        if (preg_match('/po_/i', $txn->source)){
    +            $origin="payouts";
    +        } elseif (preg_match('/fee_/i', $txn->source)) {
    +            $origin="connect/application_fees";
    +        } else {
    +            $origin="payments";
    +        }
    +
    +		$url='https://dashboard.stripe.com/'.$connect.'test/'.$origin.'/'.$txn->source;
    +		if ($servicestatus) {
    +			$url='https://dashboard.stripe.com/'.$connect.$origin.'/'.$txn->source;
    +		}
    +        if ($txn->type == 'stripe_fee' || $txn->type == 'reserve_transaction') {
    +            print "<td>".$txn->type."</td>";
    +        } else {
    +            print "<td><a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')." " . $txn->source . "</a></td>\n";
    +        }
    +
     		// Stripe customer
    -		//print "<TD>".$charge->customer."</TD>\n";
    +		//print "<td>".$charge->customer."</td>\n";
     		// Link
    -		/*print "<TD>";
    +		/*print "<td>";
     		if ($societestatic->id > 0)
     		{
     			print $societestatic->getNomUrl(1);
    @@ -171,42 +194,42 @@ if (! $rowid) {
     		{
     			print $memberstatic->getNomUrl(1);
     		}
    -		print "</TD>\n";*/
    +		print "</td>\n";*/
     		// Origine
    -		print "<TD>";
    -		print $FULLTAG;
    -		if ($charge->metadata->source=="order"){
    -			$object = new Commande($db);
    -			$object->fetch($charge->metadata->idsource);
    -			print "<A href='".DOL_URL_ROOT."/commande/card.php?id=".$charge->metadata->idsource."'>".img_picto('', 'object_order')." ".$object->ref."</A>";
    -		} elseif ($charge->metadata->source=="invoice"){
    -			$object = new Facture($db);
    -			$object->fetch($charge->metadata->idsource);
    -			print "<A href='".DOL_URL_ROOT."/compta/facture/card.php?facid=".$charge->metadata->idsource."'>".img_picto('', 'object_invoice')." ".$object->ref."</A>";
    -		}
    -		print "</TD>\n";
    +		//print "<td>";
    +		////if ($charge->metadata->dol_type=="order"){
    +		//	$object = new Commande($db);
    +		//	$object->fetch($charge->metadata->dol_id);
    +		//	print "<a href='".DOL_URL_ROOT."/commande/card.php?id=".$charge->metadata->dol_id."'>".img_picto('', 'object_order')." ".$object->ref."</a>";
    +		//} elseif ($charge->metadata->dol_type=="invoice"){
    +		//	$object = new Facture($db);
    +		//	$object->fetch($charge->metadata->dol_id);
    +		//	print "<a href='".DOL_URL_ROOT."/compta/facture/card.php?facid=".$charge->metadata->dol_id."'>".img_picto('', 'object_invoice')." ".$object->ref."</a>";
    +		//}
    +		//print "</td>\n";
     		// Date payment
    -		print '<TD align="center">' . dol_print_date($txn->created, '%d/%m/%Y %H:%M') . "</TD>\n";
    +		print '<td align="center">' . dol_print_date($txn->created, '%d/%m/%Y %H:%M') . "</td>\n";
     		// Type
    -		print '<TD>' . $txn->type . '</TD>';
    +		print '<td>' . $txn->type . '</td>';
     		// Amount
    -		print "<TD align=\"right\">" . price(($txn->amount) / 100) . "</TD>";
    -		print "<TD align=\"right\">" . price(($txn->fee) / 100) . "</TD>";
    +		print "<td align=\"right\">" . price(($txn->amount) / 100, 0, '', 1, - 1, - 1, strtoupper($txn->currency)) . "</td>";
    +		print "<td align=\"right\">" . price(($txn->fee) / 100, 0, '', 1, - 1, - 1, strtoupper($txn->currency)) . "</td>";
     		// Status
    -		print "<TD align='right'>";
    -if ($txn->status=='available')
    - {print img_picto($langs->trans("".$txn->status.""),'statut4');} 
    -elseif ($txn->status=='pending')
    - {print img_picto($langs->trans("".$txn->status.""),'statut7');}
    -elseif ($txn->status=='failed')
    - {print img_picto($langs->trans("".$txn->status.""),'statut8');}        
    -		print '</TD>';
    -		print "</TR>\n";
    +		print "<td align='right'>";
    +		if ($txn->status=='available')
    + 		{print img_picto($langs->trans("".$txn->status.""),'statut4');}
    +		elseif ($txn->status=='pending')
    +		{print img_picto($langs->trans("".$txn->status.""),'statut7');}
    +		elseif ($txn->status=='failed')
    +		{print img_picto($langs->trans("".$txn->status.""),'statut8');}
    +		print '</td>';
    +		print "</tr>\n";
     	}
    -	print "</TABLE>";
    -	print '</DIV>';
    -	print '</FORM>';
    -} else {}
    +	print "</table>";
    +	print '</div>';
    +	print '</form>';
    +}
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/supplier_proposal/admin/supplier_proposal_extrafields.php b/htdocs/supplier_proposal/admin/supplier_proposal_extrafields.php
    index 545d953e753..24ae20848f1 100644
    --- a/htdocs/supplier_proposal/admin/supplier_proposal_extrafields.php
    +++ b/htdocs/supplier_proposal/admin/supplier_proposal_extrafields.php
    @@ -143,6 +143,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/supplier_proposal/admin/supplier_proposaldet_extrafields.php b/htdocs/supplier_proposal/admin/supplier_proposaldet_extrafields.php
    index 1acf85b45a3..7d153a78cdc 100644
    --- a/htdocs/supplier_proposal/admin/supplier_proposaldet_extrafields.php
    +++ b/htdocs/supplier_proposal/admin/supplier_proposaldet_extrafields.php
    @@ -113,7 +113,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
         print '<div class="tabsAction">';
    -    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +    print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
         print "</div>";
     }
     
    @@ -126,8 +126,8 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -    print "<br>";
    -    print load_fiche_titre($langs->trans('NewAttribute'));
    +	print '<br><div id="newattrib"></div>';
    +	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
     }
    @@ -145,6 +145,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php
    index d133e1fe4f7..248165727cf 100644
    --- a/htdocs/supplier_proposal/card.php
    +++ b/htdocs/supplier_proposal/card.php
    @@ -1,15 +1,16 @@
     <?php
    -/* Copyright (C) 2001-2007 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2017 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C) 2004      Eric Seigne           <eric.seigne@ryxeo.com>
    - * Copyright (C) 2005      Marc Barilley / Ocebo <marc@ocebo.com>
    - * Copyright (C) 2005-2012 Regis Houssin         <regis.houssin@capnetworks.com>
    - * Copyright (C) 2006      Andre Cianfarani      <acianfa@free.fr>
    - * Copyright (C) 2010-2014 Juanjo Menent         <jmenent@2byte.es>
    - * Copyright (C) 2010-2011 Philippe Grand        <philippe.grand@atoo-net.com>
    - * Copyright (C) 2012-2013 Christophe Battarel   <christophe.battarel@altairis.fr>
    - * Copyright (C) 2013-2014 Florian Henry		 <florian.henry@open-concept.pro>
    - * Copyright (C) 2014	   Ferran Marcet		 <fmarcet@2byte.es>
    +/* Copyright (C) 2001-2007  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2004       Eric Seigne             <eric.seigne@ryxeo.com>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2006       Andre Cianfarani        <acianfa@free.fr>
    + * Copyright (C) 2010-2014  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2010-2011  Philippe Grand          <philippe.grand@atoo-net.com>
    + * Copyright (C) 2012-2013  Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2014       Ferran Marcet           <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -624,7 +625,11 @@ if (empty($reshook))
     				{
     					$label = $productsupplier->label;
     
    -					$desc = $productsupplier->description;
    +					// if we use supplier description of the products
    +					if(!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) {
    +					    $desc = $productsupplier->desc_supplier;
    +					} else $desc = $productsupplier->description;
    +
     					if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc);
     
     					$pu_ht = $productsupplier->fourn_pu;
    @@ -788,7 +793,7 @@ if (empty($reshook))
     	}
     
     	// Mise a jour d'une ligne dans la demande de prix
    -	else if ($action == 'updateligne' && $user->rights->supplier_proposal->creer && GETPOST('save') == $langs->trans("Save")) {
    +	else if ($action == 'updateline' && $user->rights->supplier_proposal->creer && GETPOST('save') == $langs->trans("Save")) {
     
     		// Define info_bits
     		$info_bits = 0;
    @@ -914,7 +919,7 @@ if (empty($reshook))
     		}
     	}
     
    -	else if ($action == 'updateligne' && $user->rights->supplier_proposal->creer && GETPOST('cancel','alpha') == $langs->trans('Cancel')) {
    +	else if ($action == 'updateline' && $user->rights->supplier_proposal->creer && GETPOST('cancel','alpha') == $langs->trans('Cancel')) {
     		header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
     		exit();
     	}
    @@ -1129,9 +1134,9 @@ if ($action == 'create')
     		$syear = date("Y", $tmpdte);
     		$smonth = date("m", $tmpdte);
     		$sday = date("d", $tmpdte);
    -		$form->select_date($syear."-".$smonth."-".$sday, 'liv_', '', '', '', "addask");
    +		print $form->selectDate($syear."-".$smonth."-".$sday, 'liv_', '', '', '', "addask");
     	} else {
    -		$form->select_date($datedelivery ? $datedelivery : -1, 'liv_', '', '', '', "addask", 1, 1);
    +		print $form->selectDate($datedelivery ? $datedelivery : -1, 'liv_', '', '', '', "addask", 1, 1);
     	}
     	print '</td></tr>';
     
    @@ -1298,7 +1303,6 @@ if ($action == 'create')
     
     		print '</table>';
     	}
    -
     } else {
     	/*
     	 * Show object in view mode
    @@ -1368,12 +1372,11 @@ if ($action == 'create')
     			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ValidateAsk'), $text, 'confirm_validate', '', 0, 1);
     	}
     
    -	if (! $formconfirm) {
    -		$parameters = array('lineid' => $lineid);
    -		$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -		if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -		elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    @@ -1488,7 +1491,7 @@ if ($action == 'create')
     		print '<form name="editdate_livraison" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
     		print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
     		print '<input type="hidden" name="action" value="setdate_livraison">';
    -		$form->select_date($object->date_livraison, 'liv_', '', '', '', "editdate_livraison");
    +		print $form->selectDate($object->date_livraison, 'liv_', '', '', '', "editdate_livraison");
     		print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     		print '</form>';
     	} else {
    @@ -1687,7 +1690,7 @@ if ($action == 'create')
     
     	print '	<form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#add' : '#line_' . GETPOST('lineid')) . '" method="POST">
     	<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
    -	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateligne') . '">
    +	<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
     	<input type="hidden" name="mode" value="">
     	<input type="hidden" name="id" value="' . $object->id . '">
     	';
    diff --git a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php
    index 306c7e3e177..fd490902049 100644
    --- a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php
    +++ b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php
    @@ -94,7 +94,8 @@ class Supplierproposals extends DolibarrApi
     	 * @param string    $sqlfilters         Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.datec:<:'20160101')"
     	 * @return  array                       Array of order objects
     	 */
    -	function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
    +    {
     		global $db, $conf;
     
     		$obj_ret = array();
    @@ -184,30 +185,30 @@ class Supplierproposals extends DolibarrApi
     			if (!isset($data[$field]))
     				throw new RestException(400, "$field field missing");
     			$propal[$field] = $data[$field];
    -
     		}
     		return $propal;
     	}
     
     
    -	/**
    -	 * Clean sensible object datas
    -	 *
    -	 * @param   object  $object    Object to clean
    -	 * @return    array    Array of cleaned object properties
    -	 */
    -	function _cleanObjectDatas($object) {
    +    /**
    +     * Clean sensible object datas
    +     *
    +     * @param   object  $object    Object to clean
    +     * @return    array    Array of cleaned object properties
    +     */
    +    function _cleanObjectDatas($object)
    +    {
     
    -		$object = parent::_cleanObjectDatas($object);
    +        $object = parent::_cleanObjectDatas($object);
     
    -		unset($object->name);
    -		unset($object->lastname);
    -		unset($object->firstname);
    -		unset($object->civility_id);
    -		unset($object->address);
    -		unset($object->datec);
    -		unset($object->datev);
    +        unset($object->name);
    +        unset($object->lastname);
    +        unset($object->firstname);
    +        unset($object->civility_id);
    +        unset($object->address);
    +        unset($object->datec);
    +        unset($object->datev);
     
    -		return $object;
    -	}
    +        return $object;
    +    }
     }
    diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php
    index c3b6e4b3338..a05d0485aaf 100644
    --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php
    +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php
    @@ -7,7 +7,7 @@
      * Copyright (C) 2006      Andre Cianfarani			<acianfa@free.fr>
      * Copyright (C) 2008      Raphael Bertrand			<raphael.bertrand@resultic.fr>
      * Copyright (C) 2010-2015 Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2010-2011 Philippe Grand			<philippe.grand@atoo-net.com>
    + * Copyright (C) 2010-2018 Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2012-2014 Christophe Battarel  	<christophe.battarel@altairis.fr>
      * Copyright (C) 2013      Florian Henry		  	<florian.henry@open-concept.pro>
      * Copyright (C) 2014      Marcos García            <marcosgdf@gmail.com>
    @@ -45,16 +45,34 @@ require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php';
      */
     class SupplierProposal extends CommonObject
     {
    -    public $element='supplier_proposal';
    -    public $table_element='supplier_proposal';
    -    public $table_element_line='supplier_proposaldet';
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='supplier_proposal';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='supplier_proposal';
    +
    +    /**
    +	 * @var int    Name of subtable line
    +	 */
    +	public $table_element_line='supplier_proposaldet';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
         public $fk_element='fk_supplier_proposal';
    +
         public $picto='propal';
    +
         /**
          * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
          * @var int
          */
         public $ismultientitymanaged = 1;
    +
         /**
          * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
          * @var integer
    @@ -66,24 +84,25 @@ class SupplierProposal extends CommonObject
          */
         protected $table_ref_field = 'ref';
     
    -    var $socid;		// Id client
    +    public $socid;		// Id client
     
     	/**
     	 * @deprecated
     	 * @see user_author_id
     	 */
    -    var $author;
    -    var $ref_fourn;					//Reference saisie lors de l'ajout d'une ligne à la demande
    -    var $ref_supplier;				//Reference saisie lors de l'ajout d'une ligne à la demande
    -    var $statut;					// 0 (draft), 1 (validated), 2 (signed), 3 (not signed), 4 (processed/billed)
    -    var $date;						// Date of proposal
    -    var $date_livraison;
    +    public $author;
    +
    +    public $ref_fourn;					//Reference saisie lors de l'ajout d'une ligne à la demande
    +    public $ref_supplier;				//Reference saisie lors de l'ajout d'une ligne à la demande
    +    public $statut;					// 0 (draft), 1 (validated), 2 (signed), 3 (not signed), 4 (processed/billed)
    +    public $date;						// Date of proposal
    +    public $date_livraison;
     
     	/**
     	 * @deprecated
     	 * @see date_creation
     	 */
    -	var $datec;
    +	public $datec;
     
     	/**
     	 * Creation date
    @@ -95,7 +114,7 @@ class SupplierProposal extends CommonObject
     	 * @deprecated
     	 * @see date_validation
     	 */
    -	var $datev;
    +	public $datev;
     
     	/**
     	 * Validation date
    @@ -104,70 +123,80 @@ class SupplierProposal extends CommonObject
     	public $date_validation;
     
     
    -    var $user_author_id;
    -    var $user_valid_id;
    -    var $user_close_id;
    +    public $user_author_id;
    +    public $user_valid_id;
    +    public $user_close_id;
     
     	/**
     	 * @deprecated
     	 * @see price_ht
     	 */
    -    var $price;
    +    public $price;
    +
     	/**
     	 * @deprecated
     	 * @see total_tva
     	 */
    -    var $tva;
    +    public $tva;
    +
     	/**
     	 * @deprecated
     	 * @see total_ttc
     	 */
    -    var $total;
    +    public $total;
     
    -    var $cond_reglement_code;
    -    var $mode_reglement_code;
    -    var $remise = 0;
    -    var $remise_percent = 0;
    -    var $remise_absolue = 0;
    +    public $cond_reglement_code;
    +    public $mode_reglement_code;
    +    public $remise = 0;
    +    public $remise_percent = 0;
    +    public $remise_absolue = 0;
     
    -    var $products=array();
    -    var $extraparams=array();
    +    public $products=array();
    +    public $extraparams=array();
     
    -    var $lines = array();
    -    var $line;
    +    public $lines = array();
    +    public $line;
     
    -    var $labelstatut=array();
    -    var $labelstatut_short=array();
    +    public $labelstatut=array();
    +    public $labelstatut_short=array();
     
    -    var $nbtodo;
    -    var $nbtodolate;
    +    public $nbtodo;
    +    public $nbtodolate;
     
    -    var $specimen;
    +    public $specimen;
     
     	// Multicurrency
    -	var $fk_multicurrency;
    -	var $multicurrency_code;
    -	var $multicurrency_tx;
    -	var $multicurrency_total_ht;
    -	var $multicurrency_total_tva;
    -	var $multicurrency_total_ttc;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_multicurrency;
    +
    +	public $multicurrency_code;
    +	public $multicurrency_tx;
    +	public $multicurrency_total_ht;
    +	public $multicurrency_total_tva;
    +	public $multicurrency_total_ttc;
     
     	/**
     	 * Draft status
     	 */
     	const STATUS_DRAFT = 0;
    +
     	/**
     	 * Validated status
     	 */
     	const STATUS_VALIDATED = 1;
    +
     	/**
     	 * Signed quote
     	 */
     	const STATUS_SIGNED = 2;
    +
     	/**
     	 * Not signed quote, canceled
     	 */
     	const STATUS_NOTSIGNED = 3;
    +
     	/**
     	 * Billed or closed/processed quote
     	 */
    @@ -195,9 +224,10 @@ class SupplierProposal extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * 	Add line into array products
    -     *	$this->client doit etre charge
    +     *  $this->client doit etre charge
          *
          * 	@param  int		$idproduct       	Product Id to add
          * 	@param  int		$qty             	Quantity
    @@ -209,6 +239,7 @@ class SupplierProposal extends CommonObject
          */
         function add_product($idproduct, $qty, $remise_percent=0)
         {
    +        // phpcs:enable
             global $conf, $mysoc;
     
             if (! $qty) $qty = 1;
    @@ -250,6 +281,7 @@ class SupplierProposal extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Adding line of fixed discount in the proposal in DB
          *
    @@ -258,6 +290,7 @@ class SupplierProposal extends CommonObject
          */
         function insert_discount($idremise)
         {
    +        // phpcs:enable
             global $langs;
     
             include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
    @@ -1064,6 +1097,7 @@ class SupplierProposal extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Insert into DB a supplier_proposal object completely defined by its data members (ex, results from copy).
          *
    @@ -1073,6 +1107,7 @@ class SupplierProposal extends CommonObject
          */
         function create_from($user)
         {
    +        // phpcs:enable
             $this->products=$this->lines;
     
             return $this->create($user);
    @@ -1493,6 +1528,7 @@ class SupplierProposal extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Set delivery date
          *
    @@ -1502,6 +1538,7 @@ class SupplierProposal extends CommonObject
          */
         function set_date_livraison($user, $date_livraison)
         {
    +        // phpcs:enable
             if (! empty($user->rights->supplier_proposal->creer))
             {
                 $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal ";
    @@ -1522,6 +1559,7 @@ class SupplierProposal extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Set an overall discount on the proposal
          *
    @@ -1531,6 +1569,7 @@ class SupplierProposal extends CommonObject
          */
         function set_remise_percent($user, $remise)
         {
    +        // phpcs:enable
             $remise=trim($remise)?trim($remise):0;
     
             if (! empty($user->rights->supplier_proposal->creer))
    @@ -1555,6 +1594,7 @@ class SupplierProposal extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Set an absolute overall discount on the proposal
          *
    @@ -1564,6 +1604,7 @@ class SupplierProposal extends CommonObject
          */
         function set_remise_absolue($user, $remise)
         {
    +        // phpcs:enable
             $remise=trim($remise)?trim($remise):0;
     
             if (! empty($user->rights->supplier_proposal->creer))
    @@ -1689,7 +1730,6 @@ class SupplierProposal extends CommonObject
                     {
                         $result = $this->updateOrCreatePriceFournisseur($user);
                     }
    -
                 }
                 if ($statut == 4)
                 {
    @@ -1775,7 +1815,8 @@ class SupplierProposal extends CommonObject
     	 *	@param      User	$user					Object user
          *	@return     int         					<0 if KO, >0 if OK
          */
    -     function updatePriceFournisseur($idProductFournPrice, $product, $user) {
    +    function updatePriceFournisseur($idProductFournPrice, $product, $user)
    +    {
     		$price=price2num($product->subprice*$product->qty,'MU');
     		$unitPrice = price2num($product->subprice,'MU');
     
    @@ -1787,7 +1828,7 @@ class SupplierProposal extends CommonObject
                 $this->db->rollback();
                 return -1;
     		}
    -	 }
    +	}
     
     	 /**
          *	Create ProductFournisseur
    @@ -1796,7 +1837,8 @@ class SupplierProposal extends CommonObject
     	 *	@param      User		$user		Object user
          *	@return     int         			<0 if KO, >0 if OK
          */
    -	 function createPriceFournisseur($product, $user) {
    +    function createPriceFournisseur($product, $user)
    +    {
     	 	$price=price2num($product->subprice*$product->qty,'MU');
     	    $qty=price2num($product->qty);
     		$unitPrice = price2num($product->subprice,'MU');
    @@ -1823,16 +1865,18 @@ class SupplierProposal extends CommonObject
                 $this->db->rollback();
                 return -1;
     		}
    -	 }
    +	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *	Set draft status
    +     *  Set draft status
          *
          *	@param		User	$user		Object user that modify
          *	@return		int					<0 if KO, >0 if OK
          */
         function set_draft($user)
         {
    +        // phpcs:enable
             global $conf,$langs;
     
             $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal SET fk_statut = 0";
    @@ -1851,6 +1895,7 @@ class SupplierProposal extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return list of askprice (eventually filtered on user) into an array
          *
    @@ -1866,6 +1911,7 @@ class SupplierProposal extends CommonObject
          */
         function liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datec', $sortorder='DESC')
         {
    +        // phpcs:enable
             global $conf,$user;
     
             $ga = array();
    @@ -2091,11 +2137,8 @@ class SupplierProposal extends CommonObject
                         $cluser->fetch($obj->fk_user_cloture);
                         $this->user_cloture     = $cluser;
                     }
    -
    -
                 }
                 $this->db->free($result);
    -
             }
             else
             {
    @@ -2115,15 +2158,17 @@ class SupplierProposal extends CommonObject
             return $this->LibStatut($this->statut,$mode);
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    -     *    	Return label of a status (draft, validated, ...)
    +     *  Return label of a status (draft, validated, ...)
          *
    -     *    	@param      int			$statut		id statut
    -     *    	@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		Label
    +     *  @param      int			$statut		id statut
    +     *  @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      Label
          */
     	function LibStatut($statut,$mode=1)
         {
    +        // phpcs:enable
         	// Init/load array of translation of status
         	if (empty($this->labelstatut) || empty($this->labelstatut_short))
         	{
    @@ -2143,30 +2188,32 @@ class SupplierProposal extends CommonObject
     
         	$statuttrans='';
     		if ($statut==0) $statuttrans='statut0';
    -		if ($statut==1) $statuttrans='statut1';
    -		if ($statut==2) $statuttrans='statut3';
    -		if ($statut==3) $statuttrans='statut5';
    -		if ($statut==4) $statuttrans='statut6';
    +		elseif ($statut==1) $statuttrans='statut1';
    +		elseif ($statut==2) $statuttrans='statut3';
    +		elseif ($statut==3) $statuttrans='statut5';
    +		elseif ($statut==4) $statuttrans='statut6';
     
     		if ($mode == 0)	return $this->labelstatut[$statut];
    -		if ($mode == 1)	return $this->labelstatut_short[$statut];
    -		if ($mode == 2)	return img_picto($this->labelstatut[$statut], $statuttrans).' '.$this->labelstatut_short[$statut];
    -		if ($mode == 3)	return img_picto($this->labelstatut[$statut], $statuttrans);
    -		if ($mode == 4)	return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut];
    -		if ($mode == 5)	return '<span class="hideonsmartphone">'.$this->labelstatut_short[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    -		if ($mode == 6)	return '<span class="hideonsmartphone">'.$this->labelstatut[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    +		elseif ($mode == 1)	return $this->labelstatut_short[$statut];
    +		elseif ($mode == 2)	return img_picto($this->labelstatut[$statut], $statuttrans).' '.$this->labelstatut_short[$statut];
    +		elseif ($mode == 3)	return img_picto($this->labelstatut[$statut], $statuttrans);
    +		elseif ($mode == 4)	return img_picto($this->labelstatut[$statut],$statuttrans).' '.$this->labelstatut[$statut];
    +		elseif ($mode == 5)	return '<span class="hideonsmartphone">'.$this->labelstatut_short[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
    +		elseif ($mode == 6)	return '<span class="hideonsmartphone">'.$this->labelstatut[$statut].' </span>'.img_picto($this->labelstatut[$statut],$statuttrans);
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *      Load indicators for dashboard (this->nbtodo and this->nbtodolate)
          *
          *      @param          User	$user   Object user
          *      @param          int		$mode   "opened" for askprice to close, "signed" for proposal to invoice
    -     *      @return         int     		<0 if KO, >0 if OK
    +     *      @return         int             <0 if KO, >0 if OK
          */
         function load_board($user,$mode)
         {
    +        // phpcs:enable
             global $conf, $user, $langs;
     
             $now=dol_now();
    @@ -2318,6 +2365,7 @@ class SupplierProposal extends CommonObject
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *      Charge indicateurs this->nb de tableau de bord
          *
    @@ -2325,6 +2373,7 @@ class SupplierProposal extends CommonObject
          */
         function load_state_board()
         {
    +        // phpcs:enable
             global $conf, $user;
     
             $this->nb=array();
    @@ -2625,7 +2674,6 @@ class SupplierProposal extends CommonObject
     
     	    return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
     	}
    -
     }
     
     
    @@ -2634,26 +2682,58 @@ class SupplierProposal extends CommonObject
      */
     class SupplierProposalLine extends CommonObjectLine
     {
    -    var $db;
    -    var $error;
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
     
    -    public $element='supplier_proposaldet';
    -    public $table_element='supplier_proposaldet';
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error='';
     
    -    var $oldline;
    +    /**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='supplier_proposaldet';
    +
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='supplier_proposaldet';
    +
    +    public $oldline;
     
         // From llx_supplier_proposaldet
    -    var $rowid; // deprecated
    -    var $id;
    -    var $fk_supplier_proposal;
    -    var $fk_parent_line;
    -    var $desc;          	// Description ligne
    -    var $fk_product;		// Id produit predefini
    +    public $rowid; // deprecated
    +
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
    +
    +	/**
    +     * @var int ID
    +     */
    +    public $fk_supplier_proposal;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_parent_line;
    +
    +    public $desc;          	// Description ligne
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_product;		// Id produit predefini
    +
     	/**
     	 * @deprecated
     	 * @see product_type
     	 */
    -	var $fk_product_type;
    +	public $fk_product_type;
     	/**
     	 * Product type
     	 * @var int
    @@ -2661,89 +2741,106 @@ class SupplierProposalLine extends CommonObjectLine
     	 */
         public $product_type = Product::TYPE_PRODUCT;
     
    -    var $qty;
    -    var $tva_tx;
    -    var $subprice;
    -    var $remise_percent;
    -    var $fk_remise_except;
    +    public $qty;
    +    public $tva_tx;
    +    public $subprice;
    +    public $remise_percent;
     
    -    var $rang = 0;
    +    /**
    +     * @var int ID
    +     */
    +    public $fk_remise_except;
     
    -	var $fk_fournprice;
    -	var $pa_ht;
    -	var $marge_tx;
    -	var $marque_tx;
    +    public $rang = 0;
     
    -    var $special_code;	// Tag for special lines (exlusive tags)
    +    /**
    +     * @var int ID
    +     */
    +	public $fk_fournprice;
    +
    +	public $pa_ht;
    +	public $marge_tx;
    +	public $marque_tx;
    +
    +    public $special_code;	// Tag for special lines (exlusive tags)
         // 1: frais de port
         // 2: ecotaxe
         // 3: option line (when qty = 0)
     
    -    var $info_bits = 0;	// Liste d'options cumulables:
    +    public $info_bits = 0;	// Liste d'options cumulables:
         // Bit 0: 	0 si TVA normal - 1 si TVA NPR
         // Bit 1:	0 ligne normale - 1 si ligne de remise fixe
     
    -    var $total_ht;			// Total HT  de la ligne toute quantite et incluant la remise ligne
    -    var $total_tva;			// Total TVA  de la ligne toute quantite et incluant la remise ligne
    -    var $total_ttc;			// Total TTC de la ligne toute quantite et incluant la remise ligne
    +    public $total_ht;			// Total HT  de la ligne toute quantite et incluant la remise ligne
    +    public $total_tva;			// Total TVA  de la ligne toute quantite et incluant la remise ligne
    +    public $total_ttc;			// Total TTC de la ligne toute quantite et incluant la remise ligne
     
     	/**
     	 * @deprecated
     	 * @see remise_percent, fk_remise_except
     	 */
    -    var $remise;
    +    public $remise;
    +
     	/**
     	 * @deprecated
     	 * @see subprice
     	 */
    -    var $price;
    +    public $price;
     
         // From llx_product
     	/**
     	 * @deprecated
     	 * @see product_ref
     	 */
    -	var $ref;
    +	public $ref;
    +
     	/**
     	 * Product reference
     	 * @var string
     	 */
     	public $product_ref;
    +
     	/**
     	 * @deprecated
     	 * @see product_label
     	 */
    -	var $libelle;
    +	public $libelle;
    +
     	/**
     	 *  Product label
     	 * @var string
     	 */
     	public $product_label;
    +
     	/**
     	 * Product description
     	 * @var string
     	 */
     	public $product_desc;
     
    -    var $localtax1_tx;		// Local tax 1
    -    var $localtax2_tx;		// Local tax 2
    -    var $localtax1_type;	// Local tax 1 type
    -	var $localtax2_type;	// Local tax 2 type
    -    var $total_localtax1;  	// Line total local tax 1
    -    var $total_localtax2;	// Line total local tax 2
    +    public $localtax1_tx;		// Local tax 1
    +    public $localtax2_tx;		// Local tax 2
    +    public $localtax1_type;	// Local tax 1 type
    +	public $localtax2_type;	// Local tax 2 type
    +    public $total_localtax1;  	// Line total local tax 1
    +    public $total_localtax2;	// Line total local tax 2
     
    -    var $skip_update_total; // Skip update price total for special lines
    +    public $skip_update_total; // Skip update price total for special lines
     
    -    var $ref_fourn;
    -    var $ref_supplier;
    +    public $ref_fourn;
    +    public $ref_supplier;
     
     	// Multicurrency
    -	var $fk_multicurrency;
    -	var $multicurrency_code;
    -	var $multicurrency_subprice;
    -	var $multicurrency_total_ht;
    -	var $multicurrency_total_tva;
    -	var $multicurrency_total_ttc;
    +	/**
    +     * @var int ID
    +     */
    +	public $fk_multicurrency;
    +
    +	public $multicurrency_code;
    +	public $multicurrency_subprice;
    +	public $multicurrency_total_ht;
    +	public $multicurrency_total_tva;
    +	public $multicurrency_total_ttc;
     
         /**
          * 	Class line Contructor
    @@ -3146,6 +3243,7 @@ class SupplierProposalLine extends CommonObjectLine
             }
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *	Update DB line fields total_xxx
          *	Used by migration
    @@ -3154,6 +3252,7 @@ class SupplierProposalLine extends CommonObjectLine
          */
         function update_total()
         {
    +        // phpcs:enable
             $this->db->begin();
     
             // Mise a jour ligne en base
    @@ -3178,6 +3277,4 @@ class SupplierProposalLine extends CommonObjectLine
                 return -2;
             }
         }
    -
     }
    -
    diff --git a/htdocs/supplier_proposal/contact.php b/htdocs/supplier_proposal/contact.php
    index fdf51406e8e..881fae4d1a7 100644
    --- a/htdocs/supplier_proposal/contact.php
    +++ b/htdocs/supplier_proposal/contact.php
    @@ -193,7 +193,6 @@ if ($id > 0 || ! empty($ref))
     
     		// Contacts lines
     		include DOL_DOCUMENT_ROOT.'/core/tpl/contacts.tpl.php';
    -
     	}
     	else
     	{
    @@ -202,6 +201,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/supplier_proposal/document.php b/htdocs/supplier_proposal/document.php
    index 12de448829e..cf500246290 100644
    --- a/htdocs/supplier_proposal/document.php
    +++ b/htdocs/supplier_proposal/document.php
    @@ -87,7 +87,7 @@ if ($object->id > 0)
     	$head = supplier_proposal_prepare_head($object);
     	dol_fiche_head($head, 'document', $langs->trans('CommRequest'), -1, 'supplier_proposal');
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -170,5 +170,6 @@ else
     	print $langs->trans("ErrorUnknown");
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/supplier_proposal/index.php b/htdocs/supplier_proposal/index.php
    index 0e1b51480c1..cec80662c41 100644
    --- a/htdocs/supplier_proposal/index.php
    +++ b/htdocs/supplier_proposal/index.php
    @@ -375,6 +375,6 @@ if (! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_propos
     
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/supplier_proposal/info.php b/htdocs/supplier_proposal/info.php
    index 3f83b4dca88..95a753272be 100644
    --- a/htdocs/supplier_proposal/info.php
    +++ b/htdocs/supplier_proposal/info.php
    @@ -123,5 +123,6 @@ print '</div>';
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/supplier_proposal/note.php b/htdocs/supplier_proposal/note.php
    index ba54859a207..ff531b05d83 100644
    --- a/htdocs/supplier_proposal/note.php
    +++ b/htdocs/supplier_proposal/note.php
    @@ -143,6 +143,6 @@ if ($id > 0 || ! empty($ref))
     	}
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/supplier_proposal/tpl/linkedobjectblock.tpl.php b/htdocs/supplier_proposal/tpl/linkedobjectblock.tpl.php
    index ca604e61fcc..794ed96f3ec 100644
    --- a/htdocs/supplier_proposal/tpl/linkedobjectblock.tpl.php
    +++ b/htdocs/supplier_proposal/tpl/linkedobjectblock.tpl.php
    @@ -36,12 +36,11 @@ $langs = $GLOBALS['langs'];
     $linkedObjectBlock = $GLOBALS['linkedObjectBlock'];
     
     $total=0; $ilink=0;
    -$var=true;
     foreach($linkedObjectBlock as $key => $objectlink)
     {
         $ilink++;
     
    -    $trclass=($var?'pair':'impair');
    +    $trclass='oddeven';
         if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) $trclass.=' liste_sub_total';
     ?>
         <tr class="<?php echo $trclass; ?>">
    diff --git a/htdocs/support/default.css b/htdocs/support/default.css
    index 17204387eb4..6737a6ede00 100644
    --- a/htdocs/support/default.css
    +++ b/htdocs/support/default.css
    @@ -1,4 +1,4 @@
    -/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org> 
    +/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2009 Laurent Destailleur  <eldy@users.sourceforge.net>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -147,7 +147,7 @@ padding: 4px 4px 4px 4px;
     
     tr.title
     {
    -background: #DDDFDD;	
    +background: #DDDFDD;
     }
     
     table { font-size: 12px; }
    diff --git a/htdocs/support/index.php b/htdocs/support/index.php
    index ab5d62df39e..bc0ef1a79c5 100644
    --- a/htdocs/support/index.php
    +++ b/htdocs/support/index.php
    @@ -34,9 +34,7 @@ if ($pos == '/') $pos = '';     // si $pos vaut /, on le met a ''
     if (! defined('DOL_URL_ROOT'))
     	define('DOL_URL_ROOT', $pos);	// URL racine relative
     
    -$langs->load("other");
    -$langs->load("help");
    -
    +$langs->loadLangs(array("other", $langs->load("help")));
     
     /*
      * View
    diff --git a/htdocs/support/online.php b/htdocs/support/online.php
    index 0f2dca142fc..01b2cb4dbd1 100644
    --- a/htdocs/support/online.php
    +++ b/htdocs/support/online.php
    @@ -30,9 +30,7 @@ if ($pos == '/') $pos = '';     // si $pos vaut /, on le met a ''
     define('DOL_URL_ROOT', $pos);	// URL racine relative
     
     
    -$langs->load("other");
    -$langs->load("help");
    -
    +$langs->loadLangs(array("other", "help"));
     
     /*
      * View
    diff --git a/htdocs/takepos/ChangeLog.md b/htdocs/takepos/ChangeLog.md
    new file mode 100644
    index 00000000000..7b623eaa252
    --- /dev/null
    +++ b/htdocs/takepos/ChangeLog.md
    @@ -0,0 +1,5 @@
    +# CHANGELOG TAKEPOS FOR <a href="https://www.dolibarr.org">DOLIBARR ERP CRM</a>
    +
    +## 1.0
    +Initial version
    +
    diff --git a/htdocs/takepos/README.md b/htdocs/takepos/README.md
    new file mode 100644
    index 00000000000..40d4742af27
    --- /dev/null
    +++ b/htdocs/takepos/README.md
    @@ -0,0 +1,100 @@
    +# TAKEPOS FOR <a href="https://www.takepos.com">DOLIBARR ERP CRM</a>
    +
    +## Features
    +Touch Screen POS
    +
    +<!--
    +![Screenshot takepos](img/screenshot_takepos.png?raw=true "TakePos"){imgmd}
    +-->
    +
    +Other modules are available on <a href="https://www.dolistore.com" target="_new">Dolistore.com</a>.
    +
    +
    +
    +### Translations
    +
    +Translations can be define manually by editing files into directories [langs](langs). 
    +
    +<!--
    +This module contains also a sample configuration for Transifex, under the hidden directory [.tx](.tx), so it is possible to manage translation using this service. 
    +
    +For more informations, see the [translator's documentation](https://wiki.dolibarr.org/index.php/Translator_documentation).
    +
    +There is a [Transifex project](https://transifex.com/projects/p/dolibarr-module-template) for this module.
    +-->
    +
    +
    +<!--
    +
    +Install
    +-------
    +
    +### From the ZIP file and GUI interface
    +
    +- If you get the module in a zip file (like when downloading it from the market place [Dolistore](https://www.dolistore.com)), go into
    +menu ```Home - Setup - Modules - Deploy external module``` and upload the zip file.
    +
    +
    +Note: If this screen tell you there is no custom directory, check your setup is correct: 
    +
    +- In your Dolibarr installation directory, edit the ```htdocs/conf/conf.php``` file and check that following lines are not commented:
    +
    +    ```php
    +    //$dolibarr_main_url_root_alt ...
    +    //$dolibarr_main_document_root_alt ...
    +    ```
    +
    +- Uncomment them if necessary (delete the leading ```//```) and assign a sensible value according to your Dolibarr installation
    +
    +    For example :
    +
    +    - UNIX:
    +        ```php
    +        $dolibarr_main_url_root_alt = '/custom';
    +        $dolibarr_main_document_root_alt = '/var/www/Dolibarr/htdocs/custom';
    +        ```
    +
    +    - Windows:
    +        ```php
    +        $dolibarr_main_url_root_alt = '/custom';
    +        $dolibarr_main_document_root_alt = 'C:/My Web Sites/Dolibarr/htdocs/custom';
    +        ```
    +        
    +### From a GIT repository
    +
    +- Clone the repository in ```$dolibarr_main_document_root_alt/takepos```
    +
    +```sh
    +cd ....../custom
    +git clone git@github.com:gitlogin/takepos.git takepos
    +```
    +
    +### <a name="final_steps"></a>Final steps
    +
    +From your browser:
    +
    +  - Log into Dolibarr as a super-administrator
    +  - Go to "Setup" -> "Modules"
    +  - You should now be able to find and enable the module
    +
    +
    +
    +-->
    +
    +
    +Licenses
    +--------
    +
    +### Main code
    +
    +![GPLv3 logo](img/gplv3.png)
    +
    +GPLv3 or (at your option) any later version.
    +
    +See [COPYING](COPYING) for more information.
    +
    +#### Documentation
    +
    +All texts and readmes.
    +
    +![GFDL logo](img/gfdl.png)
    diff --git a/htdocs/takepos/admin/about.php b/htdocs/takepos/admin/about.php
    new file mode 100644
    index 00000000000..27b5e51b03b
    --- /dev/null
    +++ b/htdocs/takepos/admin/about.php
    @@ -0,0 +1,75 @@
    +<?php
    +/* Copyright (C) 2004-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018 SuperAdmin
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    takepos/admin/about.php
    + * \ingroup takepos
    + * \brief   About page of module TakePos.
    + */
    +
    +require '../../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once '../lib/takepos.lib.php';
    +
    +// Translations
    +$langs->loadLangs(array("errors","admin","cashdesk"));
    +
    +// Access control
    +if (! $user->admin) {
    +	accessforbidden();
    +}
    +
    +// Parameters
    +$action = GETPOST('action', 'alpha');
    +$backtopage = GETPOST('backtopage', 'alpha');
    +
    +
    +/*
    + * Actions
    + */
    +
    +// None
    +
    +
    +/*
    + * View
    + */
    +
    +$form = new Form($db);
    +
    +$page_name = "TakePosAbout";
    +llxHeader('', $langs->trans($page_name));
    +
    +// Subheader
    +$linkback = '<a href="'.($backtopage?$backtopage:DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
    +
    +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_takepos@takepos');
    +
    +// Configuration header
    +$head = takeposAdminPrepareHead();
    +dol_fiche_head($head, 'about', '', 0, 'takepos@takepos');
    +
    +dol_include_once('/takepos/core/modules/modTakePos.class.php');
    +$tmpmodule = new modTakePos($db);
    +print $tmpmodule->getDescLong();
    +
    +// Page end
    +dol_fiche_end();
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/takepos/admin/orderprinters.php b/htdocs/takepos/admin/orderprinters.php
    new file mode 100644
    index 00000000000..4c72031b41b
    --- /dev/null
    +++ b/htdocs/takepos/admin/orderprinters.php
    @@ -0,0 +1,199 @@
    +<?php
    +/* Copyright (C) 2005       Matthieu Valleton   <mv@seeschloss.org>
    + * Copyright (C) 2005       Eric Seigne         <eric.seigne@ryxeo.com>
    + * Copyright (C) 2006-2016  Laurent Destailleur <eldy@users.sourceforge.net>
    + * Copyright (C) 2007       Patrick Raguin      <patrick.raguin@gmail.com>
    + * Copyright (C) 2005-2012  Regis Houssin       <regis.houssin@capnetworks.com>
    + * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *      \file       htdocs/takepos/admin/orderprinters.php
    + *      \ingroup    takepos
    + *      \brief      Home page of category area
    + */
    +
    +require '../../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    +
    +$langs->loadLangs(array("main"), "categories", "takepos", "printing");
    +
    +if (! $user->rights->categorie->lire) accessforbidden();
    +
    +$id=GETPOST('id','int');
    +$type=(GETPOST('type','aZ09') ? GETPOST('type','aZ09') : Categorie::TYPE_PRODUCT);
    +$catname=GETPOST('catname','alpha');
    +$action=GETPOST('action','alpha');
    +$printer1=GETPOST('printer1','alpha');
    +$printer2=GETPOST('printer2','alpha');
    +
    +if (is_numeric($type)) $type=Categorie::$MAP_ID_TO_CODE[$type];	// For backward compatibility
    +
    +/*
    + * Actions
    + */
    +print $action;
    +if ($action=="SavePrinter1"){
    +	$printedcategories=";";
    +	if (is_array($printer1)) foreach ($printer1 as $cat){
    +		$printedcategories=$printedcategories.$cat.";";
    +	}
    +	dolibarr_set_const($db,"TAKEPOS_PRINTED_CATEGORIES_1", $printedcategories,'chaine',0,'',$conf->entity);
    +}
    +
    +if ($action=="SavePrinter2"){
    +	$printedcategories=";";
    +	if (is_array($printer2)) foreach ($printer2 as $cat){
    +		$printedcategories=$printedcategories.$cat.";";
    +	}
    +	dolibarr_set_const($db,"TAKEPOS_PRINTED_CATEGORIES_2", $printedcategories,'chaine',0,'',$conf->entity);
    +}
    +
    +
    +/*
    + * View
    + */
    +
    +$categstatic = new Categorie($db);
    +$form = new Form($db);
    +
    +if ($type == Categorie::TYPE_PRODUCT)       { $title=$langs->trans("ProductsCategoriesArea");  $typetext='product'; }
    +elseif ($type == Categorie::TYPE_SUPPLIER)  { $title=$langs->trans("SuppliersCategoriesArea"); $typetext='supplier'; }
    +elseif ($type == Categorie::TYPE_CUSTOMER)  { $title=$langs->trans("CustomersCategoriesArea"); $typetext='customer'; }
    +elseif ($type == Categorie::TYPE_MEMBER)    { $title=$langs->trans("MembersCategoriesArea");   $typetext='member'; }
    +elseif ($type == Categorie::TYPE_CONTACT)   { $title=$langs->trans("ContactsCategoriesArea");  $typetext='contact'; }
    +elseif ($type == Categorie::TYPE_ACCOUNT)   { $title=$langs->trans("AccountsCategoriesArea");  $typetext='bank_account'; }
    +elseif ($type == Categorie::TYPE_PROJECT)   { $title=$langs->trans("ProjectsCategoriesArea");  $typetext='project'; }
    +elseif ($type == Categorie::TYPE_USER)      { $title=$langs->trans("UsersCategoriesArea");     $typetext='user'; }
    +else                                        { $title=$langs->trans("CategoriesArea");          $typetext='unknown'; }
    +
    +$arrayofjs=array('/includes/jquery/plugins/jquerytreeview/jquery.treeview.js', '/includes/jquery/plugins/jquerytreeview/lib/jquery.cookie.js');
    +$arrayofcss=array('/includes/jquery/plugins/jquerytreeview/jquery.treeview.css');
    +
    +llxHeader('',$title,'','',0,0,$arrayofjs,$arrayofcss);
    +
    +
    +print load_fiche_titre($langs->trans("OrderPrinters"));
    +
    +//print '<table border="0" width="100%" class="notopnoleftnoright">';
    +//print '<tr><td valign="top" width="30%" class="notopnoleft">';
    +print '<div class="fichecenter"><div class="fichethirdleft">';
    +
    +
    +//print '</td><td valign="top" width="70%">';
    +print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
    +
    +
    +//print '</td></tr></table>';
    +print '</div></div></div>';
    +
    +print '<div class="fichecenter"><br>';
    +
    +
    +// Charge tableau des categories
    +$cate_arbo = $categstatic->get_full_arbo($typetext);
    +
    +// Define fulltree array
    +$fulltree=$cate_arbo;
    +
    +// Define data (format for treeview)
    +$data=array();
    +$data[] = array('rowid'=>0,'fk_menu'=>-1,'title'=>"racine",'mainmenu'=>'','leftmenu'=>'','fk_mainmenu'=>'','fk_leftmenu'=>'');
    +foreach($fulltree as $key => $val)
    +{
    +	$categstatic->id=$val['id'];
    +	$categstatic->ref=$val['label'];
    +	$categstatic->color=$val['color'];
    +	$categstatic->type=$type;
    +	$li=$categstatic->getNomUrl(1,'',60);
    +	$desc=dol_htmlcleanlastbr($val['description']);
    +
    +	$data[] = array(
    +	'rowid'=>$val['rowid'],
    +	'fk_menu'=>$val['fk_menu'],
    +	'fk_menu'=>$val['fk_parent'],
    +	'label'=>$val['label']
    +	);
    +}
    +
    +//Printer1
    +print '<table class="liste nohover" width="100%">';
    +print '<tr class="liste_titre"><td>'.$langs->trans("Printer").' 1</td><td></td><td align="right">';
    +print '</td></tr>';
    +$nbofentries=(count($data) - 1);
    +print '<form action="orderprinters.php">';
    +if ($nbofentries > 0)
    +{
    +	print '<tr class="pair"><td colspan="3">';
    +	print '<input type="hidden" name="action" value="SavePrinter1">';
    +	foreach ($data as $row) {
    +		if (strpos($conf->global->TAKEPOS_PRINTED_CATEGORIES_1, ';'.$row["rowid"].';') !== false) $checked='checked'; else $checked='';
    +		if ($row["fk_menu"]==0) print '<input type="checkbox" name="printer1[]" value="'.$row["rowid"].'" '.$checked.'>'.$row["label"].'<br>';
    +	}
    +	print '</td></tr>';
    +}
    +else
    +{
    +	print '<tr class="pair">';
    +	print '<td colspan="3"><table class="nobordernopadding"><tr class="nobordernopadding"><td>'.img_picto_common('','treemenu/branchbottom.gif').'</td>';
    +	print '<td valign="middle">';
    +	print $langs->trans("NoCategoryYet");
    +	print '</td>';
    +	print '<td>&nbsp;</td>';
    +	print '</table></td>';
    +	print '</tr>';
    +}
    +print "</table>";
    +print '<input type="submit" value="'.$langs->trans("Save").'"></form><br><br>';
    +
    +//Printer2
    +print '<table class="liste nohover" width="100%">';
    +print '<tr class="liste_titre"><td>'.$langs->trans("Printer").' 2</td><td></td><td align="right">';
    +print '</td></tr>';
    +$nbofentries=(count($data) - 1);
    +print '<form action="orderprinters.php">';
    +if ($nbofentries > 0)
    +{
    +	print '<tr class="pair"><td colspan="3">';
    +	print '<input type="hidden" name="action" value="SavePrinter2">';
    +	foreach ($data as $row) {
    +		if (strpos($conf->global->TAKEPOS_PRINTED_CATEGORIES_2, ';'.$row["rowid"].';') !== false) $checked='checked'; else $checked='';
    +		if ($row["fk_menu"]==0) print '<input type="checkbox" name="printer2[]" value="'.$row["rowid"].'" '.$checked.'>'.$row["label"].'<br>';
    +	}
    +	print '</td></tr>';
    +}
    +else
    +{
    +	print '<tr class="pair">';
    +	print '<td colspan="3"><table class="nobordernopadding"><tr class="nobordernopadding"><td>'.img_picto_common('','treemenu/branchbottom.gif').'</td>';
    +	print '<td valign="middle">';
    +	print $langs->trans("NoCategoryYet");
    +	print '</td>';
    +	print '<td>&nbsp;</td>';
    +	print '</table></td>';
    +	print '</tr>';
    +}
    +print "</table>";
    +print '<input type="submit" value="'.$langs->trans("Save").'"></form>';
    +
    +print '</div>';
    +
    +llxFooter();
    +
    +$db->close();
    diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php
    new file mode 100644
    index 00000000000..453ecf64609
    --- /dev/null
    +++ b/htdocs/takepos/admin/setup.php
    @@ -0,0 +1,252 @@
    +<?php
    +/* Copyright (C) 2008-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2011-2017 Juanjo Menent		<jmenent@2byte.es>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *	\file       htdocs/takepos/admin/setup.php
    + *	\ingroup    takepos
    + *	\brief      Setup page for TakePos module
    + */
    +
    +require '../../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
    +
    +// If socid provided by ajax company selector
    +if (! empty($_REQUEST['CASHDESK_ID_THIRDPARTY_id']))
    +{
    +	$_GET['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id','alpha');
    +	$_POST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id','alpha');
    +	$_REQUEST['CASHDESK_ID_THIRDPARTY'] = GETPOST('CASHDESK_ID_THIRDPARTY_id','alpha');
    +}
    +
    +// Security check
    +if (!$user->admin) accessforbidden();
    +
    +$langs->loadLangs(array("admin", "cashdesk"));
    +
    +/*
    + * Actions
    + */
    +if (GETPOST('action','alpha') == 'set')
    +{
    +	$db->begin();
    +
    +	if (GETPOST('socid','int') < 0) $_POST["socid"]='';
    +
    +	$res = dolibarr_set_const($db,"CASHDESK_ID_THIRDPARTY",(GETPOST('socid','int') > 0 ? GETPOST('socid','int') : ''),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"CASHDESK_ID_BANKACCOUNT_CASH",(GETPOST('CASHDESK_ID_BANKACCOUNT_CASH','alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CASH','alpha') : ''),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"CASHDESK_ID_BANKACCOUNT_CHEQUE",(GETPOST('CASHDESK_ID_BANKACCOUNT_CHEQUE','alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CHEQUE','alpha') : ''),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"CASHDESK_ID_BANKACCOUNT_CB",(GETPOST('CASHDESK_ID_BANKACCOUNT_CB','alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CB','alpha') : ''),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"CASHDESK_ID_WAREHOUSE",(GETPOST('CASHDESK_ID_WAREHOUSE','alpha') > 0 ? GETPOST('CASHDESK_ID_WAREHOUSE','alpha') : ''),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"CASHDESK_NO_DECREASE_STOCK",GETPOST('CASHDESK_NO_DECREASE_STOCK','alpha'),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"CASHDESK_SERVICES", GETPOST('CASHDESK_SERVICES','alpha'),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"TAKEBOX", GETPOST('TAKEBOX','alpha'),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"TAKEPOS_BAR_RESTAURANT", GETPOST('TAKEPOS_BAR_RESTAURANT','alpha'),'chaine',0,'',$conf->entity);
    +    $res = dolibarr_set_const($db,"TAKEPOS_PRINT_SERVER", GETPOST('TAKEPOS_PRINT_SERVER','alpha'),'chaine',0,'',$conf->entity);
    +	$res = dolibarr_set_const($db,"TAKEPOS_ORDER_PRINTERS", GETPOST('TAKEPOS_ORDER_PRINTERS','alpha'),'chaine',0,'',$conf->entity);
    +
    +	dol_syslog("admin/cashdesk: level ".GETPOST('level','alpha'));
    +
    +	if (! $res > 0) $error++;
    +
    + 	if (! $error)
    +    {
    +        $db->commit();
    +	    setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        $db->rollback();
    +	    setEventMessages($langs->trans("Error"), null, 'errors');
    +    }
    +}
    +
    +/*
    + * View
    + */
    +
    +$form=new Form($db);
    +$formproduct=new FormProduct($db);
    +
    +llxHeader('',$langs->trans("CashDeskSetup"));
    +
    +$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
    +print load_fiche_titre($langs->trans("CashDeskSetup"),$linkback,'title_setup');
    +print '<br>';
    +
    +
    +// Mode
    +print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
    +print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +print '<input type="hidden" name="action" value="set">';
    +
    +print '<table class="noborder" width="100%">';
    +print '<tr class="liste_titre">';
    +print '<td>'.$langs->trans("Parameters").'</td><td>'.$langs->trans("Value").'</td>';
    +print "</tr>\n";
    +
    +print '<tr class="oddeven"><td width=\"50%\">'.$langs->trans("CashDeskThirdPartyForSell").'</td>';
    +print '<td colspan="2">';
    +print $form->select_company($conf->global->CASHDESK_ID_THIRDPARTY,'socid','s.client in (1,3) AND s.status = 1',1,0,1,array(),0);
    +print '</td></tr>';
    +if (! empty($conf->banque->enabled))
    +{
    +
    +	print '<tr class="oddeven"><td>'.$langs->trans("CashDeskBankAccountForSell").'</td>';
    +	print '<td colspan="2">';
    +	$form->select_comptes($conf->global->CASHDESK_ID_BANKACCOUNT_CASH,'CASHDESK_ID_BANKACCOUNT_CASH',0,"courant=2",1);
    +	print '</td></tr>';
    +
    +
    +	print '<tr class="oddeven"><td>'.$langs->trans("CashDeskBankAccountForCheque").'</td>';
    +	print '<td colspan="2">';
    +	$form->select_comptes($conf->global->CASHDESK_ID_BANKACCOUNT_CHEQUE,'CASHDESK_ID_BANKACCOUNT_CHEQUE',0,"courant=1",1);
    +	print '</td></tr>';
    +
    +
    +	print '<tr class="oddeven"><td>'.$langs->trans("CashDeskBankAccountForCB").'</td>';
    +	print '<td colspan="2">';
    +	$form->select_comptes($conf->global->CASHDESK_ID_BANKACCOUNT_CB,'CASHDESK_ID_BANKACCOUNT_CB',0,"courant=1",1);
    +	print '</td></tr>';
    +}
    +
    +if (! empty($conf->stock->enabled))
    +{
    +
    +	print '<tr class="oddeven"><td>'.$langs->trans("CashDeskDoNotDecreaseStock").'</td>';	// Force warehouse (this is not a default value)
    +	print '<td colspan="2">';
    +	if (empty($conf->productbatch->enabled)) {
    +	   print $form->selectyesno('CASHDESK_NO_DECREASE_STOCK',$conf->global->CASHDESK_NO_DECREASE_STOCK,1);
    +	}
    +	else
    +	{
    +	    if (!$conf->global->CASHDESK_NO_DECREASE_STOCK) {
    +	       $res = dolibarr_set_const($db,"CASHDESK_NO_DECREASE_STOCK",1,'chaine',0,'',$conf->entity);
    +	    }
    +	    print $langs->trans('StockDecreaseForPointOfSaleDisabledbyBatch');
    +	}
    +	print '</td></tr>';
    +
    +	$disabled=$conf->global->CASHDESK_NO_DECREASE_STOCK;
    +
    +
    +	print '<tr class="oddeven"><td>'.$langs->trans("CashDeskIdWareHouse").'</td>';	// Force warehouse (this is not a default value)
    +	print '<td colspan="2">';
    +	if (! $disabled)
    +	{
    +		print $formproduct->selectWarehouses($conf->global->CASHDESK_ID_WAREHOUSE,'CASHDESK_ID_WAREHOUSE','',1,$disabled);
    +		print ' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">('.$langs->trans("Create").')</a>';
    +	}
    +	else
    +	{
    +		print $langs->trans("StockDecreaseForPointOfSaleDisabled");
    +	}
    +	print '</td></tr>';
    +}
    +
    +if (! empty($conf->service->enabled))
    +{
    +    print '<tr class="oddeven"><td>';
    +    print $langs->trans("CashdeskShowServices");
    +    print '<td colspan="2">';
    +    print $form->selectyesno("CASHDESK_SERVICES",$conf->global->CASHDESK_SERVICES,1);
    +    print "</td></tr>\n";
    +}
    +
    +// Use Takepos printing
    +print '<tr class="oddeven"><td>';
    +print $langs->trans("DolibarrReceiptPrinter").' TakeBOX (<a href="http://en.takepos.com/takebox">'.$langs->trans("TakeboxNecesary").'</a>)';
    +print '<td colspan="2">';
    +print $form->selectyesno("TAKEBOX",$conf->global->TAKEBOX,1);
    +print "</td></tr>\n";
    +
    +if ($conf->global->TAKEBOX){
    +    print '<tr class="oddeven value"><td>';
    +    print $langs->trans("IPAddress").' (<a href="http://en.takepos.com/takebox">'.$langs->trans("TakeboxNecesary").'</a>)';
    +    print '<td colspan="2">';
    +    print '<input type="text" size="20" id="TAKEPOS_PRINT_SERVER" name="TAKEPOS_PRINT_SERVER" value="'.$conf->global->TAKEPOS_PRINT_SERVER.'">';
    +    print '</td></tr>';
    +}
    +
    +// Bar Restaurant mode
    +print '<tr class="oddeven"><td>';
    +print 'Bar Restaurant';
    +print '<td colspan="2">';
    +print $form->selectyesno("TAKEPOS_BAR_RESTAURANT",$conf->global->TAKEPOS_BAR_RESTAURANT,1);
    +print "</td></tr>\n";
    +
    +if ($conf->global->TAKEPOS_BAR_RESTAURANT and $conf->global->TAKEBOX){
    +    print '<tr class="oddeven value"><td>';
    +    print $langs->trans("OrderPrinters").' (<a href="orderprinters.php?leftmenu=setup">'.$langs->trans("Setup").'</a>)';
    +    print '<td colspan="2">';
    +    print $form->selectyesno("TAKEPOS_ORDER_PRINTERS",$conf->global->TAKEPOS_ORDER_PRINTERS,1);
    +    print '</td></tr>';
    +}
    +
    +print '</table>';
    +print '<br>';
    +
    +print '<div class="center"><input type="submit" class="button" value="'.$langs->trans("Save").'"></div>';
    +
    +print "</form>\n";
    +
    +
    +
    +// Marketplace
    +print "<br><table summary=\"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
    +print "<tr class=\"liste_titre\">\n";
    +print '<td colspan="2">TakePOS Marketplace</td>';
    +print '<td>'.$langs->trans("URL").'</td>';
    +print '</tr>';
    +
    +print "<tr class=\"oddeven\">\n";
    +$url='https://www.dolistore.com/en/modules/980-TakePOS-7-mobile.html';
    +print '<td align="left"><a href="'.$url.'" target="_blank" rel="external"><img border="0" class="imgautosize imgmaxwidth180" src="../img/marketplace/takeposmobile.jpg"></a></td>';
    +print '<td>TakePOS for mobile devices</td>';
    +print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';
    +print '</tr>';
    +
    +print "<tr class=\"oddeven\">\n";
    +$url='https://www.dolistore.com/en/modules/949-Cash-Control-7.html';
    +print '<td align="left"><a href="'.$url.'" target="_blank" rel="external"><img border="0" class="imgautosize imgmaxwidth180" src="../img/marketplace/cashcontrol.jpg"></a></td>';
    +print '<td>TakePOS CashControl</td>';
    +print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';
    +print '</tr>';
    +
    +print "</table>\n";
    +print '<br>';
    +
    +// Support
    +print "<br><table summary=\"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
    +print "<tr class=\"liste_titre\">\n";
    +print '<td colspan="2">TakePOS Support</td>';
    +print '<td>'.$langs->trans("URL").'</td>';
    +print '</tr>';
    +
    +print "<tr class=\"oddeven\">\n";
    +$url='http://www.takepos.com';
    +print '<td align="left"><a href="'.$url.'" target="_blank" rel="external"><img border="0" class="imgautosize imgmaxwidth180" src="../img/takepos.png"></a></td>';
    +print '<td>TakePOS original developers</td>';
    +print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';
    +print '</tr>';
    +
    +print "</table>\n";
    +print '<br>';
    +
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/takepos/ajax.php b/htdocs/takepos/ajax.php
    new file mode 100644
    index 00000000000..33d1503891e
    --- /dev/null
    +++ b/htdocs/takepos/ajax.php
    @@ -0,0 +1,62 @@
    +<?php
    +/* Copyright (C) 2001-2004	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *	\file       htdocs/takepos/ajax.php
    + *	\brief      Ajax search component for TakePos. It search products of a category.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +require '../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +
    +$category = GETPOST('category','alpha');
    +$action = GETPOST('action','alpha');
    +$term = GETPOST('term','alpha');
    +
    +
    +/*
    + * View
    + */
    +
    +if ($action=="getProducts"){
    +	$object = new Categorie($db);
    +	$result=$object->fetch($category);
    +	$prods = $object->getObjectsInCateg("product");
    +	echo json_encode($prods);
    +}
    +
    +if ($action=="search"){
    +	$sql = 'SELECT * FROM '.MAIN_DB_PREFIX.'product';
    +	$sql.= ' WHERE entity IN ('.getEntity('product').')';
    +	$sql .= natural_search(array('label','barcode'), $term);
    +	$resql = $db->query($sql);
    +	$rows = array();
    +	while($row = $db->fetch_array ($resql)){
    +		$rows[] = $row;
    +	}
    +	echo json_encode($rows);
    +}
    \ No newline at end of file
    diff --git a/htdocs/takepos/class/actions_takepos.class.php b/htdocs/takepos/class/actions_takepos.class.php
    new file mode 100644
    index 00000000000..2ed4a27525b
    --- /dev/null
    +++ b/htdocs/takepos/class/actions_takepos.class.php
    @@ -0,0 +1,219 @@
    +<?php
    +/* Copyright (C) 2018 SuperAdmin
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    takepos/class/actions_takepos.class.php
    + * \ingroup takepos
    + * \brief   Hooks of takepos module
    + */
    +
    +/**
    + * Class ActionsTakePos
    + */
    +class ActionsTakePos
    +{
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +    /**
    +     * @var string Error
    +     */
    +    public $error = '';
    +    /**
    +     * @var array Errors
    +     */
    +    public $errors = array();
    +
    +
    +	/**
    +	 * @var array Hook results. Propagated to $hookmanager->resArray for later reuse
    +	 */
    +	public $results = array();
    +
    +	/**
    +	 * @var string String displayed by executeHook() immediately after return
    +	 */
    +	public $resprints;
    +
    +
    +	/**
    +	 * Constructor
    +	 *
    +	 *  @param		DoliDB		$db      Database handler
    +	 */
    +	public function __construct($db)
    +	{
    +	    $this->db = $db;
    +	}
    +
    +	/**
    +	 * Overloading the doActions function : replacing the parent's function with the one below
    +	 *
    +	 * @param   array()         $parameters     Hook metadatas (context, etc...)
    +	 * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +	 * @param   string          $action         Current action (if set). Generally create or edit or null
    +	 * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
    +	 * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
    +	 */
    +	public function doActions($parameters, &$object, &$action, $hookmanager)
    +	{
    +		global $conf, $user, $langs;
    +
    +		$error = 0; // Error counter
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +	    if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2')))	    // do something only for the context 'somecontext1' or 'somecontext2'
    +	    {
    +			// Do what you want here...
    +			// You can for example call global vars like $fieldstosearchall to overwrite them, or update database depending on $action and $_POST values.
    +		}
    +
    +		if (! $error) {
    +			$this->results = array('myreturn' => 999);
    +			$this->resprints = 'A text to show';
    +			return 0;                                    // or return 1 to replace standard code
    +		} else {
    +			$this->errors[] = 'Error message';
    +			return -1;
    +		}
    +	}
    +
    +
    +	/**
    +	 * Overloading the doActions function : replacing the parent's function with the one below
    +	 *
    +	 * @param   array()         $parameters     Hook metadatas (context, etc...)
    +	 * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +	 * @param   string          $action         Current action (if set). Generally create or edit or null
    +	 * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
    +	 * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
    +	 */
    +	public function addMoreActionsButtons($parameters, &$object, &$action, $hookmanager)
    +	{
    +	    global $conf, $user, $langs;
    +
    +	    $error = 0; // Error counter
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +	    if (in_array($parameters['currentcontext'], array('invoicecard')))		// do something only for the context 'somecontext1' or 'somecontext2'
    +	    {
    +
    +			$receipt_url=DOL_URL_ROOT."/takepos/receipt.php";
    +	        print '<div class="inline-block divButAction"><a target="_blank" class="butAction" href="' . $receipt_url . '?facid=' . $object->id.'">' . $langs->trans('Ticket') .'</a></div>';
    +	    }
    +
    +	    if (! $error) {
    +	        $this->results = array('myreturn' => 999);
    +	        $this->resprints = 'A text to show';
    +	        return 0;                                    // or return 1 to replace standard code
    +	    } else {
    +	        $this->errors[] = 'Error message';
    +	        return -1;
    +	    }
    +	}
    +
    +
    +	/**
    +	 * Overloading the addMoreMassActions function : replacing the parent's function with the one below
    +	 *
    +	 * @param   array()         $parameters     Hook metadatas (context, etc...)
    +	 * @param   CommonObject    $object         The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...)
    +	 * @param   string          $action         Current action (if set). Generally create or edit or null
    +	 * @param   HookManager     $hookmanager    Hook manager propagated to allow calling another hook
    +	 * @return  int                             < 0 on error, 0 on success, 1 to replace standard code
    +	 */
    +	public function addMoreMassActions($parameters, &$object, &$action, $hookmanager)
    +	{
    +	    global $conf, $user, $langs;
    +
    +	    $error = 0; // Error counter
    +
    +        /* print_r($parameters); print_r($object); echo "action: " . $action; */
    +	    if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2')))		// do something only for the context 'somecontext1' or 'somecontext2'
    +	    {
    +	        $this->resprints = '<option value="0"'.($disabled?' disabled="disabled"':'').'>'.$langs->trans("TakePosMassAction").'</option>';
    +	    }
    +
    +	    if (! $error) {
    +	        return 0;                                    // or return 1 to replace standard code
    +	    } else {
    +	        $this->errors[] = 'Error message';
    +	        return -1;
    +	    }
    +	}
    +
    +
    +
    +	/**
    +	 * Execute action
    +	 *
    +	 * @param	array	$parameters		Array of parameters
    +	 * @param   Object	$object		   	Object output on PDF
    +	 * @param   string	$action     	'add', 'update', 'view'
    +	 * @return  int 		        	<0 if KO,
    +	 *                          		=0 if OK but we want to process standard actions too,
    +	 *  	                            >0 if OK and we want to replace standard actions.
    +	 */
    +	function beforePDFCreation($parameters, &$object, &$action)
    +	{
    +		global $langs,$conf;
    +		global $hookmanager;
    +
    +		$outputlangs=$langs;
    +
    +		$ret=0; $deltemp=array();
    +		dol_syslog(get_class($this).'::executeHooks action='.$action);
    +
    +		/* print_r($parameters); print_r($object); echo "action: " . $action; */
    +		if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2')))		// do something only for the context 'somecontext1' or 'somecontext2'
    +		{
    +
    +		}
    +
    +		return $ret;
    +	}
    +
    +	/**
    +	 * Execute action
    +	 *
    +	 * @param	array	$parameters		Array of parameters
    +	 * @param   Object	$pdfhandler   	PDF builder handler
    +	 * @param   string	$action     	'add', 'update', 'view'
    +	 * @return  int 		        	<0 if KO,
    +	 *                          		=0 if OK but we want to process standard actions too,
    +	 *  	                            >0 if OK and we want to replace standard actions.
    +	 */
    +	function afterPDFCreation($parameters, &$pdfhandler, &$action)
    +	{
    +		global $langs,$conf;
    +		global $hookmanager;
    +
    +		$outputlangs=$langs;
    +
    +		$ret=0; $deltemp=array();
    +		dol_syslog(get_class($this).'::executeHooks action='.$action);
    +
    +		/* print_r($parameters); print_r($object); echo "action: " . $action; */
    +		if (in_array($parameters['currentcontext'], array('somecontext1','somecontext2')))		// do something only for the context 'somecontext1' or 'somecontext2'
    +		{
    +
    +		}
    +
    +		return $ret;
    +	}
    +}
    diff --git a/htdocs/takepos/css/colorbox.css b/htdocs/takepos/css/colorbox.css
    new file mode 100644
    index 00000000000..e51a84c8282
    --- /dev/null
    +++ b/htdocs/takepos/css/colorbox.css
    @@ -0,0 +1,58 @@
    +/*
    +    Colorbox Core Style:
    +    The following CSS is consistent between example themes and should not be altered.
    +*/
    +#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden; -webkit-transform: translate3d(0,0,0);}
    +#cboxWrapper {max-width:none;}
    +#cboxOverlay{position:fixed; width:100%; height:100%;}
    +#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
    +#cboxContent{position:relative;}
    +#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
    +#cboxTitle{margin:0;}
    +#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
    +#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
    +.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
    +.cboxIframe{width:100%; height:100%; display:block; border:0; padding:0; margin:0;}
    +#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
    +
    +/*
    +    User Style:
    +    Change the following styles to modify the appearance of Colorbox.  They are
    +    ordered & tabbed in a way that represents the nesting of the generated HTML.
    +*/
    +#cboxOverlay{background:#000; opacity: 0.9; filter: alpha(opacity = 90);}
    +#colorbox{outline:0;}
    +#cboxTopLeft{width:14px; height:14px; background:url(images/controls.png) no-repeat 0 0;}
    +#cboxTopCenter{height:14px; background:url(images/border.png) repeat-x top left;}
    +#cboxTopRight{width:14px; height:14px; background:url(images/controls.png) no-repeat -36px 0;}
    +#cboxBottomLeft{width:14px; height:43px; background:url(images/controls.png) no-repeat 0 -32px;}
    +#cboxBottomCenter{height:43px; background:url(images/border.png) repeat-x bottom left;}
    +#cboxBottomRight{width:14px; height:43px; background:url(images/controls.png) no-repeat -36px -32px;}
    +#cboxMiddleLeft{width:14px; background:url(images/controls.png) repeat-y -175px 0;}
    +#cboxMiddleRight{width:14px; background:url(images/controls.png) repeat-y -211px 0;}
    +#cboxContent{background:#fff; overflow:visible;}
    +.cboxIframe{background:#fff;}
    +#cboxError{padding:50px; border:1px solid #ccc;}
    +#cboxLoadedContent{margin-bottom:5px;}
    +#cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
    +#cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
    +#cboxTitle{position:absolute; bottom:-25px; left:0; text-align:center; width:100%; font-weight:bold; color:#7C7C7C;}
    +#cboxCurrent{position:absolute; bottom:-25px; left:58px; font-weight:bold; color:#7C7C7C;}
    +
    +/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
    +#cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible;  position:absolute; bottom:-29px; background:url(images/controls.png) no-repeat 0px 0px; width:23px; height:23px; text-indent:-9999px;}
    +
    +/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
    +#cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
    +
    +#cboxPrevious{left:0px; background-position: -51px -25px;}
    +#cboxPrevious:hover{background-position:-51px 0px;}
    +#cboxNext{left:27px; background-position:-75px -25px;}
    +#cboxNext:hover{background-position:-75px 0px;}
    +#cboxClose{right:0; background-position:-100px -25px;}
    +#cboxClose:hover{background-position:-100px 0px;}
    +
    +.cboxSlideshow_on #cboxSlideshow{background-position:-125px 0px; right:27px;}
    +.cboxSlideshow_on #cboxSlideshow:hover{background-position:-150px 0px;}
    +.cboxSlideshow_off #cboxSlideshow{background-position:-150px -25px; right:27px;}
    +.cboxSlideshow_off #cboxSlideshow:hover{background-position:-125px 0px;}
    diff --git a/htdocs/takepos/css/images/border.png b/htdocs/takepos/css/images/border.png
    new file mode 100644
    index 00000000000..c1cd1a2a451
    Binary files /dev/null and b/htdocs/takepos/css/images/border.png differ
    diff --git a/htdocs/takepos/css/images/controls.png b/htdocs/takepos/css/images/controls.png
    new file mode 100644
    index 00000000000..259130cd537
    Binary files /dev/null and b/htdocs/takepos/css/images/controls.png differ
    diff --git a/htdocs/takepos/css/images/loading.gif b/htdocs/takepos/css/images/loading.gif
    new file mode 100644
    index 00000000000..dba33c8167b
    Binary files /dev/null and b/htdocs/takepos/css/images/loading.gif differ
    diff --git a/htdocs/takepos/css/images/loading_background.png b/htdocs/takepos/css/images/loading_background.png
    new file mode 100644
    index 00000000000..23a336b3989
    Binary files /dev/null and b/htdocs/takepos/css/images/loading_background.png differ
    diff --git a/htdocs/takepos/css/pos.css b/htdocs/takepos/css/pos.css
    new file mode 100644
    index 00000000000..8a2122de9f3
    --- /dev/null
    +++ b/htdocs/takepos/css/pos.css
    @@ -0,0 +1,114 @@
    +html,body {
    +    padding:0;
    +    margin:0;
    +    height:100%;
    +}
    +
    +body {
    +    width:100%;
    +}
    +
    +.row {
    +    width:100%;
    +    height:50%;
    +}
    +
    +.row div {
    +    width:33%;
    +    height:100%;
    +    float:left;
    +}
    +
    +button.calcbutton {
    +	display: inline-block;
    +	position: relative;
    +	padding: 0;
    +	line-height: normal;
    +	cursor: pointer;
    +	vertical-align: middle;
    +	text-align: center;
    +	font-size:180%;
    +	overflow: visible; /* removes extra width in IE */
    +	width:24%;
    +	height:24%;
    +}
    +
    +button.calcbutton2 {
    +	display: inline-block;
    +	position: relative;
    +	padding: 0;
    +	line-height: normal;
    +	cursor: pointer;
    +	vertical-align: middle;
    +	text-align: center;
    +	font-size:120%;
    +	overflow: visible; /* removes extra width in IE */
    +	width:24%;
    +	height:24%;
    +}
    +
    +button.actionbutton {
    +	display: inline-block;
    +	position: relative;
    +	padding: 0;
    +	line-height: normal;
    +	cursor: pointer;
    +	vertical-align: middle;
    +	text-align: center;
    +	font-size:100%;
    +	overflow: visible; /* removes extra width in IE */
    +	width:32%;
    +	height:32%;
    +}
    +
    +div.wrapper{
    +	float:left; /* important */
    +	position:relative; /* important(so we can absolutely position the description div */
    +	width:21.5%;
    +	height:23%;
    +	margin:1%;
    +	border: 0.1em solid;
    +	box-shadow: 3px 3px 2px #888;
    +	text-align: center;
    +}
    +
    +div.wrapper2{
    +	float:left; /* important */
    +	position:relative; /* important(so we can absolutely position the description div */
    +	width:10.2%;
    +	height:23%;
    +	margin-top:0.5%;
    +	margin-bottom:0.5%;
    +	margin-left:0.5%;
    +	margin-right:0.5%;
    +	border: 0.1em solid;
    +	box-shadow: 3px 3px 2px #888;
    +	text-align: center;
    +}
    +
    +div.description{
    +	position:absolute; /* absolute position (so we can position it where we want)*/
    +	bottom:0px; /* position will be on bottom */
    +	left:0px;
    +	width:100%;
    +	/* styling bellow */
    +	background-color:black;
    +	font-family: 'tahoma';
    +	font-size:100%;
    +	color:white;
    +	opacity:0.8; /* transparency */
    +	filter:alpha(opacity=80); /* IE transparency */
    +	text-align:center;
    +}
    +
    +@media only screen and (max-aspect-ratio: 6/4) {
    +	div.description{
    +	min-height:20%;
    +	}
    +}
    +
    +p.description_content{
    +	padding:10px;
    +	margin:0px;
    +	
    +}
    diff --git a/htdocs/takepos/customers.php b/htdocs/takepos/customers.php
    new file mode 100644
    index 00000000000..f5bcb8557cf
    --- /dev/null
    +++ b/htdocs/takepos/customers.php
    @@ -0,0 +1,1271 @@
    +<?php
    +/* Copyright (C) 2001-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2016  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2013-2015  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2015       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2016       Josep Lluis Amador      <joseplluis@lliuretic.cat>
    + * Copyright (C) 2016       Ferran Marcet      		<fmarcet@2byte.es>
    + * Copyright (C) 2017       Rui Strecht      		<rui.strecht@aliartalentos.com>
    + * Copyright (C) 2017       Juanjo Menent      		<jmenent@2byte.es>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + *	\file       htdocs/takepos/customers.php
    + *	\ingroup    societe
    + *	\brief      Page to show list of third parties. TODO Merge with societe/list.php
    + */
    +
    +require '../main.inc.php';	// Load $user and permissions
    +include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
    +
    +$langs->loadLangs(array("companies", "commercial", "customers", "suppliers", "bills", "compta", "categories", "cashdesk"));
    +
    +$action=GETPOST('action','alpha');
    +$massaction=GETPOST('massaction','alpha');
    +$show_files=GETPOST('show_files','int');
    +$confirm=GETPOST('confirm','alpha');
    +$toselect = GETPOST('toselect', 'array');
    +$idcustomer = GETPOST('idcustomer','int');
    +$place = GETPOST('place','int');
    +
    +$_GET['optioncss'] = 'print';
    +
    +
    +/*
    + * Actions
    + */
    +
    +if ($action=="change") {
    +    $sql="UPDATE ".MAIN_DB_PREFIX."facture set fk_soc=".$idcustomer." where facnumber='(PROV-POS-".$place.")'";
    +    $resql = $db->query($sql);
    +    ?>
    +    <script>
    +    parent.$("#poslines").load("invoice.php?place="+<?php print $place;?>, function() {
    +        parent.$("#poslines").scrollTop(parent.$("#poslines")[0].scrollHeight);
    +        parent.$.colorbox.close();
    +    });
    +    </script>
    +    <?php
    +    exit;
    +}
    +
    +// Security check
    +$socid = GETPOST('socid','int');
    +if ($user->societe_id) $socid=$user->societe_id;
    +$result = restrictedArea($user,'societe',$socid,'');
    +
    +$search_all=trim(GETPOST('search_all', 'alphanohtml')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));
    +$search_cti=preg_replace('/^0+/', '', preg_replace('/[^0-9]/', '', GETPOST('search_cti', 'alphanohtml')));	// Phone number without any special chars
    +
    +$search_id=trim(GETPOST("search_id","int"));
    +$search_nom=trim(GETPOST("search_nom"));
    +$search_alias=trim(GETPOST("search_alias"));
    +$search_nom_only=trim(GETPOST("search_nom_only"));
    +$search_barcode=trim(GETPOST("search_barcode"));
    +$search_customer_code=trim(GETPOST('search_customer_code'));
    +$search_supplier_code=trim(GETPOST('search_supplier_code'));
    +$search_account_customer_code=trim(GETPOST('search_account_customer_code'));
    +$search_account_supplier_code=trim(GETPOST('search_account_supplier_code'));
    +$search_town=trim(GETPOST("search_town"));
    +$search_zip=trim(GETPOST("search_zip"));
    +$search_state=trim(GETPOST("search_state"));
    +$search_region=trim(GETPOST("search_region"));
    +$search_email=trim(GETPOST('search_email'));
    +$search_phone=trim(GETPOST('search_phone'));
    +$search_url=trim(GETPOST('search_url'));
    +$search_idprof1=trim(GETPOST('search_idprof1'));
    +$search_idprof2=trim(GETPOST('search_idprof2'));
    +$search_idprof3=trim(GETPOST('search_idprof3'));
    +$search_idprof4=trim(GETPOST('search_idprof4'));
    +$search_idprof5=trim(GETPOST('search_idprof5'));
    +$search_idprof6=trim(GETPOST('search_idprof6'));
    +$search_vat=trim(GETPOST('search_vat'));
    +$search_sale=trim(GETPOST("search_sale",'int'));
    +$search_categ_cus=trim(GETPOST("search_categ_cus",'int'));
    +$search_categ_sup=trim(GETPOST("search_categ_sup",'int'));
    +$search_country=GETPOST("search_country",'intcomma');
    +$search_type_thirdparty=GETPOST("search_type_thirdparty",'int');
    +$search_status=GETPOST("search_status",'int');
    +$search_type=GETPOST('search_type','alpha');
    +$search_level_from = GETPOST("search_level_from","alpha");
    +$search_level_to   = GETPOST("search_level_to","alpha");
    +$search_stcomm=GETPOST('search_stcomm','int');
    +$search_import_key  = GETPOST("search_import_key","alpha");
    +
    +$type=GETPOST('type');
    +$optioncss=GETPOST('optioncss','alpha');
    +$mode=GETPOST("mode");
    +
    +$diroutputmassaction=$conf->societe->dir_output . '/temp/massgeneration/'.$user->id;
    +
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    +$sortfield=GETPOST("sortfield",'alpha');
    +$sortorder=GETPOST("sortorder",'alpha');
    +$page=GETPOST("page",'int');
    +if (! $sortorder) $sortorder="ASC";
    +if (! $sortfield) $sortfield="s.nom";
    +if (empty($page) || $page == -1) { $page = 0; }
    +$offset = $limit * $page;
    +$pageprev = $page - 1;
    +$pagenext = $page + 1;
    +
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$contextpage='thirdpartylist';
    +/*if ($search_type == '1,3') { $contextpage='customerlist'; $type='c'; }
    +if ($search_type == '2,3') { $contextpage='prospectlist'; $type='p'; }
    +if ($search_type == '4') { $contextpage='supplierlist'; $type='f'; }
    +*/
    +if ($type == 'c') { $contextpage='customerlist'; if ($search_type=='') $search_type='1,3'; }
    +if ($type == 'p') { $contextpage='prospectlist'; if ($search_type=='') $search_type='2,3'; }
    +if ($type == 'f') { $contextpage='supplierlist'; if ($search_type=='') $search_type='4'; }
    +
    +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
    +$hookmanager->initHooks(array($contextpage));
    +$extrafields = new ExtraFields($db);
    +
    +// fetch optionals attributes and labels
    +$extralabels = $extrafields->fetch_name_optionals_label('societe');
    +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
    +
    +// List of fields to search into when doing a "search in all"
    +$fieldstosearchall = array(
    +	's.nom'=>"ThirdPartyName",
    +	's.name_alias'=>"AliasNameShort",
    +	's.code_client'=>"CustomerCode",
    +	's.code_fournisseur'=>"SupplierCode",
    +	's.code_compta'=>"CustomerAccountancyCodeShort",
    +	's.code_compta_fournisseur'=>"SupplierAccountancyCodeShort",
    +	's.email'=>"EMail",
    +	's.url'=>"URL",
    +	's.tva_intra'=>"VATIntra",
    +	's.siren'=>"ProfId1",
    +	's.siret'=>"ProfId2",
    +	's.ape'=>"ProfId3",
    +);
    +if (($tmp = $langs->transnoentities("ProfId4".$mysoc->country_code)) && $tmp != "ProfId4".$mysoc->country_code && $tmp != '-') $fieldstosearchall['s.idprof4']='ProfId4';
    +if (($tmp = $langs->transnoentities("ProfId5".$mysoc->country_code)) && $tmp != "ProfId5".$mysoc->country_code && $tmp != '-') $fieldstosearchall['s.idprof5']='ProfId5';
    +if (($tmp = $langs->transnoentities("ProfId6".$mysoc->country_code)) && $tmp != "ProfId6".$mysoc->country_code && $tmp != '-') $fieldstosearchall['s.idprof6']='ProfId6';
    +if (!empty($conf->barcode->enabled)) $fieldstosearchall['s.barcode']='Gencod';
    +
    +// Define list of fields to show into list
    +$checkedcustomercode=(in_array($contextpage, array('thirdpartylist', 'customerlist', 'prospectlist')) ? 1 : 0);
    +$checkedsuppliercode=(in_array($contextpage, array('supplierlist')) ? 1 : 0);
    +$checkedcustomeraccountcode=(in_array($contextpage, array('customerlist')) ? 1 : 0);
    +$checkedsupplieraccountcode=(in_array($contextpage, array('supplierlist')) ? 1 : 0);
    +$checkedtypetiers=1;
    +$checkedprofid1=0;
    +$checkedprofid2=0;
    +$checkedprofid3=0;
    +$checkedprofid4=0;
    +$checkedprofid5=0;
    +$checkedprofid6=0;
    +//$checkedprofid4=((($tmp = $langs->transnoentities("ProfId4".$mysoc->country_code)) && $tmp != "ProfId4".$mysoc->country_code && $tmp != '-') ? 1 : 0);
    +//$checkedprofid5=((($tmp = $langs->transnoentities("ProfId5".$mysoc->country_code)) && $tmp != "ProfId5".$mysoc->country_code && $tmp != '-') ? 1 : 0);
    +//$checkedprofid6=((($tmp = $langs->transnoentities("ProfId6".$mysoc->country_code)) && $tmp != "ProfId6".$mysoc->country_code && $tmp != '-') ? 1 : 0);
    +$checkprospectlevel=(in_array($contextpage, array('prospectlist')) ? 1 : 0);
    +$checkstcomm=(in_array($contextpage, array('prospectlist')) ? 1 : 0);
    +$arrayfields=array(
    +	's.rowid'=>array('label'=>"TechnicalID", 'checked'=>($conf->global->MAIN_SHOW_TECHNICAL_ID?1:0), 'enabled'=>($conf->global->MAIN_SHOW_TECHNICAL_ID?1:0)),
    +	's.nom'=>array('label'=>"ThirdPartyName", 'checked'=>1),
    +	's.name_alias'=>array('label'=>"AliasNameShort", 'checked'=>1),
    +	's.barcode'=>array('label'=>"Gencod", 'checked'=>1, 'enabled'=>(! empty($conf->barcode->enabled))),
    +	's.code_client'=>array('label'=>"CustomerCodeShort", 'checked'=>$checkedcustomercode),
    +	's.code_fournisseur'=>array('label'=>"SupplierCodeShort", 'checked'=>$checkedsuppliercode, 'enabled'=>(! empty($conf->fournisseur->enabled))),
    +	's.code_compta'=>array('label'=>"CustomerAccountancyCodeShort", 'checked'=>$checkedcustomeraccountcode),
    +	's.code_compta_fournisseur'=>array('label'=>"SupplierAccountancyCodeShort", 'checked'=>$checkedsupplieraccountcode, 'enabled'=>(! empty($conf->fournisseur->enabled))),
    +	's.town'=>array('label'=>"Town", 'checked'=>1),
    +	's.zip'=>array('label'=>"Zip", 'checked'=>1),
    +	'state.nom'=>array('label'=>"State", 'checked'=>0),
    +	'region.nom'=>array('label'=>"Region", 'checked'=>0),
    +	'country.code_iso'=>array('label'=>"Country", 'checked'=>0),
    +	's.email'=>array('label'=>"Email", 'checked'=>0),
    +	's.url'=>array('label'=>"Url", 'checked'=>0),
    +	's.phone'=>array('label'=>"Phone", 'checked'=>1),
    +	'typent.code'=>array('label'=>"ThirdPartyType", 'checked'=>$checkedtypetiers),
    +	's.siren'=>array('label'=>"ProfId1Short", 'checked'=>$checkedprofid1),
    +	's.siret'=>array('label'=>"ProfId2Short", 'checked'=>$checkedprofid2),
    +	's.ape'=>array('label'=>"ProfId3Short", 'checked'=>$checkedprofid3),
    +	's.idprof4'=>array('label'=>"ProfId4Short", 'checked'=>$checkedprofid4),
    +	's.idprof5'=>array('label'=>"ProfId5Short", 'checked'=>$checkedprofid5),
    +	's.idprof6'=>array('label'=>"ProfId6Short", 'checked'=>$checkedprofid6),
    +	's.tva_intra'=>array('label'=>"VATIntra", 'checked'=>0),
    +	'customerorsupplier'=>array('label'=>'Nature', 'checked'=>1),
    +	's.fk_prospectlevel'=>array('label'=>"ProspectLevelShort", 'checked'=>$checkprospectlevel),
    +	's.fk_stcomm'=>array('label'=>"StatusProsp", 'checked'=>$checkstcomm),
    +	's.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
    +	's.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500),
    +	's.status'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000),
    +	's.import_key'=>array('label'=>"ImportId", 'checked'=>0, 'position'=>1100),
    +);
    +// Extra fields
    +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label))
    +{
    +   foreach($extrafields->attribute_label as $key => $val)
    +   {
    +		if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>(abs($extrafields->attribute_list[$key])!=3 && $extrafields->attribute_perms[$key]));
    +   }
    +}
    +
    +$object = new Societe($db);
    +
    +
    +/*
    + * Actions
    + */
    +
    +if (GETPOST('cancel','alpha')) { $action='list'; $massaction=''; }
    +if (! GETPOST('confirmmassaction','alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction=''; }
    +
    +$parameters=array();
    +$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))
    +{
    +	// Selection of new fields
    +	include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
    +
    +	// Did we click on purge search criteria ?
    +	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_id='';
    +		$search_nom='';
    +		$search_alias='';
    +		$search_categ_cus=0;
    +		$search_categ_sup=0;
    +		$search_sale='';
    +		$search_barcode="";
    +		$search_customer_code='';
    +		$search_supplier_code='';
    +		$search_account_customer_code='';
    +		$search_account_supplier_code='';
    +		$search_town="";
    +		$search_zip="";
    +		$search_state="";
    +		$search_country='';
    +		$search_email='';
    +		$search_phone='';
    +		$search_url='';
    +		$search_idprof1='';
    +		$search_idprof2='';
    +		$search_idprof3='';
    +		$search_idprof4='';
    +		$search_idprof5='';
    +		$search_idprof6='';
    +		$search_vat='';
    +		$search_type='';
    +		$search_type_thirdparty='';
    +		$search_status=-1;
    +		$search_stcomm='';
    +	 	$search_level_from='';
    +	 	$search_level_to='';
    +	 	$search_import_key='';
    +	 	$toselect='';
    +		$search_array_options=array();
    +	}
    +
    +	// Mass actions
    +	$objectclass='Societe';
    +	$objectlabel='ThirdParty';
    +	$permtoread = $user->rights->societe->lire;
    +	$permtodelete = $user->rights->societe->supprimer;
    +	$uploaddir = $conf->societe->dir_output;
    +	include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
    +
    +	if ($action == 'setstcomm')
    +	{
    +		$object = new Client($db);
    +		$result=$object->fetch(GETPOST('stcommsocid'));
    +		$object->stcomm_id=dol_getIdFromCode($db, GETPOST('stcomm','alpha'), 'c_stcomm');
    +		$result=$object->update($object->id, $user);
    +		if ($result < 0) setEventMessages($object->error,$object->errors,'errors');
    +
    +		$action='';
    +	}
    +}
    +
    +if ($search_status=='') $search_status=1; // always display active thirdparty first
    +
    +
    +
    +/*
    + * View
    + */
    +
    +/*
    + REM: Rules on permissions to see thirdparties
    + Internal or External user + No permission to see customers => See nothing
    + Internal user socid=0 + Permission to see ALL customers    => See all thirdparties
    + Internal user socid=0 + No permission to see ALL customers => See only thirdparties linked to user that are sale representative
    + External user socid=x + Permission to see ALL customers    => Can see only himself
    + External user socid=x + No permission to see ALL customers => Can see only himself
    + */
    +
    +$form=new Form($db);
    +$formother=new FormOther($db);
    +$companystatic=new Societe($db);
    +$formcompany=new FormCompany($db);
    +$prospectstatic=new Client($db);
    +$prospectstatic->client=2;
    +$prospectstatic->loadCacheOfProspStatus();
    +
    +
    +$title=$langs->trans("ListOfThirdParties");
    +if ($type == 'c' && (empty($search_type) || ($search_type == '1,3'))) $title=$langs->trans("ListOfCustomers");
    +if ($type == 'p' && (empty($search_type) || ($search_type == '2,3'))) $title=$langs->trans("ListOfProspects");
    +if ($type == 'f' && (empty($search_type) || ($search_type == '4'))) $title=$langs->trans("ListOfSuppliers");
    +
    +// If both parameters are set, search for everything BETWEEN them
    +if ($search_level_from != '' && $search_level_to != '')
    +{
    +	// Ensure that these parameters are numbers
    +	$search_level_from = (int) $search_level_from;
    +	$search_level_to = (int) $search_level_to;
    +
    +	// If from is greater than to, reverse orders
    +	if ($search_level_from > $search_level_to)
    +	{
    +		$tmp = $search_level_to;
    +		$search_level_to = $search_level_from;
    +		$search_level_from = $tmp;
    +	}
    +
    +	// Generate the SQL request
    +	$sortwhere = '(sortorder BETWEEN '.$search_level_from.' AND '.$search_level_to.') AS is_in_range';
    +}
    +// If only "from" parameter is set, search for everything GREATER THAN it
    +else if ($search_level_from != '')
    +{
    +	// Ensure that this parameter is a number
    +	$search_level_from = (int) $search_level_from;
    +
    +	// Generate the SQL request
    +	$sortwhere = '(sortorder >= '.$search_level_from.') AS is_in_range';
    +}
    +// If only "to" parameter is set, search for everything LOWER THAN it
    +else if ($search_level_to != '')
    +{
    +	// Ensure that this parameter is a number
    +	$search_level_to = (int) $search_level_to;
    +
    +	// Generate the SQL request
    +	$sortwhere = '(sortorder <= '.$search_level_to.') AS is_in_range';
    +}
    +// If no parameters are set, dont search for anything
    +else
    +{
    +	$sortwhere = '0 as is_in_range';
    +}
    +
    +// Select every potentiels, and note each potentiels which fit in search parameters
    +dol_syslog('societe/list.php',LOG_DEBUG);
    +$sql = "SELECT code, label, sortorder, ".$sortwhere;
    +$sql.= " FROM ".MAIN_DB_PREFIX."c_prospectlevel";
    +$sql.= " WHERE active > 0";
    +$sql.= " ORDER BY sortorder";
    +
    +$resql = $db->query($sql);
    +if ($resql)
    +{
    +	$tab_level = array();
    +	$search_levels = array();
    +
    +	while ($obj = $db->fetch_object($resql))
    +	{
    +		// Compute level text
    +		$level=$langs->trans($obj->code);
    +		if ($level == $obj->code) $level=$langs->trans($obj->label);
    +
    +		// Put it in the array sorted by sortorder
    +		$tab_level[$obj->sortorder] = $level;
    +
    +		// If this potentiel fit in parameters, add its code to the $search_levels array
    +		if ($obj->is_in_range == 1)
    +		{
    +			$search_levels[] = '"'.preg_replace('[^A-Za-z0-9_-]', '', $obj->code).'"';
    +		}
    +	}
    +
    +	// Implode the $search_levels array so that it can be use in a "IN (...)" where clause.
    +	// If no paramters was set, $search_levels will be empty
    +	$search_levels = implode(',', $search_levels);
    +}
    +else dol_print_error($db);
    +
    +$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.barcode, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,";
    +$sql.= " st.libelle as stcomm, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status,";
    +$sql.= " s.email, s.phone, s.url, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4 as idprof4, s.idprof5 as idprof5, s.idprof6 as idprof6, s.tva_intra, s.fk_pays,";
    +$sql.= " s.tms as date_update, s.datec as date_creation,";
    +$sql.= " s.code_compta,s.code_compta_fournisseur,";
    +$sql.= " typent.code as typent_code,";
    +$sql.= " state.code_departement as state_code, state.nom as state_name,";
    +$sql.= " region.code_region as region_code, region.nom as region_name";
    +// We'll need these fields in order to filter by sale (including the case where the user can only see his prospects)
    +if ($search_sale) $sql .= ", sc.fk_soc, sc.fk_user";
    +// We'll need these fields in order to filter by categ
    +if ($search_categ_cus) $sql .= ", cc.fk_categorie, cc.fk_soc";
    +if ($search_categ_sup) $sql .= ", cs.fk_categorie, cs.fk_soc";
    +// Add fields from extrafields
    +foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : '');
    +// Add fields from hooks
    +$parameters=array();
    +$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters);    // Note that $action and $object may have been modified by hook
    +$sql.=$hookmanager->resPrint;
    +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
    +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields as ef on (s.rowid = ef.fk_object)";
    +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)";
    +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)";
    +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)";
    +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as region on (region.	code_region = state.fk_region)";
    +// We'll need this table joined to the select in order to filter by categ
    +if (! empty($search_categ_cus)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_societe as cc ON s.rowid = cc.fk_soc"; // We'll need this table joined to the select in order to filter by categ
    +if (! empty($search_categ_sup)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc"; // We'll need this table joined to the select in order to filter by categ
    +$sql.= " ,".MAIN_DB_PREFIX."c_stcomm as st";
    +// We'll need this table joined to the select in order to filter by sale
    +if ($search_sale || (!$user->rights->societe->client->voir && !$socid)) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    +$sql.= " WHERE s.fk_stcomm = st.id";
    +$sql.= " AND s.entity IN (".getEntity('societe').")";
    +if (! $user->rights->societe->client->voir && ! $socid)	$sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
    +if ($socid)                $sql.= " AND s.rowid = ".$socid;
    +if ($search_sale)          $sql.= " AND s.rowid = sc.fk_soc";        // Join for the needed table to filter by sale
    +if (! $user->rights->fournisseur->lire) $sql.=" AND (s.fournisseur <> 1 OR s.client <> 0)";    // client=0, fournisseur=0 must be visible
    +if ($search_sale)          $sql.= " AND sc.fk_user = ".$db->escape($search_sale);
    +if ($search_categ_cus > 0) $sql.= " AND cc.fk_categorie = ".$db->escape($search_categ_cus);
    +if ($search_categ_sup > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ_sup);
    +if ($search_categ_cus == -2)   $sql.= " AND cc.fk_categorie IS NULL";
    +if ($search_categ_sup == -2)   $sql.= " AND cs.fk_categorie IS NULL";
    +
    +if ($search_all)           $sql.= natural_search(array_keys($fieldstosearchall), $search_all);
    +if (strlen($search_cti))   $sql.= natural_search('s.phone', $search_cti);
    +
    +if ($search_id > 0)        $sql.= natural_search("s.rowid",$search_id,1);
    +if ($search_nom)           $sql.= natural_search("s.nom",$search_nom);
    +if ($search_alias)         $sql.= natural_search("s.name_alias",$search_alias);
    +if ($search_nom_only)      $sql.= natural_search("s.nom",$search_nom_only);
    +if ($search_customer_code) $sql.= natural_search("s.code_client",$search_customer_code);
    +if ($search_supplier_code) $sql.= natural_search("s.code_fournisseur",$search_supplier_code);
    +if ($search_account_customer_code) $sql.= natural_search("s.code_compta",$search_account_customer_code);
    +if ($search_account_supplier_code) $sql.= natural_search("s.code_compta_fournisseur",$search_account_supplier_code);
    +if ($search_town)          $sql.= natural_search("s.town",$search_town);
    +if (strlen($search_zip))   $sql.= natural_search("s.zip",$search_zip);
    +if ($search_state)         $sql.= natural_search("state.nom",$search_state);
    +if ($search_region)         $sql.= natural_search("region.nom",$search_region);
    +if ($search_country)       $sql .= " AND s.fk_pays IN (".$search_country.')';
    +if ($search_email)         $sql.= natural_search("s.email",$search_email);
    +if (strlen($search_phone)) $sql.= natural_search("s.phone", $search_phone);
    +if ($search_url)           $sql.= natural_search("s.url",$search_url);
    +if (strlen($search_idprof1)) $sql.= natural_search("s.siren",$search_idprof1);
    +if (strlen($search_idprof2)) $sql.= natural_search("s.siret",$search_idprof2);
    +if (strlen($search_idprof3)) $sql.= natural_search("s.ape",$search_idprof3);
    +if (strlen($search_idprof4)) $sql.= natural_search("s.idprof4",$search_idprof4);
    +if (strlen($search_idprof5)) $sql.= natural_search("s.idprof5",$search_idprof5);
    +if (strlen($search_idprof6)) $sql.= natural_search("s.idprof6",$search_idprof6);
    +if (strlen($search_vat))     $sql.= natural_search("s.tva_intra",$search_vat);
    +// Filter on type of thirdparty
    +if ($search_type > 0 && in_array($search_type,array('1,3','2,3'))) $sql .= " AND s.client IN (".$db->escape($search_type).")";
    +if ($search_type > 0 && in_array($search_type,array('4')))         $sql .= " AND s.fournisseur = 1";
    +if ($search_type == '0') $sql .= " AND s.client = 0 AND s.fournisseur = 0";
    +if ($search_status!='' && $search_status >= 0) $sql .= " AND s.status = ".$db->escape($search_status);
    +if (!empty($conf->barcode->enabled) && $search_barcode) $sql.= natural_search("s.barcode", $search_barcode);
    +if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')';
    +if ($search_levels)  $sql .= " AND s.fk_prospectlevel IN (".$search_levels.')';
    +if ($search_stcomm != '' && $search_stcomm != -2) $sql.= natural_search("s.fk_stcomm",$search_stcomm,2);
    +if ($search_import_key)    $sql.= natural_search("s.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
    +$sql.=$hookmanager->resPrint;
    +
    +$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);
    +}
    +
    +$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();
    +
    +if ($num == 1 && ! empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && ($search_all != '' || $search_cti != '') && $action != 'list')
    +{
    +	$obj = $db->fetch_object($resql);
    +	$id = $obj->rowid;
    +	header("Location: ".DOL_URL_ROOT.'/societe/card.php?socid='.$id);
    +	exit;
    +}
    +
    +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
    +llxHeader('',$langs->trans("ThirdParty"),$help_url);
    +
    +$param='';
    +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
    +if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
    +if ($search_all != '')     $param = "&sall=".urlencode($search_all);
    +if ($sall != '')           $param .= "&sall=".urlencode($sall);
    +if ($search_categ_cus > 0) $param.='&search_categ_cus='.urlencode($search_categ_cus);
    +if ($search_categ_sup > 0) $param.='&search_categ_sup='.urlencode($search_categ_sup);
    +if ($search_sale > 0)	   $param.='&search_sale='.urlencode($search_sale);
    +if ($search_id > 0)        $param.= "&search_id=".urlencode($search_id);
    +if ($search_nom != '')     $param.= "&search_nom=".urlencode($search_nom);
    +if ($search_alias != '')   $param.= "&search_alias=".urlencode($search_alias);
    +if ($search_town != '')    $param.= "&search_town=".urlencode($search_town);
    +if ($search_zip != '')     $param.= "&search_zip=".urlencode($search_zip);
    +if ($search_phone != '')   $param.= "&search_phone=".urlencode($search_phone);
    +if ($search_email != '')   $param.= "&search_email=".urlencode($search_email);
    +if ($search_url != '')     $param.= "&search_url=".urlencode($search_url);
    +if ($search_state != '')   $param.= "&search_state=".urlencode($search_state);
    +if ($search_country != '') $param.= "&search_country=".urlencode($search_country);
    +if ($search_customer_code != '') $param.= "&search_customer_code=".urlencode($search_customer_code);
    +if ($search_supplier_code != '') $param.= "&search_supplier_code=".urlencode($search_supplier_code);
    +if ($search_account_customer_code != '') $param.= "&search_account_customer_code=".urlencode($search_account_customer_code);
    +if ($search_account_supplier_code != '') $param.= "&search_account_supplier_code=".urlencode($search_account_supplier_code);
    +if ($search_barcode != '') $param.= "&search_barcode=".urlencode($search_barcode);
    +if ($search_idprof1 != '') $param.= '&search_idprof1='.urlencode($search_idprof1);
    +if ($search_idprof2 != '') $param.= '&search_idprof2='.urlencode($search_idprof2);
    +if ($search_idprof3 != '') $param.= '&search_idprof3='.urlencode($search_idprof3);
    +if ($search_idprof4 != '') $param.= '&search_idprof4='.urlencode($search_idprof4);
    +if ($search_idprof5 != '') $param.= '&search_idprof5='.urlencode($search_idprof5);
    +if ($search_idprof6 != '') $param.= '&search_idprof6='.urlencode($search_idprof6);
    +if ($search_vat != '')     $param.= '&search_vat='.urlencode($search_vat);
    +if ($search_type_thirdparty != '')    $param.='&search_type_thirdparty='.urlencode($search_type_thirdparty);
    +if ($search_type != '')    $param.='&search_type='.urlencode($search_type);
    +if ($optioncss != '')      $param.='&optioncss='.urlencode($optioncss);
    +if ($search_status != '')  $param.='&search_status='.urlencode($search_status);
    +if ($search_stcomm != '')  $param.='&search_stcomm='.urlencode($search_stcomm);
    +if ($search_level_from != '') $param.='&search_level_from='.urlencode($search_level_from);
    +if ($search_level_to != '')   $param.='&search_level_to='.urlencode($search_level_to);
    +if ($search_import_key != '') $param.='&search_import_key='.urlencode($search_import_key);
    +if ($type != '') $param.='&type='.urlencode($type);
    +// Add $param from extra fields
    +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
    +
    +// Show delete result message
    +if (GETPOST('delsoc'))
    +{
    +	setEventMessages($langs->trans("CompanyDeleted",GETPOST('delsoc')), null, 'mesgs');
    +}
    +
    +// List of mass actions available
    +$arrayofmassactions =  array(
    +	'presend'=>$langs->trans("SendByMail"),
    +//    'builddoc'=>$langs->trans("PDFMerge"),
    +);
    +//if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
    +if ($user->rights->societe->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete");
    +if (GETPOST('nomassaction','int') || in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
    +$massactionbutton=$form->selectMassAction('', $arrayofmassactions);
    +
    +print '<form method="post" action="'.$_SERVER["PHP_SELF"].'" name="formfilter">';
    +if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
    +print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
    +print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
    +print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
    +print '<input type="hidden" name="page" value="'.$page.'">';
    +
    +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit);
    +
    +$langs->load("other");
    +$textprofid=array();
    +foreach(array(1,2,3,4,5,6) as $key)
    +{
    +	$label=$langs->transnoentities("ProfId".$key.$mysoc->country_code);
    +	$textprofid[$key]='';
    +	if ($label != "ProfId".$key.$mysoc->country_code)
    +	{	// Get only text between ()
    +		if (preg_match('/\((.*)\)/i',$label,$reg)) $label=$reg[1];
    +		$textprofid[$key]=$langs->trans("ProfIdShortDesc",$key,$mysoc->country_code,$label);
    +	}
    +}
    +
    +$topicmail="Information";
    +$modelmail="thirdparty";
    +$objecttmp=new Societe($db);
    +$trackid='thi'.$object->id;
    +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
    +
    +if ($search_all)
    +{
    +	foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    +	print $langs->trans("FilterOnInto", $search_all) . join(', ',$fieldstosearchall);
    +}
    +
    +// Filter on categories
    +$moreforfilter='';
    +if (empty($type) || $type == 'c' || $type == 'p')
    +{
    +	if (! empty($conf->categorie->enabled))
    +	{
    +		require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
    +		$moreforfilter.='<div class="divsearchfield">';
    +	 	$moreforfilter.=$langs->trans('CustomersProspectsCategoriesShort').': ';
    +		$moreforfilter.=$formother->select_categories('customer', $search_categ_cus, 'search_categ_cus', 1, $langs->trans('CustomersProspectsCategoriesShort'));
    +	 	$moreforfilter.='</div>';
    +	}
    +}
    +if (empty($type) || $type == 'f')
    +{
    +	if (! empty($conf->categorie->enabled))
    +	{
    +		require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
    +		$moreforfilter.='<div class="divsearchfield">';
    +		$moreforfilter.=$langs->trans('SuppliersCategoriesShort').': ';
    +		$moreforfilter.=$formother->select_categories('supplier',$search_categ_sup,'search_categ_sup',1);
    +		$moreforfilter.='</div>';
    +	}
    +}
    +
    +// If the user can view prospects other than his'
    +if ($user->rights->societe->client->voir || $socid)
    +{
    + 	$moreforfilter.='<div class="divsearchfield">';
    + 	$moreforfilter.=$langs->trans('SalesRepresentatives'). ': ';
    +	$moreforfilter.=$formother->select_salesrepresentatives($search_sale,'search_sale',$user, 0, 1, 'maxwidth300');
    +	$moreforfilter.='</div>';
    +}
    +if ($moreforfilter)
    +{
    +	print '<div class="liste_titre liste_titre_bydiv centpercent">';
    +	print $moreforfilter;
    +	$parameters=array('type'=>$type);
    +	$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
    +	print $hookmanager->resPrint;
    +	print '</div>';
    +}
    +
    +$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
    +$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
    +if ($massactionbutton) $selectedfields.=$form->showCheckAddButtons('checkforselect', 1);
    +
    +if (empty($arrayfields['customerorsupplier']['checked'])) print '<input type="hidden" name="type" value="'.$type.'">';
    +
    +print '<div class="div-table-responsive">';
    +print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">'."\n";
    +
    +// Fields title search
    +print '<tr class="liste_titre_filter">';
    +if (! empty($arrayfields['s.rowid']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" type="text" name="search_id" size="1" value="'.dol_escape_htmltag($search_id).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.nom']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	if (! empty($search_nom_only) && empty($search_nom)) $search_nom=$search_nom_only;
    +	print '<input class="flat searchstring" type="text" name="search_nom" size="8" value="'.dol_escape_htmltag($search_nom).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.name_alias']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" type="text" name="search_alias" size="8" value="'.dol_escape_htmltag($search_alias).'">';
    +	print '</td>';
    +}
    +// Barcode
    +if (! empty($arrayfields['s.barcode']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" type="text" name="search_barcode" size="6" value="'.dol_escape_htmltag($search_barcode).'">';
    +	print '</td>';
    +}
    +// Customer code
    +if (! empty($arrayfields['s.code_client']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="8" type="text" name="search_customer_code" value="'.dol_escape_htmltag($search_customer_code).'">';
    +	print '</td>';
    +}
    +// Supplier code
    +if (! empty($arrayfields['s.code_fournisseur']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="8" type="text" name="search_supplier_code" value="'.dol_escape_htmltag($search_supplier_code).'">';
    +	print '</td>';
    +}
    +// Account Customer code
    +if (! empty($arrayfields['s.code_compta']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="8" type="text" name="search_account_customer_code" value="'.dol_escape_htmltag($search_account_customer_code).'">';
    +	print '</td>';
    +}
    +// Account Supplier code
    +if (! empty($arrayfields['s.code_compta_fournisseur']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat" size="8" type="text" name="search_account_supplier_code" value="'.dol_escape_htmltag($search_account_supplier_code).'">';
    +	print '</td>';
    +}
    +// Town
    +if (! empty($arrayfields['s.town']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="6" type="text" name="search_town" value="'.dol_escape_htmltag($search_town).'">';
    +	print '</td>';
    +}
    +// Zip
    +if (! empty($arrayfields['s.zip']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_zip" value="'.dol_escape_htmltag($search_zip).'">';
    +	print '</td>';
    +}
    +// State
    +if (! empty($arrayfields['state.nom']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_state" value="'.dol_escape_htmltag($search_state).'">';
    +	print '</td>';
    +}
    +// Region
    +if (! empty($arrayfields['region.nom']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_region" value="'.dol_escape_htmltag($search_region).'">';
    +	print '</td>';
    +}
    +// Country
    +if (! empty($arrayfields['country.code_iso']['checked']))
    +{
    +	print '<td class="liste_titre" align="center">';
    +	print $form->select_country($search_country,'search_country','',0,'maxwidth100');
    +	print '</td>';
    +}
    +// Company type
    +if (! empty($arrayfields['typent.code']['checked']))
    +{
    +	print '<td class="liste_titre maxwidthonsmartphone" align="center">';
    +	print $form->selectarray("search_type_thirdparty", $formcompany->typent_array(0), $search_type_thirdparty, 0, 0, 0, '', 0, 0, 0, (empty($conf->global->SOCIETE_SORT_ON_TYPEENT)?'ASC':$conf->global->SOCIETE_SORT_ON_TYPEENT));
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.email']['checked']))
    +{
    +	// Email
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchemail" size="4" type="text" name="search_email" value="'.dol_escape_htmltag($search_email).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.phone']['checked']))
    +{
    +	// Phone
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_phone" value="'.dol_escape_htmltag($search_phone).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.url']['checked']))
    +{
    +	// Url
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_url" value="'.dol_escape_htmltag($search_url).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.siren']['checked']))
    +{
    +	// IdProf1
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_idprof1" value="'.dol_escape_htmltag($search_idprof1).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.siret']['checked']))
    +{
    +	// IdProf2
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_idprof2" value="'.dol_escape_htmltag($search_idprof2).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.ape']['checked']))
    +{
    +	// IdProf3
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_idprof3" value="'.dol_escape_htmltag($search_idprof3).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.idprof4']['checked']))
    +{
    +	// IdProf4
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_idprof4" value="'.dol_escape_htmltag($search_idprof4).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.idprof5']['checked']))
    +{
    +	// IdProf5
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_idprof5" value="'.dol_escape_htmltag($search_idprof5).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.idprof6']['checked']))
    +{
    +	// IdProf6
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_idprof6" value="'.dol_escape_htmltag($search_idprof6).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.tva_intra']['checked']))
    +{
    +	// Vat number
    +	print '<td class="liste_titre">';
    +	print '<input class="flat searchstring" size="4" type="text" name="search_vat" value="'.dol_escape_htmltag($search_vat).'">';
    +	print '</td>';
    +}
    +
    +// Type (customer/prospect/supplier)
    +if (! empty($arrayfields['customerorsupplier']['checked']))
    +{
    +	print '<td class="liste_titre maxwidthonsmartphone" align="middle">';
    +	if ($type != '') print '<input type="hidden" name="type" value="'.$type.'">';
    +	print '<select class="flat" name="search_type">';
    +	print '<option value="-1"'.($search_type==''?' selected':'').'>&nbsp;</option>';
    +	if (empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print '<option value="1,3"'.($search_type=='1,3'?' selected':'').'>'.$langs->trans('Customer').'</option>';
    +	if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) print '<option value="2,3"'.($search_type=='2,3'?' selected':'').'>'.$langs->trans('Prospect').'</option>';
    +	//if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS)) print '<option value="3"'.($search_type=='3'?' selected':'').'>'.$langs->trans('ProspectCustomer').'</option>';
    +	print '<option value="4"'.($search_type=='4'?' selected':'').'>'.$langs->trans('Supplier').'</option>';
    +	print '<option value="0"'.($search_type=='0'?' selected':'').'>'.$langs->trans('Others').'</option>';
    +	print '</select></td>';
    +}
    +if (! empty($arrayfields['s.fk_prospectlevel']['checked']))
    +{
    +	// Prospect level
    + 	print '<td class="liste_titre" align="center">';
    + 	$options_from = '<option value="">&nbsp;</option>';	 	// Generate in $options_from the list of each option sorted
    + 	foreach ($tab_level as $tab_level_sortorder => $tab_level_label)
    + 	{
    + 		$options_from .= '<option value="'.$tab_level_sortorder.'"'.($search_level_from == $tab_level_sortorder ? ' selected':'').'>';
    + 		$options_from .= $langs->trans($tab_level_label);
    + 		$options_from .= '</option>';
    + 	}
    + 	array_reverse($tab_level, true);	// Reverse the list
    + 	$options_to = '<option value="">&nbsp;</option>';		// Generate in $options_to the list of each option sorted in the reversed order
    + 	foreach ($tab_level as $tab_level_sortorder => $tab_level_label)
    + 	{
    + 		$options_to .= '<option value="'.$tab_level_sortorder.'"'.($search_level_to == $tab_level_sortorder ? ' selected':'').'>';
    + 		$options_to .= $langs->trans($tab_level_label);
    + 		$options_to .= '</option>';
    + 	}
    +
    +	// Print these two select
    + 	print $langs->trans("From").' <select class="flat" name="search_level_from">'.$options_from.'</select>';
    + 	print ' ';
    + 	print $langs->trans("to").' <select class="flat" name="search_level_to">'.$options_to.'</select>';
    +
    +	print '</td>';
    +}
    +
    +if (! empty($arrayfields['s.fk_stcomm']['checked']))
    +{
    +	// Prospect status
    +	print '<td class="liste_titre maxwidthonsmartphone" align="center">';
    +	$arraystcomm=array();
    +	foreach($prospectstatic->cacheprospectstatus as $key => $val)
    +	{
    +		$arraystcomm[$val['id']]=($langs->trans("StatusProspect".$val['id']) != "StatusProspect".$val['id'] ? $langs->trans("StatusProspect".$val['id']) : $val['label']);
    +	}
    +	print $form->selectarray('search_stcomm', $arraystcomm, $search_stcomm, -2);
    +	print '</td>';
    +}
    +// Extra fields
    +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
    +
    +// 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['s.datec']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '</td>';
    +}
    +// Date modification
    +if (! empty($arrayfields['s.tms']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '</td>';
    +}
    +// Status
    +if (! empty($arrayfields['s.status']['checked']))
    +{
    +	print '<td class="liste_titre maxwidthonsmartphone center">';
    +	print $form->selectarray('search_status', array('0'=>$langs->trans('ActivityCeased'),'1'=>$langs->trans('InActivity')), $search_status, 1);
    +	print '</td>';
    +}
    +if (! empty($arrayfields['s.import_key']['checked']))
    +{
    +	print '<td class="liste_titre center">';
    +	print '<input class="flat searchstring" type="text" name="search_import_key" size="3" value="'.dol_escape_htmltag($search_import_key).'">';
    +	print '</td>';
    +}
    +// Action column
    +print '<td class="liste_titre" align="right">';
    +$searchpicto=$form->showFilterButtons();
    +print $searchpicto;
    +print '</td>';
    +
    +print "</tr>\n";
    +
    +print '<tr class="liste_titre">';
    +if (! empty($arrayfields['s.rowid']['checked']))                   print_liste_field_titre($arrayfields['s.rowid']['label'], $_SERVER["PHP_SELF"],"s.rowid","",$param,"",$sortfield,$sortorder);
    +if (! empty($arrayfields['s.nom']['checked']))                     print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder);
    +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);
    +if (! empty($arrayfields['s.barcode']['checked']))                 print_liste_field_titre($arrayfields['s.barcode']['label'], $_SERVER["PHP_SELF"], "s.barcode",$param,'','',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.code_client']['checked']))             print_liste_field_titre($arrayfields['s.code_client']['label'],$_SERVER["PHP_SELF"],"s.code_client","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.code_fournisseur']['checked']))        print_liste_field_titre($arrayfields['s.code_fournisseur']['label'],$_SERVER["PHP_SELF"],"s.code_fournisseur","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.code_compta']['checked']))             print_liste_field_titre($arrayfields['s.code_compta']['label'],$_SERVER["PHP_SELF"],"s.code_compta","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.code_compta_fournisseur']['checked'])) print_liste_field_titre($arrayfields['s.code_compta_fournisseur']['label'],$_SERVER["PHP_SELF"],"s.code_compta_fournisseur","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.town']['checked']))           print_liste_field_titre($arrayfields['s.town']['label'],$_SERVER["PHP_SELF"],"s.town","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.zip']['checked']))            print_liste_field_titre($arrayfields['s.zip']['label'],$_SERVER["PHP_SELF"],"s.zip","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['state.nom']['checked']))        print_liste_field_titre($arrayfields['state.nom']['label'],$_SERVER["PHP_SELF"],"state.nom","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['region.nom']['checked']))       print_liste_field_titre($arrayfields['region.nom']['label'],$_SERVER["PHP_SELF"],"region.nom","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'],$_SERVER["PHP_SELF"],"country.code_iso","",$param,'align="center"',$sortfield,$sortorder);
    +if (! empty($arrayfields['typent.code']['checked']))      print_liste_field_titre($arrayfields['typent.code']['label'],$_SERVER["PHP_SELF"],"typent.code","",$param,'align="center"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.email']['checked']))          print_liste_field_titre($arrayfields['s.email']['label'],$_SERVER["PHP_SELF"],"s.email","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.phone']['checked']))          print_liste_field_titre($arrayfields['s.phone']['label'],$_SERVER["PHP_SELF"],"s.phone","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.url']['checked']))            print_liste_field_titre($arrayfields['s.url']['label'],$_SERVER["PHP_SELF"],"s.url","",$param,'',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.siren']['checked']))          print_liste_field_titre($form->textwithpicto($langs->trans("ProfId1Short"),$textprofid[1],1,0),$_SERVER["PHP_SELF"],"s.siren","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.siret']['checked']))          print_liste_field_titre($form->textwithpicto($langs->trans("ProfId2Short"),$textprofid[2],1,0),$_SERVER["PHP_SELF"],"s.siret","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.ape']['checked']))            print_liste_field_titre($form->textwithpicto($langs->trans("ProfId3Short"),$textprofid[3],1,0),$_SERVER["PHP_SELF"],"s.ape","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.idprof4']['checked']))        print_liste_field_titre($form->textwithpicto($langs->trans("ProfId4Short"),$textprofid[4],1,0),$_SERVER["PHP_SELF"],"s.idprof4","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.idprof5']['checked']))        print_liste_field_titre($form->textwithpicto($langs->trans("ProfId5Short"),$textprofid[4],1,0),$_SERVER["PHP_SELF"],"s.idprof5","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.idprof6']['checked']))        print_liste_field_titre($form->textwithpicto($langs->trans("ProfId6Short"),$textprofid[4],1,0),$_SERVER["PHP_SELF"],"s.idprof6","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.tva_intra']['checked']))      print_liste_field_titre($arrayfields['s.tva_intra']['label'],$_SERVER["PHP_SELF"],"s.tva_intra","",$param,'class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['customerorsupplier']['checked']))        print_liste_field_titre('');   // type of customer
    +if (! empty($arrayfields['s.fk_prospectlevel']['checked']))        print_liste_field_titre($arrayfields['s.fk_prospectlevel']['label'],$_SERVER["PHP_SELF"],"s.fk_prospectlevel","",$param,'align="center"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.fk_stcomm']['checked']))               print_liste_field_titre($arrayfields['s.fk_stcomm']['label'],$_SERVER["PHP_SELF"],"s.fk_stcomm","",$param,'align="center"',$sortfield,$sortorder);
    +// Extra fields
    +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);    // Note that $action and $object may have been modified by hook
    +print $hookmanager->resPrint;
    +if (! empty($arrayfields['s.datec']['checked']))      print_liste_field_titre($arrayfields['s.datec']['label'],$_SERVER["PHP_SELF"],"s.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.tms']['checked']))        print_liste_field_titre($arrayfields['s.tms']['label'],$_SERVER["PHP_SELF"],"s.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.status']['checked']))     print_liste_field_titre($arrayfields['s.status']['label'],$_SERVER["PHP_SELF"],"s.status","",$param,'align="center"',$sortfield,$sortorder);
    +if (! empty($arrayfields['s.import_key']['checked'])) print_liste_field_titre($arrayfields['s.import_key']['label'],$_SERVER["PHP_SELF"],"s.import_key","",$param,'align="center"',$sortfield,$sortorder);
    +print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ');
    +print "</tr>\n";
    +
    +
    +$i = 0;
    +$totalarray=array();
    +while ($i < min($num, $limit))
    +{
    +	$obj = $db->fetch_object($resql);
    +
    +	$companystatic->id=$obj->rowid;
    +	$companystatic->name=$obj->name;
    +	$companystatic->name_alias=$obj->name_alias;
    +	$companystatic->logo=$obj->logo;
    +	$companystatic->canvas=$obj->canvas;
    +	$companystatic->client=$obj->client;
    +	$companystatic->status=$obj->status;
    +	$companystatic->email=$obj->email;
    +	$companystatic->fournisseur=$obj->fournisseur;
    +	$companystatic->code_client=$obj->code_client;
    +	$companystatic->code_fournisseur=$obj->code_fournisseur;
    +
    +	$companystatic->code_compta_client=$obj->code_compta;
    +	$companystatic->code_compta_fournisseur=$obj->code_compta_fournisseur;
    +
    +   	$companystatic->fk_prospectlevel=$obj->fk_prospectlevel;
    +
    +	print '<tr class="oddeven" onclick="location.href=\'customers.php?action=change&idcustomer='.$obj->rowid.'&place='.$place.'\'">';
    +	if (! empty($arrayfields['s.rowid']['checked']))
    +	{
    +		print '<td class="tdoverflowmax50">';
    +		print $obj->rowid;
    +		print "</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.nom']['checked']))
    +	{
    +		$savalias = $obj->name_alias;
    +		if (! empty($arrayfields['s.name_alias']['checked'])) $companystatic->name_alias='';
    +		print '<td class="tdoverflowmax200">';
    +		print $obj->name;
    +		print "</td>\n";
    +        if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.name_alias']['checked']))
    +	{
    +		print '<td class="tdoverflowmax200">';
    +		print $companystatic->name_alias;
    +		print "</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Barcode
    +	if (! empty($arrayfields['s.barcode']['checked']))
    +	{
    +		print '<td>'.$obj->barcode.'</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Customer code
    +	if (! empty($arrayfields['s.code_client']['checked']))
    +	{
    +		print '<td>'.$obj->code_client.'</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Supplier code
    +	if (! empty($arrayfields['s.code_fournisseur']['checked']))
    +	{
    +		print '<td>'.$obj->code_fournisseur.'</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Account customer code
    +	if (! empty($arrayfields['s.code_compta']['checked']))
    +	{
    +		print '<td>'.$obj->code_compta.'</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Account supplier code
    +	if (! empty($arrayfields['s.code_compta_fournisseur']['checked']))
    +	{
    +		print '<td>'.$obj->code_compta_fournisseur.'</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Town
    +	if (! empty($arrayfields['s.town']['checked']))
    +	{
    +		print "<td>".$obj->town."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Zip
    +	if (! empty($arrayfields['s.zip']['checked']))
    +	{
    +		print "<td>".$obj->zip."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// State
    +	if (! empty($arrayfields['state.nom']['checked']))
    +	{
    +		print "<td>".$obj->state_name."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Region
    +	if (! empty($arrayfields['region.nom']['checked']))
    +	{
    +		print "<td>".$obj->region_name."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Country
    +	if (! empty($arrayfields['country.code_iso']['checked']))
    +	{
    +		print '<td align="center">';
    +		$tmparray=getCountry($obj->fk_pays,'all');
    +		print $tmparray['label'];
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Type ent
    +	if (! empty($arrayfields['typent.code']['checked']))
    +	{
    +		print '<td align="center">';
    +		if (! is_array($typenArray) || count($typenArray)==0) $typenArray = $formcompany->typent_array(1);
    +		print $typenArray[$obj->typent_code];
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.email']['checked']))
    +	{
    +		print "<td>".$obj->email."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.phone']['checked']))
    +	{
    +		print "<td>".$obj->phone."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.url']['checked']))
    +	{
    +		print "<td>".$obj->url."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.siren']['checked']))
    +	{
    +		print "<td>".$obj->idprof1."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.siret']['checked']))
    +	{
    +		print "<td>".$obj->idprof2."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.ape']['checked']))
    +	{
    +		print "<td>".$obj->idprof3."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.idprof4']['checked']))
    +	{
    +		print "<td>".$obj->idprof4."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.idprof5']['checked']))
    +	{
    +		print "<td>".$obj->idprof5."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.idprof6']['checked']))
    +	{
    +		print "<td>".$obj->idprof6."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.tva_intra']['checked']))
    +	{
    +		print "<td>".$obj->tva_intra."</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Type
    +	if (! empty($arrayfields['customerorsupplier']['checked']))
    +	{
    +		print '<td align="center">';
    +		$s='';
    +		if (($obj->client==1 || $obj->client==3) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))
    +		{
    +	  		$companystatic->name=$langs->trans("Customer");
    +	  		$companystatic->name_alias='';
    +			$s.=$companystatic->getNomUrl(0,'customer',0,1);
    +		}
    +		if (($obj->client==2 || $obj->client==3) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS))
    +		{
    +			if ($s) $s.=" / ";
    +			$companystatic->name=$langs->trans("Prospect");
    +	  		$companystatic->name_alias='';
    +			$s.=$companystatic->getNomUrl(0,'prospect',0,1);
    +		}
    +		if (! empty($conf->fournisseur->enabled) && $obj->fournisseur)
    +		{
    +			if ($s) $s.=" / ";
    +			$companystatic->name=$langs->trans("Supplier");
    +	  		$companystatic->name_alias='';
    +			$s.=$companystatic->getNomUrl(0,'supplier',0,1);
    +		}
    +		print $s;
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +
    +	if (! empty($arrayfields['s.fk_prospectlevel']['checked']))
    +	{
    +		// Prospect level
    +		print '<td align="center">';
    +		print $companystatic->getLibProspLevel();
    +		print "</td>";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +
    +	if (! empty($arrayfields['s.fk_stcomm']['checked']))
    +	{
    +		// Prospect status
    +		print '<td align="center" class="nowrap"><div class="nowrap">';
    +		print '<div class="inline-block">'.$companystatic->LibProspCommStatut($obj->stcomm_id,2,$prospectstatic->cacheprospectstatus[$obj->stcomm_id]['label']);
    +		print '</div> - <div class="inline-block">';
    +		foreach($prospectstatic->cacheprospectstatus as $key => $val)
    +		{
    +			$titlealt='default';
    +			if (! empty($val['code']) && ! in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt=$val['label'];
    +			if ($obj->stcomm_id != $val['id']) print '<a class="pictosubstatus" href="'.$_SERVER["PHP_SELF"].'?stcommsocid='.$obj->rowid.'&stcomm='.$val['code'].'&action=setstcomm'.$param.($page?'&page='.urlencode($page):'').'">'.img_action($titlealt,$val['code']).'</a>';
    +		}
    +		print '</div></div></td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Extra fields
    +	include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
    +	// Fields from hook
    +	$parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj);
    +	$reshook=$hookmanager->executeHooks('printFieldListValue',$parameters);    // Note that $action and $object may have been modified by hook
    +	print $hookmanager->resPrint;
    +	// Date creation
    +	if (! empty($arrayfields['s.datec']['checked']))
    +	{
    +		print '<td align="center" class="nowrap">';
    +		print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Date modification
    +	if (! empty($arrayfields['s.tms']['checked']))
    +	{
    +		print '<td align="center" class="nowrap">';
    +		print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
    +		print '</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Status
    +	if (! empty($arrayfields['s.status']['checked']))
    +	{
    +		print '<td align="center" class="nowrap">'.$companystatic->getLibStatut(3).'</td>';
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	if (! empty($arrayfields['s.import_key']['checked']))
    +	{
    +		print '<td class="tdoverflowmax100">';
    +		print $obj->import_key;
    +		print "</td>\n";
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +
    +	// Action column
    +	print '<td class="nowrap" align="center">';
    +	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->rowid, $arrayofselected)) $selected=1;
    +		print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected?' checked="checked"':'').'>';
    +	}
    +	print '</td>';
    +	if (! $i) $totalarray['nbfield']++;
    +
    +	print '</tr>'."\n";
    +	$i++;
    +}
    +
    +$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
    +print $hookmanager->resPrint;
    +
    +print "</table>";
    +print "</div>";
    +
    +print '</form>';
    +
    +llxFooter();
    +$db->close();
    diff --git a/htdocs/takepos/dev/img/README.md b/htdocs/takepos/dev/img/README.md
    new file mode 100644
    index 00000000000..5cd4c76d010
    --- /dev/null
    +++ b/htdocs/takepos/dev/img/README.md
    @@ -0,0 +1,53 @@
    +Source images
    +=============
    +
    +Used to generate icons and publication assets.
    +
    +Icons
    +-----
    +
    +### Dolibarr
    +
    +These resides in the [/img](../../img) directory.
    +
    +#### Small
    +
    +Required.
    +Name must begin by ```object_```.
    +
    +- Sample:  ![object_takepos.png](../../img/object_takepos.png) [object_takepos.png](../../img/object_takepos.png)
    +- Size: 14×14 pixels
    +- Type: PNG
    +
    +#### Large
    +
    +Optional.
    +
    +- Sample: ![takepos.png](../../img/takepos.png) [takepos.png](../../img/takepos.png)
    +- Size: 32×32 pixels
    +- Type: PNG
    +
    +### Dolistore
    +
    +Designed to fit a 512×512 icon + publisher branding.
    +
    +- Size: 704×704
    +- Type: PNG
    +
    +Export to 512×512
    +
    +### Transifex
    +
    +- Size: 96×96
    +- Type: PNG
    +
    +### Others
    +
    +To be on the safe side, you may also want to generate all popular sizes:
    +- 16×16
    +- 32×32
    +- 48×48
    +- 64×64
    +- 128×128
    +- 256×256
    +- 512×512
    diff --git a/htdocs/takepos/dev/img/gfdl-129x44.png b/htdocs/takepos/dev/img/gfdl-129x44.png
    new file mode 100644
    index 00000000000..f2bacfd179a
    Binary files /dev/null and b/htdocs/takepos/dev/img/gfdl-129x44.png differ
    diff --git a/htdocs/takepos/dev/img/gfdl-66x23.png b/htdocs/takepos/dev/img/gfdl-66x23.png
    new file mode 100644
    index 00000000000..b43479bf3c8
    Binary files /dev/null and b/htdocs/takepos/dev/img/gfdl-66x23.png differ
    diff --git a/htdocs/takepos/dev/img/gfdl-logo.svg b/htdocs/takepos/dev/img/gfdl-logo.svg
    new file mode 100644
    index 00000000000..a0daca0ead8
    --- /dev/null
    +++ b/htdocs/takepos/dev/img/gfdl-logo.svg
    @@ -0,0 +1,110 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    +   xmlns:cc="http://creativecommons.org/ns#"
    +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    +   width="110.72372"
    +   height="37.900333"
    +   id="svg3330"
    +   version="1.1"
    +   inkscape:version="0.48.0 r9654"
    +   sodipodi:docname="New document 4">
    +  <defs
    +     id="defs3332" />
    +  <sodipodi:namedview
    +     id="base"
    +     pagecolor="#ffffff"
    +     bordercolor="#666666"
    +     borderopacity="1.0"
    +     inkscape:pageopacity="0.0"
    +     inkscape:pageshadow="2"
    +     inkscape:zoom="3.959798"
    +     inkscape:cx="51.755214"
    +     inkscape:cy="19.316583"
    +     inkscape:document-units="px"
    +     inkscape:current-layer="layer1"
    +     showgrid="false"
    +     fit-margin-top="0"
    +     fit-margin-left="0"
    +     fit-margin-right="0"
    +     fit-margin-bottom="0"
    +     inkscape:window-width="1680"
    +     inkscape:window-height="950"
    +     inkscape:window-x="0"
    +     inkscape:window-y="27"
    +     inkscape:window-maximized="1" />
    +  <metadata
    +     id="metadata3335">
    +    <rdf:RDF>
    +      <cc:Work
    +         rdf:about="">
    +        <dc:format>image/svg+xml</dc:format>
    +        <dc:type
    +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    +        <dc:title></dc:title>
    +      </cc:Work>
    +    </rdf:RDF>
    +  </metadata>
    +  <g
    +     inkscape:label="Layer 1"
    +     inkscape:groupmode="layer"
    +     id="layer1"
    +     transform="translate(-319.64995,-513.41138)">
    +    <g
    +       id="g5424"
    +       transform="matrix(1.1204236,0,0,1.1204236,378.23897,-788.71491)">
    +      <path
    +         sodipodi:nodetypes="cccccc"
    +         inkscape:connector-curvature="0"
    +         id="rect6744"
    +         d="m -51.39745,1163.0948 85,0 0,29.5252 -85,0 2,-14.7626 z"
    +         style="fill:#f5efbc;fill-opacity:1;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0" />
    +      <text
    +         transform="scale(0.90245956,1.1080829)"
    +         sodipodi:linespacing="125%"
    +         id="text6752-6"
    +         y="1071.2108"
    +         x="-15.68348"
    +         style="font-size:24.31293869px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu Bold"
    +         xml:space="preserve"><tspan
    +           style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:URW Palladio L;-inkscape-font-specification:URW Palladio L Bold"
    +           y="1071.2108"
    +           x="-15.68348"
    +           id="tspan6754-4"
    +           sodipodi:role="line">GFDL</tspan></text>
    +      <path
    +         inkscape:connector-curvature="0"
    +         id="path7064-6"
    +         d="m 19.61576,1166.8577 0,24 0.1875,0 c -0.12127,0.1989 -0.1875,0.4164 -0.1875,0.625 0,2.002 5.8203,3.625 13,3.625 7.1797,0 13,-1.623 13,-3.625 0,-0.2086 -0.0662,-0.4261 -0.1875,-0.625 l 0.1875,0 0,-24 -26,0 z"
    +         style="color:#000000;fill:#f5efbc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
    +      <path
    +         transform="translate(-321.63424,901.70446)"
    +         d="m 367.25,264.98718 c 0,2.00203 -5.8203,3.625 -13,3.625 -7.1797,0 -13,-1.62297 -13,-3.625 0,-2.00203 5.8203,-3.625 13,-3.625 7.1797,0 13,1.62297 13,3.625 z"
    +         sodipodi:ry="3.625"
    +         sodipodi:rx="13"
    +         sodipodi:cy="264.98718"
    +         sodipodi:cx="354.25"
    +         id="path7064"
    +         style="color:#000000;fill:#f5efbc;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.79999995;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
    +         sodipodi:type="arc" />
    +      <path
    +         sodipodi:nodetypes="cccccc"
    +         inkscape:connector-curvature="0"
    +         id="path7104"
    +         d="m 45.06778,1167.3815 c -2.44864,5.5993 -9.9067,7.192 -21.52831,5.7955 l 5.7779,9.7599 -6.02275,7.2171 c 7.75095,3.1192 17.18643,1.5723 22.07112,-0.1842 z"
    +         style="fill:#2e439b;fill-opacity:1;stroke:#000000;stroke-width:1.39999986;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
    +      <path
    +         sodipodi:nodetypes="ccscc"
    +         inkscape:connector-curvature="0"
    +         id="path7106"
    +         d="m 34.45935,1165.7653 c -3.4695,-0.1017 -8.01646,0.018 -10.47747,0.7778 1.2102,0.9782 6.11198,1.5627 9.94714,1.2348 3.20297,-0.2738 6.08198,-0.1311 7.93857,-1.1503 -0.70667,-1.1077 -3.93837,-3.3774 -7.91865,-3.2613"
    +         style="fill:none;stroke:#000000;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
    +    </g>
    +  </g>
    +</svg>
    diff --git a/htdocs/takepos/dev/img/gpl-v3-logo.svg b/htdocs/takepos/dev/img/gpl-v3-logo.svg
    new file mode 100644
    index 00000000000..6754c994bda
    --- /dev/null
    +++ b/htdocs/takepos/dev/img/gpl-v3-logo.svg
    @@ -0,0 +1,389 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +<svg
    +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    +   xmlns:cc="http://creativecommons.org/ns#"
    +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    +   width="744.09448819"
    +   height="1052.3622047"
    +   id="svg1341"
    +   sodipodi:version="0.32"
    +   inkscape:version="0.46"
    +   sodipodi:docbase="/home/johns/graphics/logos/gplv3"
    +   sodipodi:docname="gpl-v3-logo (copy).svg"
    +   inkscape:output_extension="org.inkscape.output.svg.inkscape">
    +  <defs
    +     id="defs1343">
    +    <inkscape:perspective
    +       sodipodi:type="inkscape:persp3d"
    +       inkscape:vp_x="0 : 526.18109 : 1"
    +       inkscape:vp_y="0 : 1000 : 0"
    +       inkscape:vp_z="744.09448 : 526.18109 : 1"
    +       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
    +       id="perspective79" />
    +  </defs>
    +  <sodipodi:namedview
    +     id="base"
    +     pagecolor="#ffffff"
    +     bordercolor="#666666"
    +     borderopacity="1.0"
    +     inkscape:pageopacity="0.0"
    +     inkscape:pageshadow="2"
    +     inkscape:zoom="0.56729519"
    +     inkscape:cx="372.04724"
    +     inkscape:cy="526.18109"
    +     inkscape:document-units="px"
    +     inkscape:current-layer="layer1"
    +     inkscape:window-width="1439"
    +     inkscape:window-height="825"
    +     inkscape:window-x="1"
    +     inkscape:window-y="49"
    +     showgrid="false" />
    +  <metadata
    +     id="metadata1346">
    +    <rdf:RDF>
    +      <cc:Work
    +         rdf:about="">
    +        <dc:format>image/svg+xml</dc:format>
    +        <dc:type
    +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    +      </cc:Work>
    +    </rdf:RDF>
    +  </metadata>
    +  <g
    +     inkscape:label="Layer 1"
    +     inkscape:groupmode="layer"
    +     id="layer1">
    +    <g
    +       id="g3413"
    +       transform="translate(1.7627461,148.07106)">
    +      <g
    +         id="g68"
    +         style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,352.86817,563.90874)">
    +        <path
    +           style="fill:#000000;fill-opacity:0.94117647"
    +           id="path70"
    +           d="M 3.86,0 C 3.86,0 3.85,0 3.85,0 C 2.91,0 2.08,0.31 1.3,0.94 C 0.72,1.4 0.32,2.02 0,2.71 C 0,2.71 0.04,2.71 0.04,2.71 C 0.36,2.02 0.76,1.4 1.33,0.94 C 2.11,0.31 2.94,0.01 3.86,0 z" />
    +      </g>
    +      <path
    +         style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         d="M 92.93948,358.4642 C 92.9395,358.46419 33.62975,617.23158 33.62975,617.23158 C 33.6468,617.23158 33.64894,617.23158 33.68304,617.23158 C 33.68304,617.23158 308.06385,617.23158 308.06385,617.23158 C 308.06386,617.23158 450.76958,617.23158 450.76958,617.23158 C 433.76851,615.74805 420.34631,609.77976 412.34882,598.90046 C 410.86529,596.88827 409.63964,594.72053 408.56535,592.45258 C 407.88328,590.78148 407.24167,589.09543 406.59368,587.39021 C 404.88844,581.9676 404.20851,575.9503 404.51544,569.53867 C 405.36806,551.66793 413.75349,530.41065 428.28198,508.15069 C 443.71423,484.49413 466.08035,459.6998 493.77314,436.69125 C 499.98013,431.53806 506.39817,426.44926 513.11675,421.50411 C 521.42116,415.39432 529.78956,409.7675 538.1622,404.50518 C 569.00965,385.08441 599.78037,371.49508 627.04687,364.59234 C 600.9911,373.09287 571.71882,387.52374 542.79826,407.1696 C 541.7581,407.87215 540.73068,408.59175 539.70754,409.30112 C 523.66141,420.41917 509.1244,432.22698 496.43756,444.15158 C 455.61453,482.53615 434.0371,522.31042 443.84212,545.61227 C 444.54128,547.21517 445.37468,548.74562 446.34667,550.19506 C 456.88492,565.69553 483.00254,568.37485 516.10089,560.05337 C 518.35178,559.49062 520.60267,558.85333 522.92177,558.18829 C 533.49415,555.13592 544.71877,551.01356 556.28017,545.93201 C 559.05966,544.70424 561.86904,543.44238 564.6997,542.09525 C 564.98958,541.95884 565.26243,541.82242 565.55231,541.66895 C 602.04404,523.53733 630.08856,502.67437 636.15915,490.13928 C 637.48923,487.41266 637.80895,485.08798 636.90518,483.26511 C 632.57394,474.48323 602.26573,480.41611 565.55231,496.32071 C 562.60228,497.59961 559.61814,498.91563 556.5999,500.31732 C 559.05542,498.03746 561.61113,495.74904 564.2201,493.49643 C 568.38085,489.91205 572.68866,486.40698 577.2757,482.94539 C 584.4547,477.50912 591.71255,472.59468 598.85743,468.23785 C 632.31386,442.99718 649.22753,419.12063 645.69773,410.26032 C 645.03268,408.59089 643.61736,407.44243 641.43467,406.74329 C 634.46029,404.52482 621.73084,407.17258 606.26448,413.51089 C 593.50944,418.74253 578.85944,426.50169 564.00696,436.15837 C 564.00696,436.15837 561.98201,437.49057 561.98201,437.49057 C 561.98203,437.49057 561.60899,437.70371 561.60899,437.70371 C 561.60901,437.70373 554.46838,442.44636 554.46838,442.44636 C 554.46836,442.44635 558.57157,434.93273 558.57157,434.93273 C 564.65922,423.78909 574.57507,412.16206 586.92087,401.36119 C 595.9756,393.4643 606.3199,386.02357 617.455,379.51303 C 621.66691,377.0473 625.8724,374.75717 630.08429,372.69215 C 634.39851,370.58449 638.71484,368.7113 642.92675,367.0436 C 655.16357,362.20425 666.84456,359.26379 677.03117,358.4642 C 676.1035,358.46419 648.41543,358.4642 648.41543,358.4642 C 648.41544,358.46419 551.96384,358.4642 551.96384,358.4642 C 551.96385,358.46419 126.67089,358.4642 126.67089,358.4642 C 126.67089,358.46419 92.93948,358.4642 92.93948,358.4642 z M 398.92019,358.83722 C 397.2491,384.34222 402.19422,421.69937 413.41458,463.17546 C 415.40967,470.55567 417.5817,478.06631 419.96902,485.66308 C 421.45258,490.35412 422.98301,494.97189 424.5518,499.518 C 423.631,500.87196 422.70376,502.21737 421.8341,503.5679 C 407.83425,525.02298 399.6513,545.29894 397.58799,562.93093 C 391.67085,543.11625 387.21598,521.41263 384.69225,498.39895 C 383.97606,491.80485 383.41546,485.28453 383.04031,478.8422 C 380.27784,432.04581 386.3868,389.625 398.92019,358.83722 z M 119.53029,392.03576 C 119.84963,392.02822 120.16443,392.03576 120.48947,392.03576 C 120.48947,392.03574 183.52938,392.03576 183.52938,392.03576 C 188.91789,392.03574 193.08502,393.04567 196.0521,395.07318 C 199.00212,397.11264 200.10841,399.75061 199.40925,402.95983 C 199.40927,402.95985 191.89562,436.90439 191.89562,436.90439 C 191.89562,436.90442 169.67446,436.90439 169.67446,436.90439 C 169.67448,436.90442 176.97494,403.86573 176.97494,403.86573 C 176.97492,403.86573 121.34209,403.86573 121.34209,403.86573 C 121.34207,403.86573 101.25244,494.66878 101.25244,494.66878 C 101.25246,494.66878 94.00525,527.54759 94.00525,527.54759 C 94.00525,527.54762 149.58482,527.54759 149.58482,527.54759 C 149.58482,527.54762 149.63811,527.33443 149.63811,527.33443 C 149.63811,527.33445 160.77533,477.03039 160.77533,477.03039 C 160.77533,477.03037 134.66413,477.03039 134.66413,477.03039 C 134.66413,477.03037 137.16867,465.68001 137.16867,465.68001 C 137.16866,465.67999 185.50105,465.68001 185.50105,465.68001 C 185.50105,465.67999 171.64612,528.45349 171.64612,528.45349 C 171.45855,529.34701 171.1303,530.15657 170.68693,530.95802 C 169.54444,533.03839 167.55146,534.82036 164.77195,536.28685 C 160.91817,538.31608 156.30552,539.32427 150.91702,539.32427 C 150.91702,539.32429 87.9304,539.32427 87.9304,539.32427 C 82.54188,539.32429 78.37476,538.31606 75.40768,536.28685 C 72.45767,534.25765 71.33433,531.66612 72.05053,528.45349 C 72.05054,528.45347 99.81366,402.95983 99.81366,402.95983 C 100.52984,399.75062 102.76371,397.11262 106.63455,395.07318 C 106.77097,394.99987 106.92444,394.98323 107.06085,394.91332 C 110.59387,393.14362 114.74022,392.14889 119.53029,392.03576 z M 218.32657,392.03576 C 218.32655,392.03574 297.67265,392.03576 297.67265,392.03576 C 302.99296,392.03574 307.175,393.04567 310.14208,395.07318 C 313.12625,397.11264 314.26874,399.75061 313.55253,402.95983 C 313.55255,402.95985 298.73842,469.88978 298.73842,469.88978 C 298.0393,473.07852 295.75215,475.68028 291.86425,477.72314 C 287.97635,479.7728 283.39995,480.81385 278.06261,480.81385 C 278.06259,480.81385 220.40481,480.81385 220.40481,480.81385 C 220.40481,480.81385 209.26758,531.0646 209.26758,531.0646 C 209.26758,531.06462 207.45578,539.32427 207.45578,539.32427 C 207.45579,539.32429 185.7142,539.32427 185.7142,539.32427 C 185.7142,539.32429 187.36613,531.86393 187.36613,531.86393 C 187.36613,531.86395 218.32657,392.03576 218.32657,392.03576 z M 327.94034,392.03576 C 327.94033,392.03574 349.68192,392.03576 349.68192,392.03576 C 349.68194,392.03574 325.06278,503.24817 325.06278,503.24817 C 325.0628,503.24819 319.68068,527.54759 319.68068,527.54759 C 319.68068,527.54762 371.68994,527.54759 371.68994,527.54759 C 372.23562,531.53613 372.87293,535.45341 373.55502,539.32427 C 373.555,539.32429 295.32797,539.32427 295.32797,539.32427 C 295.32799,539.32429 301.5094,511.40126 301.5094,511.40126 C 301.50942,511.40126 327.94034,392.03576 327.94034,392.03576 z M 237.45702,403.86573 C 237.45704,403.86573 223.01592,468.98387 223.01592,468.98387 C 223.01592,468.98385 277.21,468.98387 277.21,468.98387 C 277.20999,468.98385 291.5978,403.86573 291.5978,403.86573 C 291.59782,403.86573 237.45702,403.86573 237.45702,403.86573 z M 191.89562,549.5556 C 192.10829,549.54845 192.32086,549.5556 192.53509,549.5556 C 195.05882,549.55562 197.26281,549.99896 199.03624,550.83451 C 200.92904,551.72122 202.28256,553.03851 203.03286,554.77784 C 203.76611,556.46603 203.95794,558.38225 203.56573,560.47968 C 203.56573,560.47969 203.40588,561.27901 203.40588,561.27901 C 203.40589,561.27898 197.17116,561.27901 197.17116,561.27901 C 197.17114,561.27898 197.22445,560.53296 197.22445,560.53296 C 197.38563,559.06753 197.20396,557.91517 196.63827,557.12253 C 196.56455,557.02312 196.45774,556.8919 196.37183,556.8028 C 196.23115,556.65917 196.01985,556.495 195.83896,556.37649 C 194.96658,555.82699 193.60193,555.52387 191.84234,555.52387 C 189.50619,555.52389 187.76047,555.93099 186.56682,556.74951 C 185.40726,557.55097 184.67402,558.44621 184.43529,559.52049 C 184.19654,560.61183 184.58875,561.18521 184.8616,561.49215 C 184.8701,561.50064 184.90453,561.53592 184.91487,561.54544 C 185.26039,561.83989 186.46023,562.5302 190.1904,563.41052 C 193.56672,564.22903 195.80272,564.96441 197.06458,565.59534 C 198.97445,566.5673 200.30877,567.82704 201.00792,569.3788 C 201.70703,570.91352 201.86052,572.71037 201.43422,574.65433 C 201.00792,576.54712 200.04233,578.29285 198.60994,579.92987 C 197.19462,581.56687 195.39347,582.86284 193.22783,583.7666 C 191.07923,584.65332 188.72179,585.15209 186.30037,585.15209 C 183.23097,585.15208 180.76694,584.68742 178.84003,583.7666 C 176.82786,582.81169 175.37629,581.3047 174.52369,579.34369 C 173.70518,577.43383 173.53039,575.26607 173.9908,572.89583 C 173.9908,572.8958 174.15067,572.14978 174.15067,572.14978 C 174.15067,572.14978 180.27881,572.14978 180.27881,572.14978 C 180.27881,572.14978 180.22552,572.89583 180.22552,572.89583 C 180.07204,574.31115 180.22339,575.45365 180.59854,576.30626 C 180.95663,577.12479 181.63873,577.80259 182.73006,578.33122 C 183.8896,578.89392 185.33904,579.18382 186.99311,579.18382 C 188.47666,579.18381 189.83232,578.93443 191.04302,578.49109 C 192.23667,578.06479 193.1852,577.50205 193.86729,576.78586 C 194.53231,576.06964 194.9224,575.31298 195.09292,574.49446 C 195.26344,573.76122 195.22294,573.14096 194.93305,572.62938 C 194.60906,572.08374 193.96747,571.59985 192.9614,571.1906 C 192.9614,571.19059 187.73914,569.64524 187.73914,569.64524 C 184.82322,568.91201 182.86009,568.21286 181.71759,567.51372 C 180.16582,566.59291 179.04678,565.41203 178.467,563.9967 C 177.88723,562.59839 177.82542,561.04879 178.20057,559.36062 C 178.59277,557.55309 179.46456,555.83295 180.81168,554.29825 C 182.17588,552.74648 183.9365,551.5294 186.03393,550.72794 C 187.88836,550.03254 189.83989,549.62473 191.89562,549.5556 z M 247.84822,549.66218 C 248.18547,549.63591 248.50258,549.66218 248.86069,549.66218 C 248.8607,549.66218 252.69744,550.08848 252.69744,550.08848 C 252.69743,550.08848 253.97635,550.19506 253.97635,550.19506 C 253.97637,550.19507 252.11127,554.9377 252.11127,554.9377 C 252.11126,554.93772 251.73825,555.68374 251.73825,555.68374 C 251.73825,555.68372 248.80741,555.4173 248.80741,555.4173 C 247.942,555.4173 247.30628,555.55082 246.88903,555.8436 C 246.86132,555.86453 246.80803,555.9278 246.78245,555.95018 C 246.72655,555.99922 246.63254,556.08476 246.5693,556.16334 C 246.31271,556.49985 246.00018,557.1012 245.76998,558.18829 C 245.76996,558.18829 245.65914,558.64869 245.55683,559.0409 C 246.90396,559.04091 250.1396,559.0409 250.1396,559.0409 C 250.1396,559.04091 248.96727,564.31642 248.96727,564.31642 C 248.96727,564.31641 245.61651,564.31642 244.49107,564.31642 C 244.15001,565.85111 239.96157,584.61922 239.96157,584.61922 C 239.96155,584.6192 233.78014,584.61922 233.78014,584.61922 C 233.78012,584.6192 237.79807,566.58437 238.30964,564.31642 C 237.26943,564.31641 234.73933,564.31642 234.73933,564.31642 C 234.73933,564.31641 235.91167,559.0409 235.91167,559.0409 C 235.91168,559.04091 238.45671,559.0409 239.42868,559.0409 C 239.5992,558.30766 239.85498,557.38896 239.85498,557.38896 C 240.23014,555.68374 240.62233,554.45811 241.13389,553.6055 C 241.83306,552.42891 242.81995,551.44413 244.06476,550.72794 C 245.09003,550.13219 246.38674,549.776 247.84822,549.66218 z M 262.60904,549.92862 C 262.60902,549.92861 260.99334,557.19926 260.58409,559.0409 C 261.77773,559.04091 264.5807,559.0409 264.5807,559.0409 C 264.5807,559.04091 263.40837,564.31642 263.40837,564.31642 C 263.40835,564.31641 260.46898,564.31642 259.41175,564.31642 C 259.08774,565.78289 256.53419,577.15888 256.53419,577.15888 C 256.53421,577.15886 256.32103,578.52519 256.32103,578.91739 C 256.32131,578.93044 256.31997,578.96107 256.32103,578.97067 C 256.32187,578.9747 256.31983,579.02064 256.32103,579.02396 C 256.32267,579.02665 256.37218,579.02182 256.37431,579.02396 C 256.37431,579.02394 257.01378,579.07725 257.01378,579.07725 C 257.01378,579.07725 259.94463,578.8641 259.94463,578.8641 C 259.94463,578.8641 259.6249,583.60674 259.6249,583.60674 C 259.62492,583.60674 259.6782,584.45935 259.6782,584.45935 C 259.67818,584.45933 255.46842,584.93895 255.46842,584.93895 C 253.79732,584.93893 252.57167,584.66612 251.68496,584.08635 C 250.74711,583.47243 250.20142,582.65821 249.97974,581.63509 C 249.94563,581.4475 249.87316,581.17467 249.87316,580.78248 C 249.87316,580.01512 250.01811,578.71703 250.51262,576.46614 C 250.51264,576.46616 252.75285,566.4309 253.23032,564.31642 C 252.42889,564.31641 250.29947,564.31642 250.29947,564.31642 C 250.29949,564.31641 251.4718,559.0409 251.4718,559.0409 C 251.47178,559.04091 253.55004,559.0409 254.40266,559.0409 C 254.67547,557.81315 255.62828,553.6055 255.62828,553.6055 C 255.62828,553.60552 260.58409,550.99438 260.58409,550.99438 C 260.58408,550.9944 262.60904,549.92862 262.60904,549.92862 z M 66.24211,550.14177 C 66.24213,550.14177 90.22179,550.14177 90.22179,550.14177 C 90.22179,550.14177 88.88959,556.11005 88.88959,556.11005 C 88.88959,556.11007 72.89248,556.11005 71.35778,556.11005 C 71.08496,557.32078 69.99147,562.22327 69.59927,563.9967 C 71.81607,563.9967 84.7864,563.9967 84.7864,563.9967 C 84.7864,563.9967 83.45419,569.96496 83.45419,569.96496 C 83.45418,569.96496 69.80177,569.96496 68.26706,569.96496 C 67.94307,571.44851 65.01648,584.61922 65.01648,584.61922 C 65.0165,584.6192 58.56862,584.61922 58.56862,584.61922 C 58.56863,584.6192 66.24211,550.14177 66.24211,550.14177 z M 98.37487,558.56131 C 98.61554,558.53175 98.87845,558.56131 99.12091,558.56131 C 100.65561,558.56131 102.07308,559.02811 103.43726,560.00008 C 103.43726,560.0001 104.28986,560.58625 104.28986,560.58625 C 104.28986,560.58625 100.986,566.02165 100.986,566.02165 C 100.986,566.02163 100.08011,565.38219 100.08011,565.38219 C 99.41507,564.9559 98.69888,564.74273 97.94858,564.74273 C 97.30059,564.74275 96.69737,564.97293 96.08349,565.38219 C 95.43552,565.80849 94.89409,566.37334 94.48485,567.1407 C 93.76865,568.45374 93.24429,569.92447 92.8862,571.51033 C 92.8862,571.51034 90.00864,584.61922 90.00864,584.61922 C 90.00864,584.6192 83.82721,584.61922 83.82721,584.61922 C 83.82721,584.6192 89.52905,559.0409 89.52905,559.0409 C 89.52907,559.04091 95.28417,559.0409 95.28417,559.0409 C 95.28417,559.04091 95.08593,559.81678 95.01772,560.10666 C 95.29056,559.90205 95.57831,559.62067 95.81705,559.4672 C 96.64302,558.9743 97.51542,558.66685 98.37487,558.56131 z M 116.70601,558.56131 C 117.0782,558.53316 117.4446,558.56131 117.82507,558.56131 C 121.30373,558.56131 123.93615,559.78053 125.65842,562.1849 C 126.7327,563.73664 127.31037,565.65502 127.31037,567.94002 C 127.31037,569.20187 127.15476,570.55967 126.83078,572.04321 C 126.83078,572.04321 126.35117,573.9083 126.35117,573.9083 C 126.35117,573.90828 110.71856,573.9083 108.97923,573.9083 C 108.94512,574.26638 108.92594,574.65007 108.92594,574.97406 C 108.92594,576.30415 109.19877,577.35071 109.77855,578.11807 C 110.05405,578.4932 110.37345,578.83106 110.73774,579.07725 C 111.42452,579.52514 112.31108,579.77 113.34886,579.77 C 114.61074,579.76998 115.71911,579.42255 116.7593,578.75752 C 117.74835,578.12659 118.69474,577.11838 119.53029,575.7201 C 119.53029,575.72007 126.13802,575.7201 126.13802,575.7201 C 126.13802,575.72007 125.55186,576.99901 125.55186,576.99901 C 124.28999,579.55686 122.52935,581.55195 120.32961,582.96729 C 118.12988,584.38262 115.5017,585.15209 112.60282,585.15209 C 108.83428,585.15208 106.02919,583.93287 104.28986,581.52851 C 102.5676,579.17528 102.19671,575.92258 103.11753,571.83005 C 104.03836,567.66932 105.87573,564.34414 108.55292,562.02503 C 110.9525,559.94441 113.67537,558.79035 116.70601,558.56131 z M 144.46916,558.56131 C 144.84134,558.53316 145.20773,558.56131 145.5882,558.56131 C 149.06687,558.56131 151.6993,559.78053 153.42157,562.1849 C 154.49586,563.73664 155.0735,565.65502 155.0735,567.94002 C 155.0735,569.18482 154.9179,570.52343 154.5939,571.98992 C 154.5939,571.98994 154.11432,573.9083 154.11432,573.9083 C 154.11432,573.90828 138.48169,573.9083 136.74237,573.9083 C 136.7253,574.147 136.70613,574.36232 136.68908,574.60105 C 136.67629,574.69057 136.69468,574.82646 136.68908,574.92077 C 136.68858,574.93615 136.68908,574.95914 136.68908,574.97406 C 136.68908,575.22986 136.72532,575.48136 136.74237,575.7201 C 136.8276,576.69206 137.08129,577.50419 137.54169,578.11807 C 137.62936,578.23743 137.71177,578.38477 137.80813,578.49109 C 138.58914,579.32663 139.69453,579.77 141.112,579.77 C 142.37388,579.76998 143.49931,579.42255 144.52245,578.75752 C 145.51149,578.12659 146.45787,577.11838 147.29343,575.7201 C 147.29343,575.72007 153.95445,575.7201 153.95445,575.7201 C 153.95444,575.72007 153.31499,576.99901 153.31499,576.99901 C 152.05313,579.55686 150.29249,581.55195 148.09275,582.96729 C 145.89301,584.38262 143.26484,585.15209 140.36597,585.15209 C 136.59744,585.15208 133.79234,583.93287 132.05301,581.52851 C 130.92756,579.99379 130.40107,578.0392 130.40107,575.7201 C 130.40107,575.36198 130.42025,574.97619 130.45436,574.60105 C 130.52259,573.71434 130.65899,572.81909 130.88067,571.83005 C 131.80151,567.68637 133.58558,564.34414 136.26277,562.02503 C 138.66234,559.94441 141.43852,558.79035 144.46916,558.56131 z M 220.08507,558.56131 C 220.46591,558.53202 220.81619,558.56131 221.20412,558.56131 C 224.75099,558.56131 227.47722,559.76135 229.25064,562.13161 C 231.00704,564.50184 231.43333,567.69915 230.52955,571.72347 C 229.83042,574.8611 228.82008,577.39547 227.43885,579.23712 C 226.05759,581.07877 224.29697,582.58361 222.21659,583.60674 C 220.15331,584.62988 217.96846,585.15209 215.76873,585.15209 C 212.15366,585.15208 209.46154,583.91581 207.72221,581.52851 C 206.59675,580.01087 206.01699,578.05625 206.01699,575.7201 C 206.01701,574.45823 206.15555,573.1175 206.49659,571.61691 C 207.51974,567.0469 209.60861,563.56613 212.67802,561.33229 C 214.93103,559.70595 217.41916,558.76623 220.08507,558.56131 z M 313.7124,558.56131 C 314.162,558.53356 314.57833,558.56131 315.0446,558.56131 C 317.19319,558.56131 318.88135,558.77871 320.16027,559.30733 C 321.52445,559.85302 322.49216,560.62462 323.03783,561.54544 C 323.56647,562.41507 323.83716,563.483 323.83716,564.79601 C 323.83717,564.79603 323.19768,568.68605 323.19768,568.68605 C 323.19771,568.68605 322.02536,573.96159 322.02536,573.96159 C 321.01925,578.46335 320.7976,580.15154 320.74643,580.78248 C 320.69528,581.6351 320.77414,582.46638 321.01288,583.23373 C 321.0129,583.23371 321.43918,584.61922 321.43918,584.61922 C 321.4392,584.6192 315.15118,584.61922 315.15118,584.61922 C 315.15116,584.6192 314.88473,583.81989 314.88473,583.81989 C 314.78242,583.44477 314.81226,582.96729 314.77816,582.54098 C 313.58451,583.27423 312.38872,583.92434 311.31443,584.29949 C 309.72859,584.84518 308.08304,585.15209 306.41192,585.15209 C 303.51306,585.15208 301.3666,584.39755 300.07062,582.91399 C 299.0816,581.82266 298.63185,580.48832 298.63185,578.97067 C 298.63183,578.3909 298.70858,577.7898 298.84499,577.15888 C 299.13487,575.86291 299.66137,574.66285 300.49693,573.58856 C 301.31544,572.5313 302.28316,571.66167 303.37449,571.03074 C 304.43175,570.39982 305.61047,569.95219 306.83823,569.64524 C 306.83821,569.64524 310.62169,569.00578 310.62169,569.00578 C 313.53763,568.66472 315.7139,568.24057 317.28271,567.78016 C 317.31683,567.60964 317.38928,567.40714 317.38928,567.40714 C 317.63654,566.30996 317.6056,565.48526 317.33599,565.06246 C 317.31615,565.03519 317.25181,564.97932 317.22942,564.95588 C 317.17186,564.89453 317.08339,564.79809 317.01626,564.74273 C 316.37491,564.2352 315.2812,563.9967 313.81898,563.9967 C 312.16491,563.9967 310.94142,564.26741 310.0888,564.79601 C 309.25325,565.32464 308.47949,566.29235 307.79741,567.67357 C 307.7974,567.67356 301.34954,567.67357 301.34954,567.67357 C 301.34956,567.67356 301.93571,566.39466 301.93571,566.39466 C 302.70304,564.62121 303.61749,563.15048 304.75999,562.02503 C 305.90249,560.89956 307.44571,560.02779 309.23619,559.41392 C 310.60835,558.96095 312.10669,558.66038 313.7124,558.56131 z M 340.72951,558.56131 C 340.96997,558.53175 341.23307,558.56131 341.47554,558.56131 C 343.02727,558.56131 344.48099,559.02811 345.84517,560.00008 C 345.84519,560.0001 346.64449,560.58625 346.64449,560.58625 C 346.6445,560.58625 343.34063,566.02165 343.34063,566.02165 C 343.34064,566.02163 342.43473,565.38219 342.43473,565.38219 C 341.7697,564.9559 341.08972,564.74273 340.35649,564.74273 C 339.70848,564.74275 339.06905,564.97293 338.4381,565.38219 C 337.79013,565.80849 337.31906,566.37334 336.89276,567.1407 C 336.1936,568.45374 335.6522,569.92447 335.29411,571.51033 C 335.29409,571.51034 332.36326,584.61922 332.36326,584.61922 C 332.36328,584.6192 326.18184,584.61922 326.18184,584.61922 C 326.18184,584.6192 331.88366,559.0409 331.88366,559.0409 C 331.88365,559.04091 337.63878,559.0409 337.63878,559.0409 C 337.63878,559.04091 337.49384,559.81678 337.42564,560.10666 C 337.69846,559.90205 337.96917,559.62067 338.22496,559.4672 C 339.03759,558.9743 339.87067,558.66685 340.72951,558.56131 z M 359.00734,558.56131 C 359.37919,558.53316 359.74593,558.56131 360.1264,558.56131 C 363.60506,558.56131 366.25453,559.78053 367.95977,562.1849 C 369.05112,563.73664 369.6117,565.65502 369.6117,567.94002 C 369.61168,569.20187 369.4028,570.55967 369.07881,572.04321 C 369.07881,572.04321 368.65251,573.9083 368.65251,573.9083 C 368.6525,573.90828 353.00283,573.9083 351.28057,573.9083 C 351.24646,574.26638 351.17398,574.65007 351.17398,574.97406 C 351.17398,576.30415 351.46387,577.35071 352.0266,578.11807 C 352.11426,578.23743 352.2496,578.38477 352.34632,578.49109 C 352.40234,578.55076 352.50044,578.64882 352.55948,578.70423 C 353.32183,579.39725 354.35929,579.77 355.65018,579.77 C 356.91207,579.76998 358.02045,579.42255 359.06063,578.75752 C 360.04968,578.12659 360.97902,577.11838 361.83162,575.7201 C 361.8316,575.72007 368.49264,575.7201 368.49264,575.7201 C 368.49264,575.72007 367.85318,576.99901 367.85318,576.99901 C 366.59131,579.55686 364.81363,581.55195 362.63094,582.96729 C 360.41417,584.38262 357.82009,585.15209 354.90415,585.15209 C 351.13564,585.15208 348.38381,583.93287 346.64449,581.52851 C 344.92219,579.17528 344.51509,575.92258 345.41886,571.83005 C 346.33967,567.66932 348.12377,564.34414 350.80097,562.02503 C 353.21572,559.94441 355.97949,558.79035 359.00734,558.56131 z M 265.69974,559.0409 C 265.69976,559.04091 272.04105,559.0409 272.04105,559.0409 C 272.04107,559.04091 272.82331,574.21951 272.84036,574.44117 C 273.09614,573.89761 273.2946,573.4403 273.31997,573.37542 C 273.31998,573.37543 280.30071,559.0409 280.30071,559.0409 C 280.30073,559.04091 286.10912,559.0409 286.10912,559.0409 C 286.10911,559.04091 286.642,574.03618 286.642,574.12144 C 286.81255,573.81453 294.58194,559.0409 294.58194,559.0409 C 294.58192,559.04091 300.86995,559.0409 300.86995,559.0409 C 300.86994,559.04091 287.01502,584.61922 287.01502,584.61922 C 287.01504,584.6192 281.31319,584.61922 281.31319,584.61922 C 281.31319,584.6192 280.76113,570.74938 280.72702,569.96496 C 278.37379,574.79076 273.58639,584.61922 273.58639,584.61922 C 273.58639,584.6192 267.72471,584.61922 267.72471,584.61922 C 267.72471,584.6192 265.69974,559.0409 265.69974,559.0409 z M 116.81259,563.89012 C 115.34366,563.95214 114.00964,564.48161 112.7627,565.48876 C 111.77368,566.27317 111.10649,567.3496 110.57787,568.52619 C 110.57787,568.52621 121.07564,568.52619 121.07564,568.52619 C 121.09271,568.33863 121.12893,568.11055 121.12893,567.94002 C 121.12891,566.96807 120.95627,566.21349 120.64934,565.70192 C 119.89906,564.47415 118.78639,563.89012 117.13232,563.89012 C 117.03322,563.89012 116.91052,563.886 116.81259,563.89012 z M 144.57572,563.89012 C 143.1068,563.95214 141.77277,564.48161 140.52582,565.48876 C 139.53678,566.27317 138.88669,567.3496 138.34102,568.52619 C 138.34102,568.52621 148.83878,568.52619 148.83878,568.52619 C 148.85582,568.33863 148.89207,568.11055 148.89207,567.94002 C 148.89206,566.96807 148.73647,566.21349 148.41247,565.70192 C 148.26353,565.45253 148.06204,565.20453 147.87959,565.00918 C 147.1676,564.27346 146.18769,563.89012 144.89546,563.89012 C 144.79635,563.89012 144.67366,563.886 144.57572,563.89012 z M 359.32708,563.89012 C 357.81652,563.93665 356.40583,564.44806 355.11731,565.48876 C 354.14533,566.27317 353.47816,567.3496 352.93249,568.52619 C 352.93251,568.52621 363.37698,568.52619 363.37698,568.52619 C 363.39401,568.33863 363.43027,568.11055 363.43027,567.94002 C 363.43026,566.96807 363.27467,566.21349 362.95067,565.70192 C 362.21743,564.4912 361.08771,563.90718 359.43365,563.89012 C 359.38463,563.89065 359.37581,563.88862 359.32708,563.89012 z M 219.71206,563.9967 C 218.30243,564.16409 216.9917,564.80721 215.76873,565.91507 C 214.30225,567.24516 213.23861,569.33404 212.62474,572.0965 C 212.36895,573.25605 212.25171,574.24721 212.25171,575.13392 C 212.25173,576.34462 212.48404,577.29529 212.94446,578.01148 C 213.06703,578.19532 213.22962,578.38959 213.37077,578.54437 C 214.12881,579.34925 215.18736,579.77 216.51477,579.77 C 218.23703,579.76998 219.75469,579.12841 221.20412,577.79833 C 222.67064,576.45119 223.71719,574.34099 224.34812,571.51033 C 224.92792,568.91838 224.8469,566.98297 224.0284,565.75521 C 223.244,564.56155 222.09724,563.9967 220.51139,563.9967 C 220.24228,563.9967 219.97309,563.96569 219.71206,563.9967 z M 316.00379,573.32213 C 314.55438,573.71431 312.93012,574.04471 310.78155,574.33461 C 309.17866,574.57335 308.03614,574.82485 307.3711,575.08064 C 306.79134,575.31936 306.32452,575.64975 305.93232,576.09312 C 305.55716,576.51939 305.30566,576.96704 305.1863,577.47861 C 305.15221,577.68325 305.133,577.89425 305.133,578.06478 C 305.133,578.07862 305.13269,578.10436 305.133,578.11807 C 305.13479,578.15865 305.12855,578.23877 305.133,578.27792 C 305.14368,578.35529 305.16517,578.47232 305.1863,578.54437 C 305.19392,578.5681 305.23081,578.62776 305.23957,578.65094 C 305.25823,578.69678 305.26972,578.76705 305.29286,578.81081 C 305.31713,578.85407 305.37076,578.9293 305.39944,578.97067 C 305.44408,579.03204 305.50494,579.12627 305.55931,579.18382 C 305.98562,579.66128 306.83609,579.87657 308.06385,579.87657 C 309.411,579.87658 310.70695,579.62079 311.9006,579.02396 C 313.07722,578.44419 314.02573,577.57878 314.72487,576.5727 C 315.23646,575.8565 315.6457,574.7545 316.00379,573.32213 z"
    +         id="path74" />
    +      <g
    +         id="g80"
    +         style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,359.45027,563.90874)">
    +        <path
    +           style="fill:#000000;fill-opacity:0.94117647"
    +           id="path82"
    +           d="M 0.03,0 C 0.02,0 0.01,0 0,0 C 0.97,0.01 1.61,0.34 2.04,1.05 C 2.23,1.35 2.33,1.8 2.33,2.37 C 2.33,2.47 2.31,2.6 2.3,2.71 C 2.3,2.71 2.34,2.71 2.34,2.71 C 2.34,2.6 2.36,2.47 2.36,2.37 C 2.36,1.8 2.27,1.35 2.08,1.05 C 1.65,0.33 1,0 0.03,0 z" />
    +      </g>
    +      <g
    +         style="fill:#000000;fill-opacity:0.94117647"
    +         id="g4966"
    +         transform="matrix(1.705222,0,0,1.705222,-200.90733,-129.69426)">
    +        <g
    +           transform="translate(125.1273,453.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g84">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 0,36 C 0,36 7.46,36 7.46,36 C 7.46,36 10.81,22 10.81,22 C 10.81,22 22.93,22 22.93,22 C 22.93,22 24.49,16 24.49,16 C 24.49,16 12.32,16 12.32,16 C 12.32,16 14.34,7 14.34,7 C 14.34,7 27.29,7 27.29,7 C 27.29,7 28.85,0 28.85,0 C 28.85,0 8.4,0 8.4,0 C 8.4,0 0,36 0,36 z"
    +             id="path86" />
    +        </g>
    +        <g
    +           transform="translate(151.0773,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g88">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 7.51,26 C 7.51,26 9.75,16.6 9.75,16.6 C 10.93,11.51 13.42,7 18.13,7 C 18.55,7 18.96,7.21 19.27,7.26 C 19.27,7.26 21.09,0.05 21.09,0.05 C 20.67,0.05 20.21,0 19.69,0 C 16.22,0 13.31,2.44 11.37,5.94 C 11.37,5.94 11.17,5.94 11.17,5.94 C 11.46,4.23 11.71,2.61 11.9,1 C 11.9,1 5.47,1 5.47,1 C 5.1,3.08 4.53,7.15 3.66,10.82 C 3.66,10.82 0,26 0,26 C 0,26 7.51,26 7.51,26 z"
    +             id="path90" />
    +        </g>
    +        <g
    +           transform="translate(171.7073,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g92">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 C 10.71,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.43,16.81 7.47,16 C 17.6,16.27 23.99,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.73,0 0.73,8.08 0.34,15.86 C 0,22.65 3.52,26 10.78,26 C 13.57,26 17.27,25.68 20.3,24.77 C 20.3,24.77 20.06,19.25 20.06,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 C 9.1,7.91 11.22,6 14.69,6 C 16.4,6 17.38,6.65 17.32,7.53 z"
    +             id="path94" />
    +        </g>
    +        <g
    +           transform="translate(198.2273,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g96">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 C 10.7,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.42,16.81 7.46,16 C 17.6,16.27 23.98,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.72,0 0.72,8.08 0.33,15.86 C 0,22.65 3.52,26 10.77,26 C 13.57,26 17.27,25.68 20.3,24.77 C 20.3,24.77 20.05,19.25 20.05,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 C 9.1,7.91 11.21,6 14.68,6 C 16.39,6 17.38,6.65 17.32,7.53 z"
    +             id="path98" />
    +        </g>
    +        <g
    +           transform="translate(234.1373,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g100">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 22.74,26 C 22.8,22.83 23.56,17.85 24.35,14.58 C 24.35,14.58 27.56,1 27.56,1 C 25.52,0.31 22.34,0 19.28,0 C 6.86,0 0.7,9.2 0.27,17.82 C 0,23.23 2.93,26 7.49,26 C 10.44,26 13.77,24.57 16.36,20.27 C 16.36,20.27 16.47,20.27 16.47,20.27 C 16.27,22.34 16.03,24.35 15.9,26 C 15.9,26 22.74,26 22.74,26 z M 17.61,11.72 C 16.15,18.08 13.17,20 10.95,20 C 8.88,20 7.98,18.53 8.1,16.39 C 8.34,11.56 12.16,6 16.98,6 C 17.76,6 18.37,5.86 18.94,5.72 C 18.94,5.72 17.61,11.72 17.61,11.72 z"
    +             id="path102" />
    +        </g>
    +        <g
    +           transform="translate(261.7673,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g104">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 0,24.82 C 1.44,25.94 4.46,25.95 7.61,26 C 14.34,26.05 19.42,23.11 19.72,17.71 C 19.89,14.11 17.1,11.98 14.37,10.55 C 12.4,9.6 11.41,8.69 11.46,7.63 C 11.53,6.2 12.87,6 14.84,6 C 17.06,6 18.84,6.27 19.86,6.47 C 19.86,6.47 21.88,1.05 21.88,1.05 C 20.73,0.36 18.43,0 15.48,0 C 8.95,0 4.17,3.45 3.9,8.69 C 3.74,11.93 6.07,14.11 8.89,15.59 C 11.17,16.76 11.95,17.66 11.89,18.93 C 11.82,20.21 10.68,20 8.61,20 C 6.18,20 3.49,19.68 2.07,19.46 C 2.07,19.46 0,24.82 0,24.82 z"
    +             id="path106" />
    +        </g>
    +        <g
    +           transform="translate(294.2173,452.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g108">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 7.45,37 C 7.45,37 13.5,12 13.5,12 C 13.5,12 6.09,12 6.09,12 C 6.09,12 0,37 0,37 C 0,37 7.45,37 7.45,37 z M 10.92,9 C 13.46,9 15.72,6.9 15.86,3.3 C 15.98,0.86 14.4,0 12.07,0 C 9.64,0 7.42,1.58 7.29,3.94 C 7.17,6.32 8.75,9 10.92,9 z"
    +             id="path110" />
    +        </g>
    +        <g
    +           transform="translate(308.5073,464.0834)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g112">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 7.46,25.31 C 7.46,25.31 10.1,14.05 10.1,14.05 C 11.47,8.32 14.42,6.31 16.85,6.31 C 18.77,6.31 19.33,7.13 19.24,8.32 C 19.19,9.28 19.04,10.29 18.84,11.19 C 18.84,11.19 15.48,25.31 15.48,25.31 C 15.48,25.31 22.94,25.31 22.94,25.31 C 22.94,25.31 26.48,10.5 26.48,10.5 C 26.75,9.22 27.05,7.31 27.11,6.15 C 27.33,1.64 25.08,0 20.94,0 C 17.62,0 14.39,1.54 11.84,4.88 C 11.84,4.88 11.74,4.88 11.74,4.88 C 11.74,4.88 12.42,0.31 12.42,0.31 C 12.42,0.31 5.84,0.31 5.84,0.31 C 5.41,2.45 4.86,5.04 4.08,8.06 C 4.08,8.06 0,25.31 0,25.31 C 0,25.31 7.46,25.31 7.46,25.31 z"
    +             id="path114" />
    +        </g>
    +        <g
    +           transform="translate(348.0673,453.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g116">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 0,36 C 0,36 7.46,36 7.46,36 C 7.46,36 10.82,22 10.82,22 C 10.82,22 22.93,22 22.93,22 C 22.93,22 24.49,16 24.49,16 C 24.49,16 12.32,16 12.32,16 C 12.32,16 14.34,7 14.34,7 C 14.34,7 27.29,7 27.29,7 C 27.29,7 28.85,0 28.85,0 C 28.85,0 8.4,0 8.4,0 C 8.4,0 0,36 0,36 z"
    +             id="path118" />
    +        </g>
    +        <g
    +           transform="translate(374.0173,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g120">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 7.51,26 C 7.51,26 9.75,16.6 9.75,16.6 C 10.93,11.51 13.42,7 18.13,7 C 18.55,7 18.96,7.21 19.27,7.26 C 19.27,7.26 21.09,0.05 21.09,0.05 C 20.67,0.05 20.21,0 19.69,0 C 16.22,0 13.31,2.44 11.37,5.94 C 11.37,5.94 11.17,5.94 11.17,5.94 C 11.46,4.23 11.71,2.61 11.9,1 C 11.9,1 5.47,1 5.47,1 C 5.11,3.08 4.53,7.15 3.66,10.82 C 3.66,10.82 0,26 0,26 C 0,26 7.51,26 7.51,26 z"
    +             id="path122" />
    +        </g>
    +        <g
    +           transform="translate(394.6473,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g124">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 C 10.71,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.43,16.81 7.47,16 C 17.6,16.27 23.99,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.73,0 0.73,8.08 0.34,15.86 C 0,22.65 3.53,26 10.78,26 C 13.57,26 17.28,25.68 20.3,24.77 C 20.3,24.77 20.06,19.25 20.06,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 C 9.1,7.91 11.22,6 14.69,6 C 16.4,6 17.38,6.65 17.32,7.53 z"
    +             id="path126" />
    +        </g>
    +        <g
    +           transform="translate(421.1673,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g128">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 C 10.7,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.42,16.81 7.46,16 C 17.6,16.27 23.98,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.72,0 0.72,8.08 0.33,15.86 C 0,22.65 3.52,26 10.77,26 C 13.57,26 17.27,25.68 20.3,24.77 C 20.3,24.77 20.05,19.25 20.05,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 C 9.1,7.91 11.21,6 14.68,6 C 16.39,6 17.38,6.65 17.32,7.53 z"
    +             id="path130" />
    +        </g>
    +        <g
    +           transform="translate(447.5473,452.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g132">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 23.31,0 C 23.31,0 20.5,11.36 20.5,11.36 C 19.48,10.94 18.15,11 17.11,11 C 7.53,11 0.75,19.2 0.3,28.08 C 0,34.34 3.34,37 7.64,37 C 10.65,37 13.82,35.67 16.22,32.23 C 16.22,32.23 16.32,32.23 16.32,32.23 C 16.32,32.23 15.75,37 15.75,37 C 15.75,37 22.53,37 22.53,37 C 22.84,34 23.49,30.43 24.22,27.17 C 24.22,27.17 30.71,0 30.71,0 C 30.71,0 23.31,0 23.31,0 z M 17.47,24.42 C 16.3,29.35 13.54,31 11.36,31 C 9.19,31 7.98,29.49 8.13,26.8 C 8.38,21.82 11.8,17 16.25,17 C 17.5,17 18.57,17.19 19.16,17.47 C 19.16,17.47 17.47,24.42 17.47,24.42 z"
    +             id="path134" />
    +        </g>
    +        <g
    +           transform="translate(477.2573,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g136">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 10.61,26 C 19.31,26 26.02,19.41 26.49,10.44 C 26.78,4.5 23.08,0 16.25,0 C 7.23,0 0.76,7.3 0.31,16.12 C 0,22.54 4.14,26 10.61,26 z M 11.78,20 C 9.24,20 7.84,18.38 7.99,15.96 C 8.19,11.93 10.68,6 14.97,6 C 17.93,6 18.84,8.27 18.72,10.5 C 18.5,14.9 15.82,20 11.78,20 z"
    +             id="path138" />
    +        </g>
    +        <g
    +           transform="translate(505.8173,463.3934)"
    +           style="fill:#000000;fill-opacity:0.94117647;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +           id="g140">
    +          <path
    +             style="fill:#000000;fill-opacity:0.94117647"
    +             d="M 7.2,26 C 7.2,26 9.9,14.58 9.9,14.58 C 11.03,9.49 13.85,6 16.38,6 C 18.2,6 18.7,7.33 18.61,9.07 C 18.56,9.97 18.36,10.98 18.15,11.98 C 18.15,11.98 14.81,26 14.81,26 C 14.81,26 22.01,26 22.01,26 C 22.01,26 24.71,14.53 24.71,14.53 C 25.95,9.28 28.61,6 31.09,6 C 32.8,6 33.51,7.22 33.43,8.96 C 33.38,9.97 33.17,11.08 32.91,12.09 C 32.91,12.09 29.67,26 29.67,26 C 29.67,26 36.92,26 36.92,26 C 36.92,26 40.41,11.19 40.41,11.19 C 40.68,9.86 40.99,7.79 41.04,6.73 C 41.26,2.33 39.11,0 35.23,0 C 31.91,0 28.68,1.5 26.23,4.66 C 26.14,2.38 24.51,0 20.47,0 C 17.2,0 14.08,1.48 11.58,4.83 C 11.58,4.83 11.48,4.83 11.48,4.83 C 11.48,4.83 12.15,1 12.15,1 C 12.15,1 5.73,1 5.73,1 C 5.31,3.14 4.8,5.73 4.02,8.75 C 4.02,8.75 0,26 0,26 C 0,26 7.2,26 7.2,26 z"
    +             id="path142" />
    +        </g>
    +      </g>
    +      <path
    +         style="fill:none;fill-opacity:0.94117647;fill-rule:evenodd;stroke:#000000;stroke-width:8.52610779;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
    +         id="path2592"
    +         d="M 402.97747,590.4172 C 403.66968,592.19682 404.36192,593.97353 405.08297,595.7113 C 406.19343,598.07207 407.47693,600.3319 409.02001,602.44175 C 417.35558,613.77261 431.31547,619.9767 449.03932,621.52122 C 449.03932,621.52122 468.10438,621.52122 468.10438,621.52122 C 474.13249,621.05108 480.44905,620.17426 486.99636,618.89363 C 498.28829,616.68573 510.25803,613.29383 522.68924,608.76119 C 532.10639,605.32744 541.78314,601.26495 551.60409,596.54341 C 572.99097,586.29126 595.0845,573.06832 616.75984,557.11106 C 623.89841,551.86024 630.74856,546.47243 637.32471,540.99376 C 643.35284,535.978 649.13581,530.88434 654.65917,525.73449 C 670.07562,510.8776 681.71367,495.78852 688.30424,482.53959 C 695.16876,468.74269 696.53885,456.94601 690.91452,449.51466 C 687.46779,444.9532 681.69925,442.50877 674.27224,441.93336 C 707.72977,416.82865 727.22752,386.37503 720.2332,367.17442 C 718.01224,361.04678 713.12339,356.47522 706.11462,353.94714 C 702.99965,352.82662 699.49519,352.11708 695.67352,351.79404 C 695.67352,351.79404 685.37669,351.79404 685.37669,351.79404 C 670.99861,352.83092 650.09005,357.97936 632.35179,366.67256"
    +         sodipodi:nodetypes="cccccssccccscccsccc" />
    +    </g>
    +    <g
    +       id="g2486"
    +       transform="translate(-10.576504,12.339255)">
    +      <path
    +         d="M 373.55234,223.69791 C 373.55234,223.69791 373.53528,223.69791 373.53528,223.69791 C 371.93238,223.69791 370.51704,224.22653 369.18697,225.30082 C 368.19794,226.08522 367.51585,227.14246 366.97018,228.31906 C 366.97018,228.31906 367.03839,228.31906 367.03839,228.31906 C 367.58406,227.14246 368.26615,226.08522 369.23813,225.30082 C 370.5682,224.22653 371.98353,223.71496 373.55234,223.69791 z"
    +         id="path2577"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter" />
    +      <path
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         d="M 107.04146,18.25331 C 107.04148,18.25331 47.731726,277.02073 47.731726,277.02073 C 47.748776,277.02073 47.750916,277.02073 47.785016,277.02073 C 47.785016,277.02073 322.16583,277.02073 322.16583,277.02073 C 322.16584,277.02073 464.87156,277.02073 464.87156,277.02073 C 447.87049,275.5372 434.44829,269.56891 426.4508,258.68961 C 424.96727,256.67742 423.74162,254.50968 422.66733,252.24173 C 421.98526,250.57063 421.34365,248.88458 420.69566,247.17936 C 418.99042,241.75675 418.31049,235.73945 418.61742,229.32782 C 419.47004,211.45708 427.85547,190.1998 442.38396,167.93984 C 457.81621,144.28328 480.18233,119.48895 507.87512,96.4804 C 514.08211,91.32721 520.50015,86.23841 527.21873,81.29326 C 535.52314,75.18347 543.89154,69.55665 552.26418,64.29433 C 583.11163,44.87356 613.88235,31.28421 641.14885,24.38151 C 615.09308,32.88202 585.8208,47.31289 556.90024,66.95875 C 555.86008,67.6613 554.83266,68.3809 553.80952,69.09027 C 537.76339,80.20832 523.22638,92.01613 510.53954,103.94073 C 469.71651,142.3253 448.13908,182.09957 457.9441,205.40142 C 458.64326,207.00432 459.47666,208.53477 460.44865,209.98421 C 470.9869,225.48468 497.10452,228.164 530.20287,219.84252 C 532.45376,219.27977 534.70465,218.64248 537.02375,217.97744 C 547.59613,214.92507 558.82075,210.80271 570.38215,205.72116 C 573.16164,204.49339 575.97102,203.23153 578.80168,201.8844 C 579.09156,201.74799 579.36441,201.61157 579.65429,201.4581 C 616.14602,183.32648 644.19054,162.46352 650.26113,149.92843 C 651.59121,147.20181 651.91093,144.87713 651.00716,143.05426 C 646.67592,134.27238 616.36771,140.20526 579.65429,156.10986 C 576.70426,157.38876 573.72012,158.70478 570.70188,160.10647 C 573.1574,157.82661 575.71311,155.53819 578.32208,153.28558 C 582.48283,149.7012 586.79064,146.19613 591.37768,142.73454 C 598.55668,137.29827 605.81453,132.38383 612.95941,128.027 C 646.41584,102.78633 663.32951,78.90978 659.79971,70.04947 C 659.13466,68.38004 657.71934,67.23158 655.53665,66.53244 C 648.56227,64.31397 635.83282,66.96173 620.36646,73.30004 C 607.61142,78.53168 592.96142,86.29084 578.10894,95.94752 C 578.10894,95.94752 576.08399,97.27972 576.08399,97.27972 C 576.08401,97.27972 575.71097,97.49286 575.71097,97.49286 C 575.71099,97.49288 568.57036,102.23551 568.57036,102.23551 C 568.57034,102.2355 572.67355,94.72188 572.67355,94.72188 C 578.7612,83.57824 588.67705,71.95121 601.02285,61.15034 C 610.07758,53.25345 620.42188,45.81272 631.55698,39.30218 C 635.76889,36.83645 639.97438,34.54632 644.18627,32.4813 C 648.50049,30.37361 652.81682,28.50041 657.02873,26.83271 C 669.26555,21.99341 680.94654,19.05291 691.13315,18.25331 C 690.20548,18.25331 662.51741,18.25331 662.51741,18.25331 C 662.51742,18.25331 566.06582,18.25331 566.06582,18.25331 C 566.06583,18.25331 140.77287,18.25331 140.77287,18.25331 C 140.77287,18.25331 107.04146,18.25331 107.04146,18.25331 z M 413.02217,18.62641 C 411.35108,44.13137 416.2962,81.48852 427.51656,122.96461 C 429.51165,130.34482 431.68368,137.85546 434.071,145.45223 C 435.55456,150.14327 437.08499,154.76104 438.65378,159.30715 C 437.73298,160.66111 436.80574,162.00652 435.93608,163.35705 C 421.93623,184.81213 413.75328,205.08809 411.68997,222.72008 C 405.77283,202.9054 401.31796,181.20178 398.79423,158.1881 C 398.07804,151.594 397.51744,145.07368 397.14229,138.63135 C 394.37982,91.83496 400.48878,49.41415 413.02217,18.62641 z M 133.63227,51.82491 C 133.95161,51.81737 134.26641,51.82491 134.59145,51.82491 C 134.59145,51.82489 197.63136,51.82491 197.63136,51.82491 C 203.01987,51.82489 207.187,52.83482 210.15408,54.86233 C 213.1041,56.90179 214.21039,59.53976 213.51123,62.74898 C 213.51125,62.749 205.9976,96.69354 205.9976,96.69354 C 205.9976,96.69357 183.77644,96.69354 183.77644,96.69354 C 183.77646,96.69357 191.07692,63.65488 191.07692,63.65488 C 191.0769,63.65488 135.44407,63.65488 135.44407,63.65488 C 135.44405,63.65488 115.35442,154.45793 115.35442,154.45793 C 115.35444,154.45793 108.10723,187.33674 108.10723,187.33674 C 108.10723,187.33677 163.6868,187.33674 163.6868,187.33674 C 163.6868,187.33677 163.74009,187.12358 163.74009,187.12358 C 163.74009,187.1236 174.87731,136.81954 174.87731,136.81954 C 174.87731,136.81952 148.76611,136.81954 148.76611,136.81954 C 148.76611,136.81952 151.27065,125.46916 151.27065,125.46916 C 151.27064,125.46914 199.60303,125.46916 199.60303,125.46916 C 199.60303,125.46914 185.7481,188.24264 185.7481,188.24264 C 185.56053,189.13616 185.23228,189.94572 184.78891,190.74717 C 183.64642,192.82754 181.65344,194.60951 178.87393,196.076 C 175.02015,198.10523 170.4075,199.11342 165.019,199.11342 C 165.019,199.11344 102.03238,199.11342 102.03238,199.11342 C 96.643856,199.11344 92.476736,198.10521 89.509656,196.076 C 86.559646,194.0468 85.436306,191.45527 86.152506,188.24264 C 86.152516,188.24262 113.91564,62.74898 113.91564,62.74898 C 114.63182,59.53977 116.86569,56.90177 120.73653,54.86233 C 120.87295,54.78902 121.02642,54.77238 121.16283,54.70247 C 124.69585,52.93277 128.8422,51.93804 133.63227,51.82491 z M 232.42855,51.82491 C 232.42853,51.82489 311.77463,51.82491 311.77463,51.82491 C 317.09494,51.82489 321.27698,52.83482 324.24406,54.86233 C 327.22823,56.90179 328.37072,59.53976 327.65451,62.74898 C 327.65453,62.749 312.8404,129.67893 312.8404,129.67893 C 312.14128,132.86767 309.85413,135.46943 305.96623,137.51229 C 302.07833,139.56195 297.50193,140.603 292.16459,140.603 C 292.16457,140.603 234.50679,140.603 234.50679,140.603 C 234.50679,140.603 223.36956,190.85375 223.36956,190.85375 C 223.36956,190.85377 221.55776,199.11342 221.55776,199.11342 C 221.55777,199.11344 199.81618,199.11342 199.81618,199.11342 C 199.81618,199.11344 201.46811,191.65308 201.46811,191.65308 C 201.46811,191.6531 232.42855,51.82491 232.42855,51.82491 z M 342.04232,51.82491 C 342.04231,51.82489 363.7839,51.82491 363.7839,51.82491 C 363.78392,51.82489 339.16476,163.03732 339.16476,163.03732 C 339.16478,163.03734 333.78266,187.33674 333.78266,187.33674 C 333.78266,187.33677 385.79192,187.33674 385.79192,187.33674 C 386.3376,191.32528 386.97491,195.24256 387.657,199.11342 C 387.65698,199.11344 309.42995,199.11342 309.42995,199.11342 C 309.42997,199.11344 315.61138,171.19041 315.61138,171.19041 C 315.6114,171.19041 342.04232,51.82491 342.04232,51.82491 z M 251.559,63.65488 C 251.55902,63.65488 237.1179,128.77302 237.1179,128.77302 C 237.1179,128.773 291.31198,128.77302 291.31198,128.77302 C 291.31197,128.773 305.69978,63.65488 305.69978,63.65488 C 305.6998,63.65488 251.559,63.65488 251.559,63.65488 z M 205.9976,209.34475 C 206.21027,209.3376 206.42284,209.34475 206.63707,209.34475 C 209.1608,209.34477 211.36479,209.78811 213.13822,210.62366 C 215.03102,211.51037 216.38454,212.82766 217.13484,214.56699 C 217.86809,216.25518 218.05992,218.1714 217.66771,220.26883 C 217.66771,220.26884 217.50786,221.06816 217.50786,221.06816 C 217.50787,221.06813 211.27314,221.06816 211.27314,221.06816 C 211.27312,221.06813 211.32643,220.32211 211.32643,220.32211 C 211.48761,218.85668 211.30594,217.70432 210.74025,216.91168 C 210.66653,216.81227 210.55972,216.68105 210.47381,216.59195 C 210.33313,216.44832 210.12183,216.28415 209.94094,216.16564 C 209.06856,215.61614 207.70391,215.31302 205.94432,215.31302 C 203.60817,215.31304 201.86245,215.72014 200.6688,216.53866 C 199.50924,217.34012 198.776,218.23536 198.53727,219.30964 C 198.29852,220.40098 198.69073,220.97436 198.96358,221.2813 C 198.97208,221.28979 199.00651,221.32507 199.01685,221.33459 C 199.36237,221.62904 200.56221,222.31935 204.29238,223.19967 C 207.6687,224.01818 209.9047,224.75356 211.16656,225.38449 C 213.07643,226.35645 214.41075,227.61619 215.1099,229.16795 C 215.80901,230.70267 215.9625,232.49952 215.5362,234.44348 C 215.1099,236.33627 214.14431,238.082 212.71192,239.71902 C 211.2966,241.35602 209.49545,242.65199 207.32981,243.55575 C 205.18121,244.44247 202.82377,244.94124 200.40235,244.94124 C 197.33295,244.94123 194.86892,244.47657 192.94201,243.55575 C 190.92984,242.60084 189.47827,241.09385 188.62567,239.13284 C 187.80716,237.22298 187.63237,235.05522 188.09278,232.68498 C 188.09278,232.68495 188.25265,231.93893 188.25265,231.93893 C 188.25265,231.93893 194.38079,231.93893 194.38079,231.93893 C 194.38079,231.93893 194.3275,232.68498 194.3275,232.68498 C 194.17402,234.1003 194.32537,235.2428 194.70052,236.09541 C 195.05861,236.91394 195.74071,237.59174 196.83204,238.12037 C 197.99158,238.68307 199.44102,238.97297 201.09509,238.97297 C 202.57864,238.97296 203.9343,238.72358 205.145,238.28024 C 206.33865,237.85394 207.28718,237.2912 207.96927,236.57501 C 208.63429,235.85879 209.02438,235.10213 209.1949,234.28361 C 209.36542,233.55037 209.32492,232.93011 209.03503,232.41853 C 208.71104,231.87289 208.06945,231.389 207.06338,230.97975 C 207.06338,230.97974 201.84112,229.43439 201.84112,229.43439 C 198.9252,228.70116 196.96207,228.00201 195.81957,227.30287 C 194.2678,226.38206 193.14876,225.20118 192.56898,223.78585 C 191.98921,222.38754 191.9274,220.83794 192.30255,219.14977 C 192.69475,217.34224 193.56654,215.6221 194.91366,214.0874 C 196.27786,212.53563 198.03848,211.31855 200.13591,210.51709 C 201.99034,209.82169 203.94187,209.41388 205.9976,209.34475 z M 261.9502,209.45133 C 262.28745,209.42506 262.60456,209.45133 262.96267,209.45133 C 262.96268,209.45133 266.79942,209.87763 266.79942,209.87763 C 266.79941,209.87763 268.07833,209.98421 268.07833,209.98421 C 268.07835,209.98422 266.21325,214.72685 266.21325,214.72685 C 266.21324,214.72687 265.84023,215.47289 265.84023,215.47289 C 265.84023,215.47287 262.90939,215.20645 262.90939,215.20645 C 262.04398,215.20645 261.40826,215.33997 260.99101,215.63275 C 260.9633,215.65368 260.91001,215.71695 260.88443,215.73933 C 260.82853,215.78837 260.73452,215.87391 260.67128,215.95249 C 260.41469,216.289 260.10216,216.89035 259.87196,217.97744 C 259.87194,217.97744 259.76112,218.43784 259.65881,218.83005 C 261.00594,218.83006 264.24158,218.83005 264.24158,218.83005 C 264.24158,218.83006 263.06925,224.10557 263.06925,224.10557 C 263.06925,224.10556 259.71849,224.10557 258.59305,224.10557 C 258.25199,225.64026 254.06355,244.40837 254.06355,244.40837 C 254.06353,244.40835 247.88212,244.40837 247.88212,244.40837 C 247.8821,244.40835 251.90005,226.37352 252.41162,224.10557 C 251.37141,224.10556 248.84131,224.10557 248.84131,224.10557 C 248.84131,224.10556 250.01365,218.83005 250.01365,218.83005 C 250.01366,218.83006 252.55869,218.83005 253.53066,218.83005 C 253.70118,218.09681 253.95696,217.17811 253.95696,217.17811 C 254.33212,215.47289 254.72431,214.24726 255.23587,213.39465 C 255.93504,212.21806 256.92193,211.23328 258.16674,210.51709 C 259.19201,209.92134 260.48872,209.56515 261.9502,209.45133 z M 276.71102,209.71777 C 276.711,209.71776 275.09532,216.98841 274.68607,218.83005 C 275.87971,218.83006 278.68268,218.83005 278.68268,218.83005 C 278.68268,218.83006 277.51035,224.10557 277.51035,224.10557 C 277.51033,224.10556 274.57096,224.10557 273.51373,224.10557 C 273.18972,225.57204 270.63617,236.94803 270.63617,236.94803 C 270.63619,236.94801 270.42301,238.31434 270.42301,238.70654 C 270.42329,238.71959 270.42195,238.75022 270.42301,238.75982 C 270.42385,238.76385 270.42181,238.80979 270.42301,238.81311 C 270.42465,238.8158 270.47416,238.81097 270.47629,238.81311 C 270.47629,238.81309 271.11576,238.8664 271.11576,238.8664 C 271.11576,238.8664 274.04661,238.65325 274.04661,238.65325 C 274.04661,238.65325 273.72688,243.39589 273.72688,243.39589 C 273.7269,243.39589 273.78018,244.2485 273.78018,244.2485 C 273.78016,244.24848 269.5704,244.7281 269.5704,244.7281 C 267.8993,244.72808 266.67365,244.45527 265.78694,243.8755 C 264.84909,243.26158 264.3034,242.44736 264.08172,241.42424 C 264.04761,241.23665 263.97514,240.96382 263.97514,240.57163 C 263.97514,239.80427 264.12009,238.50618 264.6146,236.25529 C 264.61462,236.25531 266.85483,226.22005 267.3323,224.10557 C 266.53087,224.10556 264.40145,224.10557 264.40145,224.10557 C 264.40147,224.10556 265.57378,218.83005 265.57378,218.83005 C 265.57376,218.83006 267.65202,218.83005 268.50464,218.83005 C 268.77745,217.6023 269.73026,213.39465 269.73026,213.39465 C 269.73026,213.39467 274.68607,210.78353 274.68607,210.78353 C 274.68606,210.78355 276.71102,209.71777 276.71102,209.71777 z M 80.344086,209.93092 C 80.344106,209.93092 104.32377,209.93092 104.32377,209.93092 C 104.32377,209.93092 102.99157,215.8992 102.99157,215.8992 C 102.99157,215.89922 86.994456,215.8992 85.459756,215.8992 C 85.186936,217.10993 84.093446,222.01242 83.701246,223.78585 C 85.918046,223.78585 98.888376,223.78585 98.888376,223.78585 C 98.888376,223.78585 97.556166,229.75411 97.556166,229.75411 C 97.556156,229.75411 83.903746,229.75411 82.369036,229.75411 C 82.045046,231.23766 79.118456,244.40837 79.118456,244.40837 C 79.118476,244.40835 72.670596,244.40837 72.670596,244.40837 C 72.670606,244.40835 80.344086,209.93092 80.344086,209.93092 z M 112.47685,218.35046 C 112.71752,218.3209 112.98043,218.35046 113.22289,218.35046 C 114.75759,218.35046 116.17506,218.81726 117.53924,219.78923 C 117.53924,219.78925 118.39184,220.3754 118.39184,220.3754 C 118.39184,220.3754 115.08798,225.8108 115.08798,225.8108 C 115.08798,225.81078 114.18209,225.17134 114.18209,225.17134 C 113.51705,224.74505 112.80086,224.53188 112.05056,224.53188 C 111.40257,224.5319 110.79935,224.76208 110.18547,225.17134 C 109.5375,225.59764 108.99607,226.16249 108.58683,226.92985 C 107.87063,228.24289 107.34627,229.71362 106.98818,231.29948 C 106.98818,231.29949 104.11062,244.40837 104.11062,244.40837 C 104.11062,244.40835 97.929186,244.40837 97.929186,244.40837 C 97.929186,244.40835 103.63103,218.83005 103.63103,218.83005 C 103.63105,218.83006 109.38615,218.83005 109.38615,218.83005 C 109.38615,218.83006 109.18791,219.60593 109.1197,219.89581 C 109.39254,219.6912 109.68029,219.40982 109.91903,219.25635 C 110.745,218.76345 111.6174,218.456 112.47685,218.35046 z M 130.80799,218.35046 C 131.18018,218.32231 131.54658,218.35046 131.92705,218.35046 C 135.40571,218.35046 138.03813,219.56968 139.7604,221.97405 C 140.83468,223.52579 141.41235,225.44417 141.41235,227.72917 C 141.41235,228.99102 141.25674,230.34882 140.93276,231.83236 C 140.93276,231.83236 140.45315,233.69745 140.45315,233.69745 C 140.45315,233.69743 124.82054,233.69745 123.08121,233.69745 C 123.0471,234.05553 123.02792,234.43922 123.02792,234.76321 C 123.02792,236.0933 123.30075,237.13986 123.88053,237.90722 C 124.15603,238.28235 124.47543,238.62021 124.83972,238.8664 C 125.5265,239.31429 126.41306,239.55915 127.45084,239.55915 C 128.71272,239.55913 129.82109,239.2117 130.86128,238.54667 C 131.85033,237.91574 132.79672,236.90753 133.63227,235.50925 C 133.63227,235.50922 140.24,235.50925 140.24,235.50925 C 140.24,235.50922 139.65384,236.78816 139.65384,236.78816 C 138.39197,239.34601 136.63133,241.3411 134.43159,242.75644 C 132.23186,244.17177 129.60368,244.94124 126.7048,244.94124 C 122.93626,244.94123 120.13117,243.72202 118.39184,241.31766 C 116.66958,238.96443 116.29869,235.71173 117.21951,231.6192 C 118.14034,227.45847 119.97771,224.13329 122.6549,221.81418 C 125.05448,219.73356 127.77735,218.5795 130.80799,218.35046 z M 158.57114,218.35046 C 158.94332,218.32231 159.30971,218.35046 159.69018,218.35046 C 163.16885,218.35046 165.80128,219.56968 167.52355,221.97405 C 168.59784,223.52579 169.17548,225.44417 169.17548,227.72917 C 169.17548,228.97397 169.01988,230.31258 168.69588,231.77907 C 168.69588,231.77909 168.2163,233.69745 168.2163,233.69745 C 168.2163,233.69743 152.58367,233.69745 150.84435,233.69745 C 150.82728,233.93615 150.80811,234.15147 150.79106,234.3902 C 150.77827,234.47972 150.79666,234.61561 150.79106,234.70992 C 150.79056,234.7253 150.79106,234.74829 150.79106,234.76321 C 150.79106,235.01901 150.8273,235.27051 150.84435,235.50925 C 150.92958,236.48121 151.18327,237.29334 151.64367,237.90722 C 151.73134,238.02658 151.81375,238.17392 151.91011,238.28024 C 152.69112,239.11578 153.79651,239.55915 155.21398,239.55915 C 156.47586,239.55913 157.60129,239.2117 158.62443,238.54667 C 159.61347,237.91574 160.55985,236.90753 161.39541,235.50925 C 161.39541,235.50922 168.05643,235.50925 168.05643,235.50925 C 168.05642,235.50922 167.41697,236.78816 167.41697,236.78816 C 166.15511,239.34601 164.39447,241.3411 162.19473,242.75644 C 159.99499,244.17177 157.36682,244.94124 154.46795,244.94124 C 150.69942,244.94123 147.89432,243.72202 146.15499,241.31766 C 145.02954,239.78294 144.50305,237.82835 144.50305,235.50925 C 144.50305,235.15113 144.52223,234.76534 144.55634,234.3902 C 144.62457,233.50349 144.76097,232.60824 144.98265,231.6192 C 145.90349,227.47552 147.68756,224.13329 150.36475,221.81418 C 152.76432,219.73356 155.5405,218.5795 158.57114,218.35046 z M 234.18705,218.35046 C 234.56789,218.32117 234.91817,218.35046 235.3061,218.35046 C 238.85297,218.35046 241.5792,219.5505 243.35262,221.92076 C 245.10902,224.29099 245.53531,227.4883 244.63153,231.51262 C 243.9324,234.65025 242.92206,237.18462 241.54083,239.02627 C 240.15957,240.86792 238.39895,242.37276 236.31857,243.39589 C 234.25529,244.41903 232.07044,244.94124 229.87071,244.94124 C 226.25564,244.94123 223.56352,243.70496 221.82419,241.31766 C 220.69873,239.80002 220.11897,237.8454 220.11897,235.50925 C 220.11899,234.24738 220.25753,232.90665 220.59857,231.40606 C 221.62172,226.83605 223.71059,223.35528 226.78,221.12144 C 229.03301,219.4951 231.52114,218.55538 234.18705,218.35046 z M 327.81438,218.35046 C 328.26398,218.32271 328.68031,218.35046 329.14658,218.35046 C 331.29517,218.35046 332.98333,218.56786 334.26225,219.09648 C 335.62643,219.64217 336.59414,220.41377 337.13981,221.33459 C 337.66845,222.20422 337.93914,223.27215 337.93914,224.58516 C 337.93915,224.58518 337.29966,228.4752 337.29966,228.4752 C 337.29969,228.4752 336.12734,233.75074 336.12734,233.75074 C 335.12123,238.2525 334.89958,239.94069 334.84841,240.57163 C 334.79726,241.42425 334.87612,242.25553 335.11486,243.02288 C 335.11488,243.02286 335.54116,244.40837 335.54116,244.40837 C 335.54118,244.40835 329.25316,244.40837 329.25316,244.40837 C 329.25314,244.40835 328.98671,243.60904 328.98671,243.60904 C 328.8844,243.23392 328.91424,242.75644 328.88014,242.33013 C 327.68649,243.06338 326.4907,243.71349 325.41641,244.08864 C 323.83057,244.63433 322.18502,244.94124 320.5139,244.94124 C 317.61504,244.94123 315.46858,244.1867 314.1726,242.70314 C 313.18358,241.61181 312.73383,240.27747 312.73383,238.75982 C 312.73381,238.18005 312.81056,237.57895 312.94697,236.94803 C 313.23685,235.65206 313.76335,234.452 314.59891,233.37771 C 315.41742,232.32045 316.38514,231.45082 317.47647,230.81989 C 318.53373,230.18897 319.71245,229.74134 320.94021,229.43439 C 320.94019,229.43439 324.72367,228.79493 324.72367,228.79493 C 327.63961,228.45387 329.81588,228.02972 331.38469,227.56931 C 331.41881,227.39879 331.49126,227.19629 331.49126,227.19629 C 331.73852,226.09911 331.70758,225.27441 331.43797,224.85161 C 331.41813,224.82434 331.35379,224.76847 331.3314,224.74503 C 331.27384,224.68368 331.18537,224.58724 331.11824,224.53188 C 330.47689,224.02435 329.38318,223.78585 327.92096,223.78585 C 326.26689,223.78585 325.0434,224.05656 324.19078,224.58516 C 323.35523,225.11379 322.58147,226.0815 321.89939,227.46272 C 321.89938,227.46271 315.45152,227.46272 315.45152,227.46272 C 315.45154,227.46271 316.03769,226.18381 316.03769,226.18381 C 316.80502,224.41036 317.71947,222.93963 318.86197,221.81418 C 320.00447,220.68871 321.54769,219.81694 323.33817,219.20307 C 324.71033,218.7501 326.20867,218.44953 327.81438,218.35046 z M 354.83149,218.35046 C 355.07195,218.3209 355.33505,218.35046 355.57752,218.35046 C 357.12925,218.35046 358.58297,218.81726 359.94715,219.78923 C 359.94717,219.78925 360.74647,220.3754 360.74647,220.3754 C 360.74648,220.3754 357.44261,225.8108 357.44261,225.8108 C 357.44262,225.81078 356.53671,225.17134 356.53671,225.17134 C 355.87168,224.74505 355.1917,224.53188 354.45847,224.53188 C 353.81046,224.5319 353.17103,224.76208 352.54008,225.17134 C 351.89211,225.59764 351.42104,226.16249 350.99474,226.92985 C 350.29558,228.24289 349.75418,229.71362 349.39609,231.29948 C 349.39607,231.29949 346.46524,244.40837 346.46524,244.40837 C 346.46526,244.40835 340.28382,244.40837 340.28382,244.40837 C 340.28382,244.40835 345.98564,218.83005 345.98564,218.83005 C 345.98563,218.83006 351.74076,218.83005 351.74076,218.83005 C 351.74076,218.83006 351.59582,219.60593 351.52762,219.89581 C 351.80044,219.6912 352.07115,219.40982 352.32694,219.25635 C 353.13957,218.76345 353.97265,218.456 354.83149,218.35046 z M 373.10932,218.35046 C 373.48117,218.32231 373.84791,218.35046 374.22838,218.35046 C 377.70704,218.35046 380.35651,219.56968 382.06175,221.97405 C 383.1531,223.52579 383.71368,225.44417 383.71368,227.72917 C 383.71366,228.99102 383.50478,230.34882 383.18079,231.83236 C 383.18079,231.83236 382.75449,233.69745 382.75449,233.69745 C 382.75448,233.69743 367.10481,233.69745 365.38255,233.69745 C 365.34844,234.05553 365.27596,234.43922 365.27596,234.76321 C 365.27596,236.0933 365.56585,237.13986 366.12858,237.90722 C 366.21624,238.02658 366.35158,238.17392 366.4483,238.28024 C 366.50432,238.33991 366.60242,238.43797 366.66146,238.49338 C 367.42381,239.1864 368.46127,239.55915 369.75216,239.55915 C 371.01405,239.55913 372.12243,239.2117 373.16261,238.54667 C 374.15166,237.91574 375.081,236.90753 375.9336,235.50925 C 375.93358,235.50922 382.59462,235.50925 382.59462,235.50925 C 382.59462,235.50922 381.95516,236.78816 381.95516,236.78816 C 380.69329,239.34601 378.91561,241.3411 376.73292,242.75644 C 374.51615,244.17177 371.92207,244.94124 369.00613,244.94124 C 365.23762,244.94123 362.48579,243.72202 360.74647,241.31766 C 359.02417,238.96443 358.61707,235.71173 359.52084,231.6192 C 360.44165,227.45847 362.22575,224.13329 364.90295,221.81418 C 367.3177,219.73356 370.08147,218.5795 373.10932,218.35046 z M 279.80172,218.83005 C 279.80174,218.83006 286.14303,218.83005 286.14303,218.83005 C 286.14305,218.83006 286.92529,234.00866 286.94234,234.23032 C 287.19812,233.68676 287.39658,233.22945 287.42195,233.16457 C 287.42196,233.16458 294.40269,218.83005 294.40269,218.83005 C 294.40271,218.83006 300.2111,218.83005 300.2111,218.83005 C 300.21109,218.83006 300.74398,233.82533 300.74398,233.91059 C 300.91453,233.60368 308.68392,218.83005 308.68392,218.83005 C 308.6839,218.83006 314.97193,218.83005 314.97193,218.83005 C 314.97192,218.83006 301.117,244.40837 301.117,244.40837 C 301.11702,244.40835 295.41517,244.40837 295.41517,244.40837 C 295.41517,244.40835 294.86311,230.53853 294.829,229.75411 C 292.47577,234.57991 287.68837,244.40837 287.68837,244.40837 C 287.68837,244.40835 281.82669,244.40837 281.82669,244.40837 C 281.82669,244.40835 279.80172,218.83005 279.80172,218.83005 z M 130.91457,223.67927 C 129.44564,223.74129 128.11162,224.27076 126.86468,225.27791 C 125.87566,226.06232 125.20847,227.13875 124.67985,228.31534 C 124.67985,228.31536 135.17762,228.31534 135.17762,228.31534 C 135.19469,228.12778 135.23091,227.8997 135.23091,227.72917 C 135.23089,226.75722 135.05825,226.00264 134.75132,225.49107 C 134.00104,224.2633 132.88837,223.67927 131.2343,223.67927 C 131.1352,223.67927 131.0125,223.67515 130.91457,223.67927 z M 158.6777,223.67927 C 157.20878,223.74129 155.87475,224.27076 154.6278,225.27791 C 153.63876,226.06232 152.98867,227.13875 152.443,228.31534 C 152.443,228.31536 162.94076,228.31534 162.94076,228.31534 C 162.9578,228.12778 162.99405,227.8997 162.99405,227.72917 C 162.99404,226.75722 162.83845,226.00264 162.51445,225.49107 C 162.36551,225.24168 162.16402,224.99368 161.98157,224.79833 C 161.26958,224.06261 160.28967,223.67927 158.99744,223.67927 C 158.89833,223.67927 158.77564,223.67515 158.6777,223.67927 z M 373.42906,223.67927 C 371.9185,223.7258 370.50781,224.23721 369.21929,225.27791 C 368.24731,226.06232 367.58014,227.13875 367.03447,228.31534 C 367.03449,228.31536 377.47896,228.31534 377.47896,228.31534 C 377.49599,228.12778 377.53225,227.8997 377.53225,227.72917 C 377.53224,226.75722 377.37665,226.00264 377.05265,225.49107 C 376.31941,224.28035 375.18969,223.69633 373.53563,223.67927 C 373.48661,223.6798 373.47779,223.67777 373.42906,223.67927 z M 233.81404,223.78585 C 232.40441,223.95324 231.09368,224.59636 229.87071,225.70422 C 228.40423,227.03431 227.34059,229.12319 226.72672,231.88565 C 226.47093,233.0452 226.35369,234.03636 226.35369,234.92307 C 226.35371,236.13377 226.58602,237.08444 227.04644,237.80063 C 227.16901,237.98447 227.3316,238.17874 227.47275,238.33352 C 228.23079,239.1384 229.28934,239.55915 230.61675,239.55915 C 232.33901,239.55913 233.85667,238.91756 235.3061,237.58748 C 236.77262,236.24034 237.81917,234.13014 238.4501,231.29948 C 239.0299,228.70753 238.94888,226.77212 238.13038,225.54436 C 237.34598,224.3507 236.19922,223.78585 234.61337,223.78585 C 234.34426,223.78585 234.07507,223.75484 233.81404,223.78585 z M 330.10577,233.11128 C 328.65636,233.50346 327.0321,233.83386 324.88353,234.12376 C 323.28064,234.3625 322.13812,234.614 321.47308,234.86979 C 320.89332,235.10851 320.4265,235.4389 320.0343,235.88227 C 319.65914,236.30854 319.40764,236.75619 319.28828,237.26776 C 319.25419,237.4724 319.23498,237.6834 319.23498,237.85393 C 319.23498,237.86777 319.23467,237.89351 319.23498,237.90722 C 319.23677,237.9478 319.23053,238.02792 319.23498,238.06707 C 319.24566,238.14444 319.26715,238.26147 319.28828,238.33352 C 319.2959,238.35725 319.33279,238.41691 319.34155,238.44009 C 319.36021,238.48593 319.3717,238.5562 319.39484,238.59996 C 319.41911,238.64322 319.47274,238.71845 319.50142,238.75982 C 319.54606,238.82119 319.60692,238.91542 319.66129,238.97297 C 320.0876,239.45043 320.93807,239.66572 322.16583,239.66572 C 323.51298,239.66573 324.80893,239.40994 326.00258,238.81311 C 327.1792,238.23334 328.12771,237.36793 328.82685,236.36185 C 329.33844,235.64565 329.74768,234.54365 330.10577,233.11128 z"
    +         id="path2579" />
    +      <path
    +         d="M 373.60344,223.69791 C 373.58638,223.69791 373.56933,223.69791 373.55228,223.69791 C 375.20635,223.71496 376.29769,224.27769 377.03093,225.48839 C 377.35493,225.99996 377.52545,226.76731 377.52545,227.73929 C 377.52545,227.90981 377.49134,228.13149 377.47429,228.31906 C 377.47429,228.31906 377.5425,228.31906 377.5425,228.31906 C 377.5425,228.13149 377.5766,227.90981 377.5766,227.73929 C 377.5766,226.76731 377.42313,225.99996 377.09914,225.48839 C 376.3659,224.26063 375.2575,223.69791 373.60344,223.69791 z"
    +         id="path2583"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter" />
    +      <g
    +         id="g2587"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,26.564476,303.23111)">
    +        <path
    +           id="path2589"
    +           d="M 0,36 C 0,36 7.46,36 7.46,36 C 7.46,36 10.81,22 10.81,22 C 10.81,22 22.93,22 22.93,22 C 22.93,22 24.49,16 24.49,16 C 24.49,16 12.32,16 12.32,16 C 12.32,16 14.34,7 14.34,7 C 14.34,7 27.29,7 27.29,7 C 27.29,7 28.85,0 28.85,0 C 28.85,0 8.4,0 8.4,0 C 8.4,0 0,36 0,36 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2591"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,70.814976,320.28331)">
    +        <path
    +           id="path2593"
    +           d="M 7.51,26 C 7.51,26 9.75,16.6 9.75,16.6 C 10.93,11.51 13.42,7 18.13,7 C 18.55,7 18.96,7.21 19.27,7.26 C 19.27,7.26 21.09,0.05 21.09,0.05 C 20.67,0.05 20.21,0 19.69,0 C 16.22,0 13.31,2.44 11.37,5.94 C 11.37,5.94 11.17,5.94 11.17,5.94 C 11.46,4.23 11.71,2.61 11.9,1 C 11.9,1 5.47,1 5.47,1 C 5.1,3.08 4.53,7.15 3.66,10.82 C 3.66,10.82 0,26 0,26 C 0,26 7.51,26 7.51,26 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2595"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,105.99378,320.28331)">
    +        <path
    +           id="path2597"
    +           d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 C 10.71,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.43,16.81 7.47,16 C 17.6,16.27 23.99,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.73,0 0.73,8.08 0.34,15.86 C 0,22.65 3.52,26 10.78,26 C 13.57,26 17.27,25.68 20.3,24.77 C 20.3,24.77 20.06,19.25 20.06,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 C 9.1,7.91 11.22,6 14.69,6 C 16.4,6 17.38,6.65 17.32,7.53 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2599"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,151.21628,320.28331)">
    +        <path
    +           id="path2601"
    +           d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 C 10.7,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.42,16.81 7.46,16 C 17.6,16.27 23.98,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.72,0 0.72,8.08 0.33,15.86 C 0,22.65 3.52,26 10.77,26 C 13.57,26 17.27,25.68 20.3,24.77 C 20.3,24.77 20.05,19.25 20.05,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 C 9.1,7.91 11.21,6 14.68,6 C 16.39,6 17.38,6.65 17.32,7.53 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2603"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,212.45078,320.28331)">
    +        <path
    +           id="path2605"
    +           d="M 22.74,26 C 22.8,22.83 23.56,17.85 24.35,14.58 C 24.35,14.58 27.56,1 27.56,1 C 25.52,0.31 22.34,0 19.28,0 C 6.86,0 0.7,9.2 0.27,17.82 C 0,23.23 2.93,26 7.49,26 C 10.44,26 13.77,24.57 16.36,20.27 C 16.36,20.27 16.47,20.27 16.47,20.27 C 16.27,22.34 16.03,24.35 15.9,26 C 15.9,26 22.74,26 22.74,26 z M 17.61,11.72 C 16.15,18.08 13.17,20 10.95,20 C 8.88,20 7.98,18.53 8.1,16.39 C 8.34,11.56 12.16,6 16.98,6 C 17.76,6 18.37,5.86 18.94,5.72 C 18.94,5.72 17.61,11.72 17.61,11.72 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2607"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,259.56608,320.28331)">
    +        <path
    +           id="path2609"
    +           d="M 0,24.82 C 1.44,25.94 4.46,25.95 7.61,26 C 14.34,26.05 19.42,23.11 19.72,17.71 C 19.89,14.11 17.1,11.98 14.37,10.55 C 12.4,9.6 11.41,8.69 11.46,7.63 C 11.53,6.2 12.87,6 14.84,6 C 17.06,6 18.84,6.27 19.86,6.47 C 19.86,6.47 21.88,1.05 21.88,1.05 C 20.73,0.36 18.43,0 15.48,0 C 8.95,0 4.17,3.45 3.9,8.69 C 3.74,11.93 6.07,14.11 8.89,15.59 C 11.17,16.76 11.95,17.66 11.89,18.93 C 11.82,20.21 10.68,20 8.61,20 C 6.18,20 3.49,19.68 2.07,19.46 C 2.07,19.46 0,24.82 0,24.82 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2611"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,314.90048,301.52591)">
    +        <path
    +           id="path2613"
    +           d="M 7.45,37 C 7.45,37 13.5,12 13.5,12 C 13.5,12 6.09,12 6.09,12 C 6.09,12 0,37 0,37 C 0,37 7.45,37 7.45,37 z M 10.92,9 C 13.46,9 15.72,6.9 15.86,3.3 C 15.98,0.86 14.4,0 12.07,0 C 9.64,0 7.42,1.58 7.29,3.94 C 7.17,6.32 8.75,9 10.92,9 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2615"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,339.26808,321.45991)">
    +        <path
    +           id="path2617"
    +           d="M 7.46,25.31 C 7.46,25.31 10.1,14.05 10.1,14.05 C 11.47,8.32 14.42,6.31 16.85,6.31 C 18.77,6.31 19.33,7.13 19.24,8.32 C 19.19,9.28 19.04,10.29 18.84,11.19 C 18.84,11.19 15.48,25.31 15.48,25.31 C 15.48,25.31 22.94,25.31 22.94,25.31 C 22.94,25.31 26.48,10.5 26.48,10.5 C 26.75,9.22 27.05,7.31 27.11,6.15 C 27.33,1.64 25.08,0 20.94,0 C 17.62,0 14.39,1.54 11.84,4.88 C 11.84,4.88 11.74,4.88 11.74,4.88 C 11.74,4.88 12.42,0.31 12.42,0.31 C 12.42,0.31 5.84,0.31 5.84,0.31 C 5.41,2.45 4.86,5.04 4.08,8.06 C 4.08,8.06 0,25.31 0,25.31 C 0,25.31 7.46,25.31 7.46,25.31 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2619"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,406.72668,303.23111)">
    +        <path
    +           id="path2621"
    +           d="M 0,36 C 0,36 7.46,36 7.46,36 C 7.46,36 10.82,22 10.82,22 C 10.82,22 22.93,22 22.93,22 C 22.93,22 24.49,16 24.49,16 C 24.49,16 12.32,16 12.32,16 C 12.32,16 14.34,7 14.34,7 C 14.34,7 27.29,7 27.29,7 C 27.29,7 28.85,0 28.85,0 C 28.85,0 8.4,0 8.4,0 C 8.4,0 0,36 0,36 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2623"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,450.97718,320.28331)">
    +        <path
    +           id="path2625"
    +           d="M 7.51,26 C 7.51,26 9.75,16.6 9.75,16.6 C 10.93,11.51 13.42,7 18.13,7 C 18.55,7 18.96,7.21 19.27,7.26 C 19.27,7.26 21.09,0.05 21.09,0.05 C 20.67,0.05 20.21,0 19.69,0 C 16.22,0 13.31,2.44 11.37,5.94 C 11.37,5.94 11.17,5.94 11.17,5.94 C 11.46,4.23 11.71,2.61 11.9,1 C 11.9,1 5.47,1 5.47,1 C 5.11,3.08 4.53,7.15 3.66,10.82 C 3.66,10.82 0,26 0,26 C 0,26 7.51,26 7.51,26 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2627"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,486.15598,320.28331)">
    +        <path
    +           id="path2629"
    +           d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 C 10.71,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.43,16.81 7.47,16 C 17.6,16.27 23.99,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.73,0 0.73,8.08 0.34,15.86 C 0,22.65 3.53,26 10.78,26 C 13.57,26 17.28,25.68 20.3,24.77 C 20.3,24.77 20.06,19.25 20.06,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 C 9.1,7.91 11.22,6 14.69,6 C 16.4,6 17.38,6.65 17.32,7.53 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2631"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,531.37838,320.28331)">
    +        <path
    +           id="path2633"
    +           d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 C 10.7,20 9.03,19.62 8.11,18.88 C 7.63,18.07 7.42,16.81 7.46,16 C 17.6,16.27 23.98,13.93 24.31,7.53 C 24.55,2.7 21.02,0 15.89,0 C 6.72,0 0.72,8.08 0.33,15.86 C 0,22.65 3.52,26 10.77,26 C 13.57,26 17.27,25.68 20.3,24.77 C 20.3,24.77 20.05,19.25 20.05,19.25 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 C 9.1,7.91 11.21,6 14.68,6 C 16.39,6 17.38,6.65 17.32,7.53 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2635"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,576.36218,301.52591)">
    +        <path
    +           id="path2637"
    +           d="M 23.31,0 C 23.31,0 20.5,11.36 20.5,11.36 C 19.48,10.94 18.15,11 17.11,11 C 7.53,11 0.75,19.2 0.3,28.08 C 0,34.34 3.34,37 7.64,37 C 10.65,37 13.82,35.67 16.22,32.23 C 16.22,32.23 16.32,32.23 16.32,32.23 C 16.32,32.23 15.75,37 15.75,37 C 15.75,37 22.53,37 22.53,37 C 22.84,34 23.49,30.43 24.22,27.17 C 24.22,27.17 30.71,0 30.71,0 C 30.71,0 23.31,0 23.31,0 z M 17.47,24.42 C 16.3,29.35 13.54,31 11.36,31 C 9.19,31 7.98,29.49 8.13,26.8 C 8.38,21.82 11.8,17 16.25,17 C 17.5,17 18.57,17.19 19.16,17.47 C 19.16,17.47 17.47,24.42 17.47,24.42 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2639"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,627.02428,320.28331)">
    +        <path
    +           id="path2641"
    +           d="M 10.61,26 C 19.31,26 26.02,19.41 26.49,10.44 C 26.78,4.5 23.08,0 16.25,0 C 7.23,0 0.76,7.3 0.31,16.12 C 0,22.54 4.14,26 10.61,26 z M 11.78,20 C 9.24,20 7.84,18.38 7.99,15.96 C 8.19,11.93 10.68,6 14.97,6 C 17.93,6 18.84,8.27 18.72,10.5 C 18.5,14.9 15.82,20 11.78,20 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <g
    +         id="g2643"
    +         style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter"
    +         transform="matrix(1.705222,0,0,1.705222,675.72548,320.28331)">
    +        <path
    +           id="path2645"
    +           d="M 7.2,26 C 7.2,26 9.9,14.58 9.9,14.58 C 11.03,9.49 13.85,6 16.38,6 C 18.2,6 18.7,7.33 18.61,9.07 C 18.56,9.97 18.36,10.98 18.15,11.98 C 18.15,11.98 14.81,26 14.81,26 C 14.81,26 22.01,26 22.01,26 C 22.01,26 24.71,14.53 24.71,14.53 C 25.95,9.28 28.61,6 31.09,6 C 32.8,6 33.51,7.22 33.43,8.96 C 33.38,9.97 33.17,11.08 32.91,12.09 C 32.91,12.09 29.67,26 29.67,26 C 29.67,26 36.92,26 36.92,26 C 36.92,26 40.41,11.19 40.41,11.19 C 40.68,9.86 40.99,7.79 41.04,6.73 C 41.26,2.33 39.11,0 35.23,0 C 31.91,0 28.68,1.5 26.23,4.66 C 26.14,2.38 24.51,0 20.47,0 C 17.2,0 14.08,1.48 11.58,4.83 C 11.58,4.83 11.48,4.83 11.48,4.83 C 11.48,4.83 12.15,1 12.15,1 C 12.15,1 5.73,1 5.73,1 C 5.31,3.14 4.8,5.73 4.02,8.75 C 4.02,8.75 0,26 0,26 C 0,26 7.2,26 7.2,26 z"
    +           style="fill:#bd0000;fill-opacity:1" />
    +      </g>
    +      <path
    +         style="fill:#bd0000;fill-opacity:0;fill-rule:evenodd;stroke:#bd0000;stroke-width:8.52610779;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
    +         id="path2647"
    +         d="M 417.07944,250.20635 C 417.77165,251.98597 418.46389,253.76268 419.18494,255.50045 C 420.2954,257.86122 421.5789,260.12105 423.12198,262.2309 C 431.45755,273.56176 445.41744,279.76585 463.14129,281.31037 C 463.14129,281.31037 482.20635,281.31037 482.20635,281.31037 C 488.23446,280.84023 494.55102,279.96341 501.09833,278.68278 C 512.39026,276.47488 524.36,273.08298 536.79121,268.55034 C 546.20836,265.11659 555.88511,261.0541 565.70606,256.33256 C 587.09294,246.08041 609.18647,232.85747 630.86181,216.90021 C 638.00038,211.64939 644.85053,206.26158 651.42668,200.78291 C 657.45481,195.76715 663.23778,190.67349 668.76114,185.52364 C 684.17759,170.66675 695.81564,155.57767 702.40621,142.32874 C 709.27073,128.53184 710.64082,116.73516 705.01649,109.30381 C 701.56976,104.74235 695.80122,102.29792 688.37421,101.72251 C 721.83174,76.6178 741.32949,46.16418 734.33517,26.96361 C 732.11421,20.83591 727.22536,16.26441 720.21659,13.73631 C 717.10162,12.61581 713.59716,11.90621 709.77549,11.58321 C 709.77549,11.58321 699.47866,11.58321 699.47866,11.58321 C 685.10058,12.62011 664.19202,17.76851 646.45376,26.46171"
    +         sodipodi:nodetypes="cccccssccccscccsccc" />
    +    </g>
    +  </g>
    +</svg>
    diff --git a/htdocs/takepos/dev/img/gplv3-127x51.png b/htdocs/takepos/dev/img/gplv3-127x51.png
    new file mode 100644
    index 00000000000..3e9136e6266
    Binary files /dev/null and b/htdocs/takepos/dev/img/gplv3-127x51.png differ
    diff --git a/htdocs/takepos/dev/img/gplv3-88x31.png b/htdocs/takepos/dev/img/gplv3-88x31.png
    new file mode 100644
    index 00000000000..ba78d4c4941
    Binary files /dev/null and b/htdocs/takepos/dev/img/gplv3-88x31.png differ
    diff --git a/htdocs/takepos/dev/img/takepos.svg b/htdocs/takepos/dev/img/takepos.svg
    new file mode 100644
    index 00000000000..f51ead1a94e
    --- /dev/null
    +++ b/htdocs/takepos/dev/img/takepos.svg
    @@ -0,0 +1,70 @@
    +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
    +<!-- Created with Inkscape (http://www.inkscape.org/) -->
    +
    +<svg
    +   xmlns:dc="http://purl.org/dc/elements/1.1/"
    +   xmlns:cc="http://creativecommons.org/ns#"
    +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    +   xmlns:svg="http://www.w3.org/2000/svg"
    +   xmlns="http://www.w3.org/2000/svg"
    +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
    +   width="14"
    +   height="14"
    +   id="svg2"
    +   version="1.1"
    +   inkscape:version="0.48.3.1 r9886"
    +   sodipodi:docname="object_mymodule.svg"
    +   inkscape:export-filename="/home/raph/Travail/src/zenfusion-modules/img/object_mymodule.png"
    +   inkscape:export-xdpi="90"
    +   inkscape:export-ydpi="90">
    +  <defs
    +     id="defs4" />
    +  <sodipodi:namedview
    +     id="base"
    +     pagecolor="#ffffff"
    +     bordercolor="#666666"
    +     borderopacity="1.0"
    +     inkscape:pageopacity="0.0"
    +     inkscape:pageshadow="2"
    +     inkscape:zoom="3.959798"
    +     inkscape:cx="24.310822"
    +     inkscape:cy="18.155032"
    +     inkscape:document-units="px"
    +     inkscape:current-layer="layer1"
    +     showgrid="false"
    +     inkscape:window-width="1920"
    +     inkscape:window-height="1021"
    +     inkscape:window-x="1080"
    +     inkscape:window-y="867"
    +     inkscape:window-maximized="1" />
    +  <metadata
    +     id="metadata7">
    +    <rdf:RDF>
    +      <cc:Work
    +         rdf:about="">
    +        <dc:format>image/svg+xml</dc:format>
    +        <dc:type
    +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    +        <dc:title></dc:title>
    +      </cc:Work>
    +    </rdf:RDF>
    +  </metadata>
    +  <g
    +     inkscape:label="Calque 1"
    +     inkscape:groupmode="layer"
    +     id="layer1"
    +     transform="translate(0,-1038.3622)">
    +    <text
    +       xml:space="preserve"
    +       style="font-size:12.99629784px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Serif;-inkscape-font-specification:DejaVu Serif"
    +       x="0.35272363"
    +       y="1050.0994"
    +       id="text2985"
    +       sodipodi:linespacing="125%"><tspan
    +         sodipodi:role="line"
    +         id="tspan2987"
    +         x="0.35272363"
    +         y="1050.0994">M</tspan></text>
    +  </g>
    +</svg>
    diff --git a/htdocs/takepos/floors.php b/htdocs/takepos/floors.php
    new file mode 100644
    index 00000000000..8dd6f729950
    --- /dev/null
    +++ b/htdocs/takepos/floors.php
    @@ -0,0 +1,176 @@
    +<?php
    +/* Copyright (C) 2018	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +$_GET['theme']="md"; // Force theme. MD theme provides better look and feel to TakePOS
    +
    +require '../main.inc.php';	// Load $user and permissions
    +
    +$floor=GETPOST('floor','alpha');
    +if ($floor=="") $floor=1;
    +$id = GETPOST('id','int');
    +$action = GETPOST('action','alpha');
    +$left = GETPOST('left','alpha');
    +$top = GETPOST('top','alpha');
    +$place = GETPOST('place','int');
    +$newname = GETPOST('newname');
    +$mode = GETPOST('mode','alpha');
    +
    +if ($action=="getTables"){
    +    $sql="SELECT * from ".MAIN_DB_PREFIX."takepos_floor_tables where floor=".$floor;
    +    $resql = $db->query($sql);
    +    $rows = array();
    +    while($row = $db->fetch_array ($resql)){
    +        $rows[] = $row;
    +    }
    +    echo json_encode($rows);
    +    exit;
    +}
    +
    +if ($action=="update")
    +{
    +    if ($left>95) $left=95;
    +    if ($top>95) $top=95;
    +    if ($left>3 or $top>4) $db->query("update ".MAIN_DB_PREFIX."takepos_floor_tables set leftpos=$left, toppos=$top where label='$place'");
    +    else $db->query("delete from ".MAIN_DB_PREFIX."takepos_floor_tables where label='$place'");
    +}
    +
    +if ($action=="updatename")
    +{
    +	$newname = preg_replace("/[^a-zA-Z0-9\s]/", "", $newname); // Only English chars
    +	if (strlen($newname) > 3) $newname = substr($newname, 0, 3); // Only 3 chars
    +    $db->query("update ".MAIN_DB_PREFIX."takepos_floor_tables set label='$newname' where label='$place'");
    +}
    +
    +if ($action=="add")
    +{
    +    $asdf=$db->query("insert into ".MAIN_DB_PREFIX."takepos_floor_tables values ('', '', '', '45', '45', $floor)");
    +	$db->query("update ".MAIN_DB_PREFIX."takepos_floor_tables set label=rowid where label=''"); // No empty table names
    +}
    +
    +// Title
    +$title='TakePOS - Dolibarr '.DOL_VERSION;
    +if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title='TakePOS - '.$conf->global->MAIN_APPLICATION_TITLE;
    +top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
    +?>
    +<link rel="stylesheet" href="css/pos.css?a=xxx">
    +<style type="text/css">
    +div.tablediv{
    +background-image:url(img/table.gif);
    +-moz-background-size:100% 100%;
    +-webkit-background-size:100% 100%;
    +background-size:100% 100%;
    +height:10%;
    +width:10%;
    +text-align: center;
    +font-size:300%;
    +color:white;
    +}
    +html, body
    +{
    +height: 100%;
    +}
    +</style>
    +
    +<script>
    +var DragDrop='<?php echo $langs->trans("DragDrop"); ?>';
    +
    +function updateplace(idplace, left, top) {
    +	$.ajax({
    +		type: "POST",
    +		url: "floors.php",
    +		data: { action: "update", left: left, top: top, place: idplace }
    +		}).done(function( msg ) {
    +		window.location.href='floors.php?mode=edit&floor=<?php echo $floor;?>';
    +	});
    +}
    +
    +function updatename(before) {
    +	var after=$("#"+before).text();
    +	$.ajax({
    +		type: "POST",
    +		url: "floors.php",
    +		data: { action: "updatename", place: before, newname: after }
    +		}).done(function( msg ) {
    +		window.location.href='floors.php?mode=edit&floor=<?php echo $floor;?>';
    +		});
    +	}
    +
    +function LoadPlace(place){
    +	parent.location.href='takepos.php?place='+place;
    +}
    +
    +
    +$( document ).ready(function() {
    +	$.getJSON('./floors.php?action=getTables&floor=<?php echo $floor; ?>', function(data) {
    +        $.each(data, function(key, val) {
    +			<?php if ($mode=="edit"){?>
    +			$('body').append('<div class="tablediv" contenteditable onblur="updatename('+val.label+');" style="position: absolute; left: '+val.leftpos+'%; top: '+val.toppos+'%;" id="'+val.label+'">'+val.label+'</div>');
    +			$( "#"+val.label ).draggable(
    +				{
    +					start: function() {
    +					$("#add").html("<?php echo $langs->trans("Delete"); ?>");
    +                    },
    +					stop: function() {
    +					var left=$(this).offset().left*100/$(window).width();
    +					var top=$(this).offset().top*100/$(window).height();
    +					updateplace($(this).attr('id'), left, top);
    +					}
    +				}
    +			);
    +			//simultaneous draggable and contenteditable
    +			$('#'+val.label).draggable().bind('click', function(){
    +				$(this).focus();
    +			})
    +			<?php }
    +			else {?>
    +			$('body').append('<div class="tablediv" onclick="LoadPlace('+val.label+');" style="position: absolute; left: '+val.leftpos+'%; top: '+val.toppos+'%;" id="'+val.label+'">'+val.label+'</div>');
    +			<?php } ?>
    +		});
    +	});
    +});
    +
    +</script>
    +</head>
    +<body style="overflow: hidden">
    +<?php if ($user->admin){?>
    +<div style="position: absolute; left: 0.1%; top: 0.8%; width:8%; height:11%;">
    +<?php if ($mode=="edit"){?>
    +<a id="add" onclick="window.location.href='floors.php?mode=edit&action=add&floor=<?php echo $floor;?>';"><?php echo $langs->trans("AddTable"); ?></a>
    +<?php } else { ?>
    +<a onclick="window.location.href='floors.php?mode=edit&floor=<?php echo $floor;?>';"><?php echo $langs->trans("Edit"); ?></a>
    +<?php } ?>
    +</div>
    +<?php }
    +?>
    +
    +<div style="position: absolute; left: 25%; bottom: 8%; width:50%; height:3%;">
    +    <center>
    +    <h1><img src="./img/arrow-prev.png" width="5%" onclick="location.href='floors.php?floor=<?php if ($floor>1) { $floor--; echo $floor; $floor++;} else echo "1"; ?>';"><?php echo $langs->trans("Floor")." ".$floor; ?><img src="./img/arrow-next.png" width="5%" onclick="location.href='floors.php?floor=<?php $floor++; echo $floor; ?>';"></h1>
    +    </center>
    +</div>
    +</body>
    +</html>
    \ No newline at end of file
    diff --git a/htdocs/takepos/freezone.php b/htdocs/takepos/freezone.php
    new file mode 100644
    index 00000000000..702c59541a3
    --- /dev/null
    +++ b/htdocs/takepos/freezone.php
    @@ -0,0 +1,59 @@
    +<?php
    +/* Copyright (C) 2018	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +require '../main.inc.php';	// Load $user and permissions
    +
    +$langs->loadLangs(array("bills", "cashdesk"));
    +
    +$place = GETPOST('place','int');
    +
    +
    +/*
    + * View
    + */
    +
    +top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
    +
    +?>
    +<script>
    +function Save(){
    +	$.get( "invoice.php", { action: "freezone", place: "<?php echo $place;?>", desc:$('#desc').val(), number:$('#price').val()} );
    +	parent.$.colorbox.close();
    +}
    +</script>
    +</head>
    +<body>
    +<br>
    +<center>
    +<input type="text" id="desc" name="desc" style="width:40%;font-size: 200%;" placeholder="<?php echo $langs->trans('Description');?>">
    +<input type="text" id="price" name="price" style="width:15%;font-size: 200%;" placeholder="<?php echo $langs->trans('Price');?>">
    +<input type="hidden" name="place" value="<?php echo $place;?>">
    +<input type="button" style="width:15%;font-size: 200%;" value="OK" onclick="Save();">
    +</center>
    +
    +</body>
    +</html>
    \ No newline at end of file
    diff --git a/htdocs/takepos/genimg/add.jpg b/htdocs/takepos/genimg/add.jpg
    new file mode 100644
    index 00000000000..976fd10697d
    Binary files /dev/null and b/htdocs/takepos/genimg/add.jpg differ
    diff --git a/htdocs/takepos/genimg/empty.jpg b/htdocs/takepos/genimg/empty.jpg
    new file mode 100644
    index 00000000000..8883f7c9957
    Binary files /dev/null and b/htdocs/takepos/genimg/empty.jpg differ
    diff --git a/htdocs/takepos/genimg/index.php b/htdocs/takepos/genimg/index.php
    new file mode 100644
    index 00000000000..ff1b368b743
    --- /dev/null
    +++ b/htdocs/takepos/genimg/index.php
    @@ -0,0 +1,143 @@
    +<?php
    +/* Copyright (C) 2018	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +require '../../main.inc.php';	// Load $user and permissions
    +
    +$id= GETPOST('id');
    +$w= GETPOST('w');
    +$h= GETPOST('h');
    +$query= GETPOST('query');
    +
    +
    +
    +/*
    + * View
    + */
    +
    +header('Content-Type: image/jpeg');
    +header('Cache-Control: max-age=604800, public, must-revalidate');
    +header('Pragma: cache');
    +
    +if ($query=="cat")
    +{
    +	require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +	require_once DOL_DOCUMENT_ROOT.'/core/lib/categories.lib.php';
    +
    +	$object = new Categorie($db);
    +	$result = $object->fetch($id);
    +	$upload_dir = $conf->categorie->multidir_output[$object->entity];
    +	$pdir = get_exdir($object->id,2,0,0,$object,'category') . $object->id ."/photos/";
    +	$dir = $upload_dir.'/'.$pdir;
    +	foreach ($object->liste_photos($dir) as $key => $obj)
    +	{
    +		$filename=$obj['photo'];
    +	}
    +
    +	// The file
    +	$filename = $dir.$filename;
    +	if (!file_exists($filename)) $filename="empty.jpg";
    +
    +	// Dimensions
    +	list($width, $height) = getimagesize($filename);
    +	$new_width = $w;
    +	$new_height = $h;
    +
    +	// Resample
    +	$image_p = imagecreatetruecolor($new_width, $new_height);
    +	$image = imagecreatefromjpeg($filename);
    +	imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    +
    +	// Add icon
    +	$icon = imagecreatefromjpeg('add.jpg');
    +	list($width, $height) = getimagesize('add.jpg');
    +	$new_width = $w*0.3;
    +	$new_height = $h*0.3;
    +	$icon_p = imagecreatetruecolor($new_width, $new_height);
    +	imagecopyresampled($icon_p, $icon, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    +	imagecopymerge($image_p, $icon_p,  0, 0, 0, 0, $new_width, $new_height, 100);
    +
    +	// Output
    +	imagejpeg($image_p, null, 100);
    +}
    +else if ($query=="pro")
    +{
    +	require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
    +
    +	$objProd = new Product($db);
    +	$objProd->fetch($id);
    +
    +	$dir .= get_exdir(0,0,0,0,$objProd,'product').$objProd->ref.'/';
    +	$pdir .= get_exdir(0,0,0,0,$objProd,'product').$objProd->ref.'/';
    +
    +	foreach ($objProd->liste_photos($dir) as $key => $obj)
    +	{
    +		$filename=$obj['photo'];
    +	}
    +	$filename = $dir.$filename;
    +
    +	if (!file_exists($filename)){
    +		$dir = $conf->product->multidir_output[$objProd->entity].'/'.$pdir;
    +		foreach ($objProd->liste_photos($dir) as $key => $obj)
    +		{
    +		$filename=$obj['photo'];
    +		}
    +		$filename = $dir.$filename;
    +	}
    +
    +	if (!file_exists($filename)) $filename="empty.jpg";
    +
    +	// Dimensions
    +	list($width, $height) = getimagesize($filename);
    +	$new_width = $w;
    +	$new_height = $h;
    +
    +	// Resample
    +	$image_p = imagecreatetruecolor($new_width, $new_height);
    +	$image = imagecreatefromjpeg($filename);
    +	imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    +
    +	// Output
    +	imagejpeg($image_p, null, 100);
    +}
    +else
    +{
    +	// The file
    +	$filename = $query.".jpg";
    +
    +	// Dimensions
    +	list($width, $height) = getimagesize($filename);
    +	$new_width = $w;
    +	$new_height = $h;
    +
    +	// Resample
    +	$image_p = imagecreatetruecolor($new_width, $new_height);
    +	$image = imagecreatefromjpeg($filename);
    +	imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    +
    +	// Output
    +	imagejpeg($image_p, null, 100);
    +}
    diff --git a/htdocs/takepos/img/arrow-next-top.png b/htdocs/takepos/img/arrow-next-top.png
    new file mode 100644
    index 00000000000..70f720cab10
    Binary files /dev/null and b/htdocs/takepos/img/arrow-next-top.png differ
    diff --git a/htdocs/takepos/img/arrow-next.png b/htdocs/takepos/img/arrow-next.png
    new file mode 100644
    index 00000000000..1056f024390
    Binary files /dev/null and b/htdocs/takepos/img/arrow-next.png differ
    diff --git a/htdocs/takepos/img/arrow-prev-top.png b/htdocs/takepos/img/arrow-prev-top.png
    new file mode 100644
    index 00000000000..23567d35890
    Binary files /dev/null and b/htdocs/takepos/img/arrow-prev-top.png differ
    diff --git a/htdocs/takepos/img/arrow-prev.png b/htdocs/takepos/img/arrow-prev.png
    new file mode 100644
    index 00000000000..b7311f26f54
    Binary files /dev/null and b/htdocs/takepos/img/arrow-prev.png differ
    diff --git a/htdocs/takepos/img/gfdl.png b/htdocs/takepos/img/gfdl.png
    new file mode 100644
    index 00000000000..f2bacfd179a
    Binary files /dev/null and b/htdocs/takepos/img/gfdl.png differ
    diff --git a/htdocs/takepos/img/gplv3.png b/htdocs/takepos/img/gplv3.png
    new file mode 100644
    index 00000000000..ba78d4c4941
    Binary files /dev/null and b/htdocs/takepos/img/gplv3.png differ
    diff --git a/htdocs/takepos/img/marketplace/cashcontrol.jpg b/htdocs/takepos/img/marketplace/cashcontrol.jpg
    new file mode 100644
    index 00000000000..66240218dff
    Binary files /dev/null and b/htdocs/takepos/img/marketplace/cashcontrol.jpg differ
    diff --git a/htdocs/takepos/img/marketplace/takeposmobile.jpg b/htdocs/takepos/img/marketplace/takeposmobile.jpg
    new file mode 100644
    index 00000000000..918f7c49d5e
    Binary files /dev/null and b/htdocs/takepos/img/marketplace/takeposmobile.jpg differ
    diff --git a/htdocs/takepos/img/object_takepos.png b/htdocs/takepos/img/object_takepos.png
    new file mode 100644
    index 00000000000..5a307bfc62f
    Binary files /dev/null and b/htdocs/takepos/img/object_takepos.png differ
    diff --git a/htdocs/takepos/img/table.gif b/htdocs/takepos/img/table.gif
    new file mode 100644
    index 00000000000..54f7a209d89
    Binary files /dev/null and b/htdocs/takepos/img/table.gif differ
    diff --git a/htdocs/takepos/img/takepos.png b/htdocs/takepos/img/takepos.png
    new file mode 100644
    index 00000000000..be9d3dcfc3f
    Binary files /dev/null and b/htdocs/takepos/img/takepos.png differ
    diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php
    new file mode 100644
    index 00000000000..c71f7f861a3
    --- /dev/null
    +++ b/htdocs/takepos/invoice.php
    @@ -0,0 +1,290 @@
    +<?php
    +/* Copyright (C) 2018	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +require '../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
    +
    +$langs->loadLangs(array("bills", "cashdesk"));
    +
    +$id = GETPOST('id','int');
    +$action = GETPOST('action','alpha');
    +$idproduct = GETPOST('idproduct','int');
    +$place = GETPOST('place','int');
    +$number = GETPOST('number');
    +$idline = GETPOST('idline');
    +$desc = GETPOST('desc','alpha');
    +$pay = GETPOST('pay');
    +
    +$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."facture where facnumber='(PROV-POS-".$place.")'";
    +$resql = $db->query($sql);
    +$row = $db->fetch_array ($resql);
    +$placeid=$row[0];
    +if (! $placeid) $placeid=0; // not necesary
    +else{
    +	$invoice = new Facture($db);
    +	$invoice->fetch($placeid);
    +}
    +
    +/*
    + * Actions
    + */
    +
    +if ($action == 'valid' && $user->rights->facture->creer){
    +	if ($pay=="cash") $bankaccount=$conf->global->CASHDESK_ID_BANKACCOUNT_CASH;
    +	else if ($pay=="card") $bankaccount=$conf->global->CASHDESK_ID_BANKACCOUNT_CB;
    +	$now=dol_now();
    +	$invoice = new Facture($db);
    +	$invoice->fetch($placeid);
    +	if (! empty($conf->stock->enabled) and $conf->global->CASHDESK_NO_DECREASE_STOCK!="1") $invoice->validate($user, '', $conf->global->CASHDESK_ID_WAREHOUSE);
    +	else $invoice->validate($user);
    +	// Add the payment
    +	$payment=new Paiement($db);
    +	$payment->datepaye=$now;
    +	$payment->bank_account=$bankaccount;
    +	$payment->amounts[$invoice->id]=$invoice->total_ttc;
    +	if ($pay=="cash") $payment->paiementid=4;
    +	else if ($pay=="card") $payment->paiementid=6;
    +	$payment->num_paiement=$invoice->facnumber;
    +	$payment->create($user);
    +	$payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', '');
    +	$invoice->set_paid($user);
    +}
    +
    +if (($action=="addline" || $action=="freezone") and $placeid==0)
    +{
    +	// $place is id of POS, $placeid is id of invoice
    +	if ($placeid==0) {
    +		$invoice = new Facture($db);
    +		$invoice->socid=$conf->global->CASHDESK_ID_THIRDPARTY;
    +		$invoice->date=dol_now();
    +		$invoice->ref="(PROV-POS)";
    +		$invoice->module_source = 'takepos';
    +		$invoice->pos_source = (string) (empty($place)?'0':$place);
    +
    +		$placeid=$invoice->create($user);
    +		$sql="UPDATE ".MAIN_DB_PREFIX."facture set facnumber='(PROV-POS-".$place.")' where rowid=".$placeid;
    +		$db->query($sql);
    +	}
    +}
    +
    +if ($action=="addline"){
    +	$prod = new Product($db);
    +	$prod->fetch($idproduct);
    +	$invoice->addline($prod->description, $prod->price, 1, $prod->tva_tx, $prod->localtax1_tx, $prod->localtax2_tx, $idproduct, $prod->remise_percent, '', 0, 0, 0, '', $prod->price_base_type, $prod->price_ttc, $prod->type, - 1, 0, '', 0, 0, null, 0, '', 0, 100, '', null, 0);
    +	$invoice->fetch($placeid);
    +}
    +
    +if ($action=="freezone"){
    +	$invoice->addline($desc, $number, 1, $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS, 0, 0, 0, 0, '', 0, 0, 0, '', 'TTC', $number, 0, - 1, 0, '', 0, 0, null, 0, '', 0, 100, '', null, 0);
    +	$invoice->fetch($placeid);
    +}
    +
    +if ($action=="deleteline"){
    +    if ($idline>0 and $placeid>0){ //If exist invoice and line, to avoid errors if deleted from other device or no line selected
    +        $invoice->deleteline($idline);
    +        $invoice->fetch($placeid);
    +    }
    +    else if ($placeid>0){ //If exist invoice, but no line selected, proced to delete last line
    +        $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."facturedet where fk_facture='$placeid' order by rowid DESC";
    +        $resql = $db->query($sql);
    +        $row = $db->fetch_array ($resql);
    +        $deletelineid=$row[0];
    +        $invoice->deleteline($deletelineid);
    +        $invoice->fetch($placeid);
    +    }
    +}
    +
    +if ($action=="updateqty"){
    +    foreach ($invoice->lines as $line){
    +        if ($line->id==$idline) $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $number, $line->remise_percent,
    +			$line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type,
    +			$line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent,
    +			$line->fk_unit);
    +    }
    +	$invoice->fetch($placeid);
    +}
    +
    +if ($action=="updateprice"){
    +    foreach ($invoice->lines as $line){
    +        if ($line->id==$idline) $result = $invoice->updateline($line->id, $line->desc, $number, $line->qty, $line->remise_percent,
    +			$line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type,
    +			$line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent,
    +			$line->fk_unit);
    +    }
    +	$invoice->fetch($placeid);
    +}
    +
    +if ($action=="updatereduction"){
    +    foreach ($invoice->lines as $line){
    +        if ($line->id==$idline) $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty, $number,
    +			$line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type,
    +			$line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent,
    +			$line->fk_unit);
    +    }
    +	$invoice->fetch($placeid);
    +}
    +
    +if ($action=="order"){
    +	require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
    +	$headerorder='<html><br><b>'.$langs->trans('Place').' '.$place.'<br><table width="65%"><thead><tr><th align="left">'.$langs->trans("Label").'</th><th align="right">'.$langs->trans("Qty").'</th></tr></thead><tbody>';
    +	$footerorder='</tbody></table>'.dol_print_date(dol_now(), 'dayhour').'<br></html>';
    +	$order_receipt_printer1="";
    +	$order_receipt_printer2="";
    +	$catsprinter1 = explode(';',$conf->global->TAKEPOS_PRINTED_CATEGORIES_1);
    +	$catsprinter2 = explode(';',$conf->global->TAKEPOS_PRINTED_CATEGORIES_2);
    +	foreach ($invoice->lines as $line){
    +		if ($line->special_code=="3") continue;
    +		$c = new Categorie($db);
    +		$existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
    +		$result = array_intersect($catsprinter1, $existing);
    +		$count=count($result);
    +		if ($count>0){
    +			$sql="UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='3' where rowid=$line->rowid";
    +			$db->query($sql);
    +			$order_receipt_printer1.='<tr>'.$line->product_label.'<td align="right">'.$line->qty.'</td></tr>';
    +		}
    +    }
    +	foreach ($invoice->lines as $line){
    +		if ($line->special_code=="3") continue;
    +		$c = new Categorie($db);
    +		$existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
    +		$result = array_intersect($catsprinter2, $existing);
    +		$count=count($result);
    +		if ($count>0){
    +			$sql="UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='3' where rowid=$line->rowid";
    +			$db->query($sql);
    +			$order_receipt_printer2.='<tr>'.$line->product_label.'<td align="right">'.$line->qty.'</td></tr>';
    +		}
    +    }
    +	$invoice->fetch($placeid);
    +}
    +
    +?>
    +<style>
    +.selected {
    +	color: red;
    +}
    +.order {
    +	color: limegreen;
    +}
    +</style>
    +<script language="javascript">
    +var selectedline=0;
    +var selectedtext="";
    +$(document).ready(function(){
    +    $('table tbody tr').click(function(){
    +		$('table tbody tr').removeClass("selected");
    +        $(this).addClass("selected");
    +		if (selectedline==this.id) return; // If is already selected
    +        else selectedline=this.id;
    +        selectedtext=$('#'+selectedline).find("td:first").html();
    +    });
    +<?php if ($action=="order" and $order_receipt_printer1!=""){
    +	?>
    +	$.ajax({
    +		type: "POST",
    +		url: 'http://<?php print $conf->global->TAKEPOS_PRINT_SERVER;?>:8111/print',
    +		data: '<?php print $headerorder.$order_receipt_printer1.$footerorder; ?>'
    +	});
    +<?php
    +}
    +if ($action=="order" and $order_receipt_printer2!=""){
    +	?>
    +	$.ajax({
    +		type: "POST",
    +		url: 'http://<?php print $conf->global->TAKEPOS_PRINT_SERVER;?>:8111/print2',
    +		data: '<?php print $headerorder.$order_receipt_printer2.$footerorder; ?>'
    +	});
    +<?php
    +}
    +if ($action=="search"){
    +	?>
    +	$('#search').focus();
    +	<?php
    +}
    +?>
    +});
    +
    +function Print(id){
    +	$.colorbox({href:"receipt.php?facid="+id, width:"40%", height:"90%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("PrintTicket");?>"});
    +}
    +
    +function TakeposPrinting(id){
    +	var receipt;
    +	$.get("receipt.php?facid="+id, function(data, status){
    +        receipt=data.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '');;
    +		$.ajax({
    +			type: "POST",
    +			url: 'http://<?php print $conf->global->TAKEPOS_PRINT_SERVER;?>:8111/print',
    +			data: receipt
    +		});
    +    });
    +}
    +</script>
    +<?php
    +print '<div class="div-table-responsive-no-min">';
    +print '<table id="tablelines" class="noborder noshadow" width="100%">';
    +print '<tr class="liste_titre nodrag nodrop">';
    +print '<td class="linecoldescription">'.$langs->trans('Description').'</td>';
    +print '<td class="linecolqty" align="right">'.$langs->trans('Qty').'</td>';
    +print '<td class="linecolht" align="right">'.$langs->trans('TotalHTShort').'</td>';
    +print "</tr>\n";
    +if ($placeid>0) foreach ($invoice->lines as $line)
    +{
    +	print '<tr class="drag drop oddeven';
    +	if ($line->special_code=="3") print ' order';
    +	print '" id="'.$line->rowid.'">';
    +	print '<td>'.$line->product_label.$line->desc.'</td>';
    +	print '<td align="right">'.$line->qty.'</td>';
    +	print '<td align="right">'.price($line->total_ttc).'</td>';
    +	print '</tr>';
    +}
    +print '</table>';
    +print '<p style="font-size:120%;" align="right"><b>'.$langs->trans('TotalTTC');
    +if($conf->global->TAKEPOS_BAR_RESTAURANT) print " ".$langs->trans('Place')." ".$place;
    +print ': '.price($invoice->total_ttc, 1, '', 1, - 1, - 1, $conf->currency).'&nbsp;</b></p>';
    +
    +//if ($invoice->socid != $conf->global->CASHDESK_ID_THIRDPARTY){
    +    $soc = new Societe($db);
    +    if ($invoice->socid > 0) $soc->fetch($invoice->socid);
    +    else $soc->fetch($conf->global->CASHDESK_ID_THIRDPARTY);
    +    print '<p style="font-size:120%;" align="right">';
    +    print $langs->trans("Customer").': '.$soc->name;
    +    print '</p>';
    +//}
    +if ($action=="valid"){
    +	print '<p style="font-size:120%;" align="center"><b>'.$invoice->facnumber." ".$langs->trans('BillShortStatusValidated').'</b></p>';
    +	if ($conf->global->TAKEBOX) print '<center><button type="button" onclick="TakeposPrinting('.$placeid.');">'.$langs->trans('PrintTicket').'</button><center>';
    +	else print '<center><button type="button" onclick="Print('.$placeid.');">'.$langs->trans('PrintTicket').'</button><center>';
    +}
    +if ($action=="search"){
    +	print '<center>
    +	<input type="text" id="search" name="search" onkeyup="Search2();" name="search" style="width:80%;font-size: 150%;" placeholder='.$langs->trans('Search').'
    +	</center>';
    +}
    +print '</div>';
    diff --git a/htdocs/takepos/js/jquery.colorbox-min.js b/htdocs/takepos/js/jquery.colorbox-min.js
    new file mode 100644
    index 00000000000..b5109a262ef
    --- /dev/null
    +++ b/htdocs/takepos/js/jquery.colorbox-min.js
    @@ -0,0 +1,6 @@
    +/*!
    +	Colorbox 1.6.4
    +	license: MIT
    +	http://www.jacklmoore.com/colorbox
    +*/
    +(function(t,e,i){function n(i,n,o){var r=e.createElement(i);return n&&(r.id=Z+n),o&&(r.style.cssText=o),t(r)}function o(){return i.innerHeight?i.innerHeight:t(i).height()}function r(e,i){i!==Object(i)&&(i={}),this.cache={},this.el=e,this.value=function(e){var n;return void 0===this.cache[e]&&(n=t(this.el).attr("data-cbox-"+e),void 0!==n?this.cache[e]=n:void 0!==i[e]?this.cache[e]=i[e]:void 0!==X[e]&&(this.cache[e]=X[e])),this.cache[e]},this.get=function(e){var i=this.value(e);return t.isFunction(i)?i.call(this.el,this):i}}function h(t){var e=W.length,i=(A+t)%e;return 0>i?e+i:i}function a(t,e){return Math.round((/%/.test(t)?("x"===e?E.width():o())/100:1)*parseInt(t,10))}function s(t,e){return t.get("photo")||t.get("photoRegex").test(e)}function l(t,e){return t.get("retinaUrl")&&i.devicePixelRatio>1?e.replace(t.get("photoRegex"),t.get("retinaSuffix")):e}function d(t){"contains"in x[0]&&!x[0].contains(t.target)&&t.target!==v[0]&&(t.stopPropagation(),x.focus())}function c(t){c.str!==t&&(x.add(v).removeClass(c.str).addClass(t),c.str=t)}function g(e){A=0,e&&e!==!1&&"nofollow"!==e?(W=t("."+te).filter(function(){var i=t.data(this,Y),n=new r(this,i);return n.get("rel")===e}),A=W.index(_.el),-1===A&&(W=W.add(_.el),A=W.length-1)):W=t(_.el)}function u(i){t(e).trigger(i),ae.triggerHandler(i)}function f(i){var o;if(!G){if(o=t(i).data(Y),_=new r(i,o),g(_.get("rel")),!U){U=$=!0,c(_.get("className")),x.css({visibility:"hidden",display:"block",opacity:""}),I=n(se,"LoadedContent","width:0; height:0; overflow:hidden; visibility:hidden"),b.css({width:"",height:""}).append(I),j=T.height()+k.height()+b.outerHeight(!0)-b.height(),D=C.width()+H.width()+b.outerWidth(!0)-b.width(),N=I.outerHeight(!0),z=I.outerWidth(!0);var h=a(_.get("initialWidth"),"x"),s=a(_.get("initialHeight"),"y"),l=_.get("maxWidth"),f=_.get("maxHeight");_.w=Math.max((l!==!1?Math.min(h,a(l,"x")):h)-z-D,0),_.h=Math.max((f!==!1?Math.min(s,a(f,"y")):s)-N-j,0),I.css({width:"",height:_.h}),J.position(),u(ee),_.get("onOpen"),O.add(F).hide(),x.focus(),_.get("trapFocus")&&e.addEventListener&&(e.addEventListener("focus",d,!0),ae.one(re,function(){e.removeEventListener("focus",d,!0)})),_.get("returnFocus")&&ae.one(re,function(){t(_.el).focus()})}var p=parseFloat(_.get("opacity"));v.css({opacity:p===p?p:"",cursor:_.get("overlayClose")?"pointer":"",visibility:"visible"}).show(),_.get("closeButton")?B.html(_.get("close")).appendTo(b):B.appendTo("<div/>"),w()}}function p(){x||(V=!1,E=t(i),x=n(se).attr({id:Y,"class":t.support.opacity===!1?Z+"IE":"",role:"dialog",tabindex:"-1"}).hide(),v=n(se,"Overlay").hide(),L=t([n(se,"LoadingOverlay")[0],n(se,"LoadingGraphic")[0]]),y=n(se,"Wrapper"),b=n(se,"Content").append(F=n(se,"Title"),R=n(se,"Current"),P=t('<button type="button"/>').attr({id:Z+"Previous"}),K=t('<button type="button"/>').attr({id:Z+"Next"}),S=t('<button type="button"/>').attr({id:Z+"Slideshow"}),L),B=t('<button type="button"/>').attr({id:Z+"Close"}),y.append(n(se).append(n(se,"TopLeft"),T=n(se,"TopCenter"),n(se,"TopRight")),n(se,!1,"clear:left").append(C=n(se,"MiddleLeft"),b,H=n(se,"MiddleRight")),n(se,!1,"clear:left").append(n(se,"BottomLeft"),k=n(se,"BottomCenter"),n(se,"BottomRight"))).find("div div").css({"float":"left"}),M=n(se,!1,"position:absolute; width:9999px; visibility:hidden; display:none; max-width:none;"),O=K.add(P).add(R).add(S)),e.body&&!x.parent().length&&t(e.body).append(v,x.append(y,M))}function m(){function i(t){t.which>1||t.shiftKey||t.altKey||t.metaKey||t.ctrlKey||(t.preventDefault(),f(this))}return x?(V||(V=!0,K.click(function(){J.next()}),P.click(function(){J.prev()}),B.click(function(){J.close()}),v.click(function(){_.get("overlayClose")&&J.close()}),t(e).bind("keydown."+Z,function(t){var e=t.keyCode;U&&_.get("escKey")&&27===e&&(t.preventDefault(),J.close()),U&&_.get("arrowKey")&&W[1]&&!t.altKey&&(37===e?(t.preventDefault(),P.click()):39===e&&(t.preventDefault(),K.click()))}),t.isFunction(t.fn.on)?t(e).on("click."+Z,"."+te,i):t("."+te).live("click."+Z,i)),!0):!1}function w(){var e,o,r,h=J.prep,d=++le;if($=!0,q=!1,u(he),u(ie),_.get("onLoad"),_.h=_.get("height")?a(_.get("height"),"y")-N-j:_.get("innerHeight")&&a(_.get("innerHeight"),"y"),_.w=_.get("width")?a(_.get("width"),"x")-z-D:_.get("innerWidth")&&a(_.get("innerWidth"),"x"),_.mw=_.w,_.mh=_.h,_.get("maxWidth")&&(_.mw=a(_.get("maxWidth"),"x")-z-D,_.mw=_.w&&_.w<_.mw?_.w:_.mw),_.get("maxHeight")&&(_.mh=a(_.get("maxHeight"),"y")-N-j,_.mh=_.h&&_.h<_.mh?_.h:_.mh),e=_.get("href"),Q=setTimeout(function(){L.show()},100),_.get("inline")){var c=t(e).eq(0);r=t("<div>").hide().insertBefore(c),ae.one(he,function(){r.replaceWith(c)}),h(c)}else _.get("iframe")?h(" "):_.get("html")?h(_.get("html")):s(_,e)?(e=l(_,e),q=_.get("createImg"),t(q).addClass(Z+"Photo").bind("error."+Z,function(){h(n(se,"Error").html(_.get("imgError")))}).one("load",function(){d===le&&setTimeout(function(){var e;_.get("retinaImage")&&i.devicePixelRatio>1&&(q.height=q.height/i.devicePixelRatio,q.width=q.width/i.devicePixelRatio),_.get("scalePhotos")&&(o=function(){q.height-=q.height*e,q.width-=q.width*e},_.mw&&q.width>_.mw&&(e=(q.width-_.mw)/q.width,o()),_.mh&&q.height>_.mh&&(e=(q.height-_.mh)/q.height,o())),_.h&&(q.style.marginTop=Math.max(_.mh-q.height,0)/2+"px"),W[1]&&(_.get("loop")||W[A+1])&&(q.style.cursor="pointer",t(q).bind("click."+Z,function(){J.next()})),q.style.width=q.width+"px",q.style.height=q.height+"px",h(q)},1)}),q.src=e):e&&M.load(e,_.get("data"),function(e,i){d===le&&h("error"===i?n(se,"Error").html(_.get("xhrError")):t(this).contents())})}var v,x,y,b,T,C,H,k,W,E,I,M,L,F,R,S,K,P,B,O,_,j,D,N,z,A,q,U,$,G,Q,J,V,X={html:!1,photo:!1,iframe:!1,inline:!1,transition:"elastic",speed:300,fadeOut:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,opacity:.9,preloading:!0,className:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0,closeButton:!0,fastIframe:!0,open:!1,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico|webp|jxr|svg)((#|\?).*)?$/i,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",returnFocus:!0,trapFocus:!0,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,rel:function(){return this.rel},href:function(){return t(this).attr("href")},title:function(){return this.title},createImg:function(){var e=new Image,i=t(this).data("cbox-img-attrs");return"object"==typeof i&&t.each(i,function(t,i){e[t]=i}),e},createIframe:function(){var i=e.createElement("iframe"),n=t(this).data("cbox-iframe-attrs");return"object"==typeof n&&t.each(n,function(t,e){i[t]=e}),"frameBorder"in i&&(i.frameBorder=0),"allowTransparency"in i&&(i.allowTransparency="true"),i.name=(new Date).getTime(),i.allowFullscreen=!0,i}},Y="colorbox",Z="cbox",te=Z+"Element",ee=Z+"_open",ie=Z+"_load",ne=Z+"_complete",oe=Z+"_cleanup",re=Z+"_closed",he=Z+"_purge",ae=t("<a/>"),se="div",le=0,de={},ce=function(){function t(){clearTimeout(h)}function e(){(_.get("loop")||W[A+1])&&(t(),h=setTimeout(J.next,_.get("slideshowSpeed")))}function i(){S.html(_.get("slideshowStop")).unbind(s).one(s,n),ae.bind(ne,e).bind(ie,t),x.removeClass(a+"off").addClass(a+"on")}function n(){t(),ae.unbind(ne,e).unbind(ie,t),S.html(_.get("slideshowStart")).unbind(s).one(s,function(){J.next(),i()}),x.removeClass(a+"on").addClass(a+"off")}function o(){r=!1,S.hide(),t(),ae.unbind(ne,e).unbind(ie,t),x.removeClass(a+"off "+a+"on")}var r,h,a=Z+"Slideshow_",s="click."+Z;return function(){r?_.get("slideshow")||(ae.unbind(oe,o),o()):_.get("slideshow")&&W[1]&&(r=!0,ae.one(oe,o),_.get("slideshowAuto")?i():n(),S.show())}}();t[Y]||(t(p),J=t.fn[Y]=t[Y]=function(e,i){var n,o=this;return e=e||{},t.isFunction(o)&&(o=t("<a/>"),e.open=!0),o[0]?(p(),m()&&(i&&(e.onComplete=i),o.each(function(){var i=t.data(this,Y)||{};t.data(this,Y,t.extend(i,e))}).addClass(te),n=new r(o[0],e),n.get("open")&&f(o[0])),o):o},J.position=function(e,i){function n(){T[0].style.width=k[0].style.width=b[0].style.width=parseInt(x[0].style.width,10)-D+"px",b[0].style.height=C[0].style.height=H[0].style.height=parseInt(x[0].style.height,10)-j+"px"}var r,h,s,l=0,d=0,c=x.offset();if(E.unbind("resize."+Z),x.css({top:-9e4,left:-9e4}),h=E.scrollTop(),s=E.scrollLeft(),_.get("fixed")?(c.top-=h,c.left-=s,x.css({position:"fixed"})):(l=h,d=s,x.css({position:"absolute"})),d+=_.get("right")!==!1?Math.max(E.width()-_.w-z-D-a(_.get("right"),"x"),0):_.get("left")!==!1?a(_.get("left"),"x"):Math.round(Math.max(E.width()-_.w-z-D,0)/2),l+=_.get("bottom")!==!1?Math.max(o()-_.h-N-j-a(_.get("bottom"),"y"),0):_.get("top")!==!1?a(_.get("top"),"y"):Math.round(Math.max(o()-_.h-N-j,0)/2),x.css({top:c.top,left:c.left,visibility:"visible"}),y[0].style.width=y[0].style.height="9999px",r={width:_.w+z+D,height:_.h+N+j,top:l,left:d},e){var g=0;t.each(r,function(t){return r[t]!==de[t]?(g=e,void 0):void 0}),e=g}de=r,e||x.css(r),x.dequeue().animate(r,{duration:e||0,complete:function(){n(),$=!1,y[0].style.width=_.w+z+D+"px",y[0].style.height=_.h+N+j+"px",_.get("reposition")&&setTimeout(function(){E.bind("resize."+Z,J.position)},1),t.isFunction(i)&&i()},step:n})},J.resize=function(t){var e;U&&(t=t||{},t.width&&(_.w=a(t.width,"x")-z-D),t.innerWidth&&(_.w=a(t.innerWidth,"x")),I.css({width:_.w}),t.height&&(_.h=a(t.height,"y")-N-j),t.innerHeight&&(_.h=a(t.innerHeight,"y")),t.innerHeight||t.height||(e=I.scrollTop(),I.css({height:"auto"}),_.h=I.height()),I.css({height:_.h}),e&&I.scrollTop(e),J.position("none"===_.get("transition")?0:_.get("speed")))},J.prep=function(i){function o(){return _.w=_.w||I.width(),_.w=_.mw&&_.mw<_.w?_.mw:_.w,_.w}function a(){return _.h=_.h||I.height(),_.h=_.mh&&_.mh<_.h?_.mh:_.h,_.h}if(U){var d,g="none"===_.get("transition")?0:_.get("speed");I.remove(),I=n(se,"LoadedContent").append(i),I.hide().appendTo(M.show()).css({width:o(),overflow:_.get("scrolling")?"auto":"hidden"}).css({height:a()}).prependTo(b),M.hide(),t(q).css({"float":"none"}),c(_.get("className")),d=function(){function i(){t.support.opacity===!1&&x[0].style.removeAttribute("filter")}var n,o,a=W.length;U&&(o=function(){clearTimeout(Q),L.hide(),u(ne),_.get("onComplete")},F.html(_.get("title")).show(),I.show(),a>1?("string"==typeof _.get("current")&&R.html(_.get("current").replace("{current}",A+1).replace("{total}",a)).show(),K[_.get("loop")||a-1>A?"show":"hide"]().html(_.get("next")),P[_.get("loop")||A?"show":"hide"]().html(_.get("previous")),ce(),_.get("preloading")&&t.each([h(-1),h(1)],function(){var i,n=W[this],o=new r(n,t.data(n,Y)),h=o.get("href");h&&s(o,h)&&(h=l(o,h),i=e.createElement("img"),i.src=h)})):O.hide(),_.get("iframe")?(n=_.get("createIframe"),_.get("scrolling")||(n.scrolling="no"),t(n).attr({src:_.get("href"),"class":Z+"Iframe"}).one("load",o).appendTo(I),ae.one(he,function(){n.src="//about:blank"}),_.get("fastIframe")&&t(n).trigger("load")):o(),"fade"===_.get("transition")?x.fadeTo(g,1,i):i())},"fade"===_.get("transition")?x.fadeTo(g,0,function(){J.position(0,d)}):J.position(g,d)}},J.next=function(){!$&&W[1]&&(_.get("loop")||W[A+1])&&(A=h(1),f(W[A]))},J.prev=function(){!$&&W[1]&&(_.get("loop")||A)&&(A=h(-1),f(W[A]))},J.close=function(){U&&!G&&(G=!0,U=!1,u(oe),_.get("onCleanup"),E.unbind("."+Z),v.fadeTo(_.get("fadeOut")||0,0),x.stop().fadeTo(_.get("fadeOut")||0,0,function(){x.hide(),v.hide(),u(he),I.remove(),setTimeout(function(){G=!1,u(re),_.get("onClosed")},1)}))},J.remove=function(){x&&(x.stop(),t[Y].close(),x.stop(!1,!0).remove(),v.remove(),G=!1,x=null,t("."+te).removeData(Y).removeClass(te),t(e).unbind("click."+Z).unbind("keydown."+Z))},J.element=function(){return t(_.el)},J.settings=X)})(jQuery,document,window);
    \ No newline at end of file
    diff --git a/htdocs/takepos/js/takepos.js b/htdocs/takepos/js/takepos.js
    new file mode 100644
    index 00000000000..062a3bb4e4a
    --- /dev/null
    +++ b/htdocs/takepos/js/takepos.js
    @@ -0,0 +1,15 @@
    +/* Copyright (C) 2018	Charles-FR BENKE		<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    diff --git a/htdocs/takepos/lib/takepos.lib.php b/htdocs/takepos/lib/takepos.lib.php
    new file mode 100644
    index 00000000000..691f118d2cb
    --- /dev/null
    +++ b/htdocs/takepos/lib/takepos.lib.php
    @@ -0,0 +1,58 @@
    +<?php
    +/* Copyright (C) 2018 SuperAdmin
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    takepos/lib/takepos.lib.php
    + * \ingroup takepos
    + * \brief   Library files with common functions for TakePos
    + */
    +
    +/**
    + * Prepare admin pages header
    + *
    + * @return array
    + */
    +function takeposAdminPrepareHead()
    +{
    +	global $langs, $conf;
    +
    +	$langs->load("cashdesk");
    +
    +	$h = 0;
    +	$head = array();
    +
    +	$head[$h][0] = dol_buildpath("/takepos/admin/setup.php", 1);
    +	$head[$h][1] = $langs->trans("Settings");
    +	$head[$h][2] = 'settings';
    +	$h++;
    +	$head[$h][0] = dol_buildpath("/takepos/admin/about.php", 1);
    +	$head[$h][1] = $langs->trans("About");
    +	$head[$h][2] = 'about';
    +	$h++;
    +
    +	// Show more tabs from modules
    +	// Entries must be declared in modules descriptor with line
    +	//$this->tabs = array(
    +	//	'entity:+tabname:Title:@takepos:/takepos/mypage.php?id=__ID__'
    +	//); // to add new tab
    +	//$this->tabs = array(
    +	//	'entity:-tabname:Title:@takepos:/takepos/mypage.php?id=__ID__'
    +	//); // to remove a tab
    +	complete_head_from_modules($conf, $langs, $object, $head, $h, 'takepos');
    +
    +	return $head;
    +}
    diff --git a/htdocs/takepos/modulebuilder.txt b/htdocs/takepos/modulebuilder.txt
    new file mode 100644
    index 00000000000..24ea0d6eac5
    --- /dev/null
    +++ b/htdocs/takepos/modulebuilder.txt
    @@ -0,0 +1,3 @@
    +# DO NOT DELETE THIS FILE MANUALLY
    +# File to flag module built using official module template.
    +# When this file is present into a module directory, you can edit it with the module builder tool. Use ModuleBuilder if you want to delete module. 
    \ No newline at end of file
    diff --git a/htdocs/takepos/pay.php b/htdocs/takepos/pay.php
    new file mode 100644
    index 00000000000..c0bfc35294a
    --- /dev/null
    +++ b/htdocs/takepos/pay.php
    @@ -0,0 +1,120 @@
    +<?php
    +/* Copyright (C) 2018	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +$_GET['theme']="md"; // Force theme. MD theme provides better look and feel to TakePOS
    +
    +require '../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
    +
    +$place = GETPOST('place','int');
    +
    +
    +/*
    + * View
    + */
    +
    +$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."facture where facnumber='(PROV-POS-".$place.")'";
    +$resql = $db->query($sql);
    +$row = $db->fetch_array ($resql);
    +$placeid=$row[0];
    +if (! $placeid) $placeid=0; // Developing error message with no lines
    +else{
    +	$invoice = new Facture($db);
    +	$invoice->fetch($placeid);
    +}
    +
    +top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
    +
    +$langs->loadLangs(array("main", "bills", "cashdesk"));
    +?>
    +<link rel="stylesheet" href="css/pos.css">
    +	<script>
    +	var received=0;
    +	function addreceived(price)
    +	{
    +	received+=parseFloat(price);
    +	$('#change1').html(received.toFixed(2));
    +	if (received><?php echo $invoice->total_ttc;?>)
    +		{
    +		var change=parseFloat(received-<?php echo $invoice->total_ttc;?>);
    +		$('#change2').html(change.toFixed(2));
    +		}
    +	}
    +
    +	function reset()
    +	{
    +		received=0;
    +		addreceived(0);
    +		$('#change2').html(received.toFixed(2));
    +	}
    +
    +	function Validate(payment){
    +        parent.$("#poslines").load("invoice.php?place=<?php echo $place;?>&action=valid&pay="+payment, function() {
    +            parent.$("#poslines").scrollTop(parent.$("#poslines")[0].scrollHeight);
    +            parent.$.colorbox.close();
    +        });
    +
    +	}
    +</script>
    +</head>
    +<body>
    +
    +<div style="position:absolute; top:2%; left:5%; height:36%; width:91%;">
    +<center>
    +<div style="width:40%; background-color:#222222; border-radius:8px; margin-bottom: 4px;">
    +<center><span style='font-family: digital; font-size: 280%;'><font color="white"><?php echo $langs->trans('TotalTTC');?>: </font><font color="red"><span id="totaldisplay"><?php echo price($invoice->total_ttc, 1, '', 1, - 1, - 1, $conf->currency) ?></span></span></center>
    +</div>
    +<div style="width:40%; background-color:#333333; border-radius:8px; margin-bottom: 4px;">
    +<center><span style='font-family: digital; font-size: 250%;'><font color="white"><?php echo $langs->trans("AlreadyPaid"); ?>: </font><font color="red"><span id="change1"><?php echo price(0) ?></span></center>
    +</div>
    +<div style="width:40%; background-color:#333333; border-radius:8px; margin-bottom: 4px;">
    +<center><span style='font-family: digital; font-size: 250%;'><font color="white"><?php echo $langs->trans("Change"); ?>: </font><font color="red"><span id="change2"><?php echo price(0) ?></span></span></center>
    +</div>
    +</center>
    +</div>
    +
    +<div style="position:absolute; top:40%; left:5%; height:55%; width:91%;">
    +<button type="button" class="calcbutton" onclick="addreceived(10);">10</button>
    +<button type="button" class="calcbutton" onclick="addreceived(20);">20</button>
    +<button type="button" class="calcbutton" onclick="addreceived(50);">50</button>
    +<button type="button" class="calcbutton2" onclick="Validate('cash');"><?php echo $langs->trans("Cash"); ?></button>
    +<button type="button" class="calcbutton" onclick="addreceived(1);">1</button>
    +<button type="button" class="calcbutton" onclick="addreceived(2);">2</button>
    +<button type="button" class="calcbutton" onclick="addreceived(5);">5</button>
    +<button type="button" class="calcbutton2" onclick="Validate('card');"><?php echo $langs->trans("PaymentTypeCB"); ?></button>
    +<button type="button" class="calcbutton" onclick="addreceived(0.10);">0.10</button>
    +<button type="button" class="calcbutton" onclick="addreceived(0.20);">0.20</button>
    +<button type="button" class="calcbutton" onclick="addreceived(0.50);">0.50</button>
    +<button type="button" class="calcbutton2" onclick="printclick();"><span id="printtext"><?php echo $langs->trans("GoBack"); ?></span></button>
    +<button type="button" class="calcbutton" onclick="addreceived(0.01);">0.01</button>
    +<button type="button" class="calcbutton" onclick="addreceived(0.02);">0.02</button>
    +<button type="button" class="calcbutton" onclick="addreceived(0.05);">0.05</button>
    +<button type="button" class="calcbutton2" onclick="reset();"><span style='font-size: 150%;'>C</span></button>
    +</div>
    +
    +</body>
    +</html>
    \ No newline at end of file
    diff --git a/htdocs/takepos/receipt.php b/htdocs/takepos/receipt.php
    new file mode 100644
    index 00000000000..d5c4ceba0a1
    --- /dev/null
    +++ b/htdocs/takepos/receipt.php
    @@ -0,0 +1,106 @@
    +<?php
    +/* Copyright (C) 2007-2008 Jeremie Ollivier    <jeremie.o@laposte.net>
    + * Copyright (C) 2011      Laurent Destailleur <eldy@users.sourceforge.net>
    + * Copyright (C) 2012      Marcos García       <marcosgdf@gmail.com>
    + * Copyright (C) 2018      Andreu Bisquerra    <jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +require '../main.inc.php';	// Load $user and permissions
    +include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
    +
    +$langs->loadLangs(array("main", "cashdesk"));
    +
    +/*
    + * View
    + */
    +
    +top_httphead('text/html');
    +
    +$facid=GETPOST('facid','int');
    +$place=GETPOST('place','int');
    +if ($place>0){
    +    $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."facture where facnumber='(PROV-POS-".$place.")'";
    +    $resql = $db->query($sql);
    +    $row = $db->fetch_array ($resql);
    +    $facid=$row[0];
    +}
    +$object=new Facture($db);
    +$object->fetch($facid);
    +
    +// IMPORTANT: This file is sended to 'Takepos Printing' application. Keep basic file. No external files as css, js... If you need images use absolut path.
    +?>
    +<html>
    +<body>
    +<center>
    +<font size="4">
    +<?php echo $mysoc->name; ?>
    +</font>
    +</center>
    +<br>
    +<p align="left">
    +<?php print dol_nl2br(dol_format_address($mysoc)); ?>
    +</p>
    +<p align="right">
    +<?php
    +print $langs->trans('Date')." ".dol_print_date($object->date, 'day').'<br>';
    +if ($mysoc->country_code == 'ES') print "Factura simplificada ";
    +print $object->ref;
    +?>
    +</p>
    +<br>
    +
    +<table width="100%">
    +    <thead>
    +	<tr>
    +        <th align="center"><?php print $langs->trans("Label"); ?></th>
    +        <th align="right"><?php print $langs->trans("Qty"); ?></th>
    +        <th align="right"><?php print $langs->trans("TotalTTC"); ?></th>
    +	</tr>
    +    </thead>
    +    <tbody>
    +    <?php
    +    foreach ($object->lines as $line)
    +    {
    +    ?>
    +    <tr>
    +        <td><?php echo $line->product_label;?></td>
    +        <td align="right"><?php echo $line->qty;?></td>
    +        <td align="right"><?php echo price($line->total_ttc);?></td>
    +    </tr>
    +    <?php
    +    }
    +    ?>
    +    </tbody>
    +</table>
    +<br>
    +<table align="right">
    +<tr>
    +    <th align="right"><?php echo $langs->trans("TotalHT");?></th>
    +    <td align="right"><?php echo price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency)."\n";?></td>
    +</tr>
    +<tr>
    +    <th align="right"><?php echo $langs->trans("TotalVAT").'</th><td align="right">'.price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency)."\n";?></td>
    +</tr>
    +<tr>
    +    <th align="right"><?php echo ''.$langs->trans("TotalTTC").'</th><td align="right">'.price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency)."\n";?></td>
    +</tr>
    +</table>
    +
    +<script type="text/javascript">
    +    window.print();
    +</script>
    +</body>
    +</html>
    diff --git a/htdocs/takepos/takepos.php b/htdocs/takepos/takepos.php
    new file mode 100644
    index 00000000000..8dec143bffe
    --- /dev/null
    +++ b/htdocs/takepos/takepos.php
    @@ -0,0 +1,403 @@
    +<?php
    +/* Copyright (C) 2018	Andreu Bisquerra	<jove@bisquerra.com>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +//if (! defined('NOREQUIREUSER'))	define('NOREQUIREUSER','1');	// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIREDB'))		define('NOREQUIREDB','1');		// Not disabled cause need to load personalized language
    +//if (! defined('NOREQUIRESOC'))		define('NOREQUIRESOC','1');
    +//if (! defined('NOREQUIRETRAN'))		define('NOREQUIRETRAN','1');
    +if (! defined('NOCSRFCHECK'))		define('NOCSRFCHECK','1');
    +if (! defined('NOTOKENRENEWAL'))	define('NOTOKENRENEWAL','1');
    +if (! defined('NOREQUIREMENU'))		define('NOREQUIREMENU','1');
    +if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
    +if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
    +
    +$_GET['theme']="md"; // Force theme. MD theme provides better look and feel to TakePOS
    +
    +require '../main.inc.php';	// Load $user and permissions
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
    +
    +$place = GETPOST('place','int');
    +if ($place=="") $place="0";
    +$action = GETPOST('action','alpha');
    +
    +$langs->loadLangs(array("bills","orders","commercial","cashdesk"));
    +
    +
    +/*
    + * View
    + */
    +
    +// Title
    +$title='TakePOS - Dolibarr '.DOL_VERSION;
    +if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title='TakePOS - '.$conf->global->MAIN_APPLICATION_TITLE;
    +top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
    +
    +?>
    +<link rel="stylesheet" href="css/pos.css?a=xxx">
    +<script type="text/javascript" src="js/takepos.js" ></script>
    +<link rel="stylesheet" href="css/colorbox.css" type="text/css" media="screen" />
    +<script type="text/javascript" src="js/jquery.colorbox-min.js"></script>
    +<script language="javascript">
    +<?php
    +$categorie = new Categorie($db);
    +$categories = $categorie->get_full_arbo('product');
    +?>
    +var categories = JSON.parse( '<?php echo json_encode($categories);?>' );
    +var currentcat;
    +var pageproducts=0;
    +var pagecategories=0;
    +var place="<?php echo $place;?>";
    +var editaction="qty";
    +var editnumber="";
    +function PrintCategories(first){
    +	for (i = 0; i < 14; i++) {
    +		if (typeof (categories[parseInt(i)+parseInt(first)]) == "undefined") break;
    +		$("#catdesc"+i).text(categories[parseInt(i)+parseInt(first)]['label']);
    +        $("#catimg"+i).attr("src","genimg/?query=cat&w=55&h=50&id="+categories[parseInt(i)+parseInt(first)]['rowid']);
    +        $("#catdiv"+i).data("rowid",categories[parseInt(i)+parseInt(first)]['rowid']);
    +	}
    +}
    +
    +function MoreCategories(moreorless){
    +	if (moreorless=="more"){
    +		$('#catimg15').animate({opacity: '0.5'}, 100);
    +		$('#catimg15').animate({opacity: '1'}, 100);
    +		pagecategories=pagecategories+1;
    +	}
    +	if (moreorless=="less"){
    +		$('#catimg14').animate({opacity: '0.5'}, 100);
    +		$('#catimg14').animate({opacity: '1'}, 100);
    +		if (pagecategories==0) return; //Return if no less pages
    +		pagecategories=pagecategories-1;
    +	}
    +	if (typeof (categories[14*pagecategories] && moreorless=="more") == "undefined"){ // Return if no more pages
    +		pagecategories=pagecategories-1;
    +		return;
    +	}
    +	for (i = 0; i < 14; i++) {
    +		if (typeof (categories[i+(14*pagecategories)]) == "undefined"){
    +				$("#catdesc"+i).text("");
    +				$("#catimg"+i).attr("src","");
    +				continue;
    +			}
    +		$("#catdesc"+i).text(categories[i+(14*pagecategories)]['label']);
    +        $("#catimg"+i).attr("src","genimg/?query=cat&w=55&h=50&id="+categories[i+(14*pagecategories)]['rowid']);
    +        $("#catdiv"+i).data("rowid",categories[i+(14*pagecategories)]['rowid']);
    +	}
    +}
    +
    +function LoadProducts(position){
    +    $('#catimg'+position).animate({opacity: '0.5'}, 100);
    +	$('#catimg'+position).animate({opacity: '1'}, 100);
    +	currentcat=$('#catdiv'+position).data('rowid');
    +    if (currentcat=="") return;
    +	pageproducts=0;
    +	$.getJSON('./ajax.php?action=getProducts&category='+currentcat, function(data) {
    +		for (i = 0; i < 30; i++) {
    +			if (typeof (data[i]) == "undefined"){
    +				$("#prodesc"+i).text("");
    +				$("#proimg"+i).attr("src","");
    +                $("#prodiv"+i).data("rowid","");
    +				continue;
    +			}
    +			$("#prodesc"+i).text(data[parseInt(i)]['label']);
    +			$("#proimg"+i).attr("src","genimg/?query=pro&w=55&h=50&id="+data[i]['id']);
    +			$("#prodiv"+i).data("rowid",data[i]['id']);
    +		}
    +	});
    +}
    +
    +function MoreProducts(moreorless){
    +	if (moreorless=="more"){
    +		$('#proimg31').animate({opacity: '0.5'}, 100);
    +		$('#proimg31').animate({opacity: '1'}, 100);
    +		pageproducts=pageproducts+1;
    +	}
    +	if (moreorless=="less"){
    +		$('#proimg30').animate({opacity: '0.5'}, 100);
    +		$('#proimg30').animate({opacity: '1'}, 100);
    +		if (pageproducts==0) return; //Return if no less pages
    +		pageproducts=pageproducts-1;
    +	}
    +	$.getJSON('./ajax.php?action=getProducts&category='+currentcat, function(data) {
    +		if (typeof (data[(30*pageproducts)]) == "undefined" && moreorless=="more"){ // Return if no more pages
    +			pageproducts=pageproducts-1;
    +			return;
    +		}
    +		for (i = 0; i < 30; i++) {
    +			if (typeof (data[i+(30*pageproducts)]) == "undefined"){
    +				$("#prodesc"+i).text("");
    +				$("#proimg"+i).attr("src","");
    +                $("#prodiv"+i).data("rowid","");
    +				continue;
    +			}
    +			$("#prodesc"+i).text(data[parseInt(i+(30*pageproducts))]['label']);
    +			$("#proimg"+i).attr("src","genimg/?query=pro&w=55&h=50&id="+data[i+(30*pageproducts)]['id']);
    +			$("#prodiv"+i).data("rowid",data[i+(30*pageproducts)]['id']);
    +		}
    +	});
    +}
    +
    +function ClickProduct(position){
    +    $('#proimg'+position).animate({opacity: '0.5'}, 100);
    +	$('#proimg'+position).animate({opacity: '1'}, 100);
    +	idproduct=$('#prodiv'+position).data('rowid');
    +    if (idproduct=="") return;
    +	$("#poslines").load("invoice.php?action=addline&place="+place+"&idproduct="+idproduct, function() {
    +		$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +	});
    +
    +}
    +
    +function deleteline(){
    +	$("#poslines").load("invoice.php?action=deleteline&place="+place+"&idline="+selectedline, function() {
    +		$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +	});
    +}
    +
    +function Customer(){
    +	$.colorbox({href:"customers.php?nomassaction=1&place="+place, width:"90%", height:"80%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("Customer");?>"});
    +}
    +
    +function CloseBill(){
    +	$.colorbox({href:"pay.php?place="+place, width:"80%", height:"90%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("CloseBill");?>"});
    +}
    +
    +function Floors(){
    +	$.colorbox({href:"floors.php?place="+place, width:"90%", height:"90%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("Floors");?>"});
    +}
    +
    +function FreeZone(){
    +	$.colorbox({href:"freezone.php?place="+place, onClosed: function () { Refresh(); },width:"80%", height:"30%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("FreeZone");?>"});
    +}
    +
    +function Refresh(){
    +	$("#poslines").load("invoice.php?place="+place, function() {
    +		$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +	});
    +}
    +
    +function Search(){
    +	$("#poslines").load("invoice.php?action=search&place="+place, function() {
    +		$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +	});
    +}
    +
    +function Search2(){
    +	pageproducts=0;
    +	$.getJSON('./ajax.php?action=search&term='+$('#search').val(), function(data) {
    +		for (i = 0; i < 30; i++) {
    +			if (typeof (data[i]) == "undefined"){
    +				$("#prodesc"+i).text("");
    +				$("#proimg"+i).attr("src","");
    +                $("#prodiv"+i).data("rowid","");
    +				continue;
    +			}
    +			$("#prodesc"+i).text(data[parseInt(i)]['label']);
    +			$("#proimg"+i).attr("src","genimg/?query=pro&w=55&h=50&id="+data[i]['rowid']);
    +			$("#prodiv"+i).data("rowid",data[i]['rowid']);
    +		}
    +	});
    +}
    +
    +function Edit(number){
    +    var text=selectedtext+"<br> ";
    +    if (number=='c'){
    +        editnumber="";
    +        Refresh();
    +        return;
    +    }
    +    else if (number=='qty'){
    +        if (editaction=='qty' && editnumber!=""){
    +            $("#poslines").load("invoice.php?action=updateqty&place="+place+"&idline="+selectedline+"&number="+editnumber, function() {
    +                editnumber="";
    +                $('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +                $("#qty").html("<?php echo $langs->trans("Qty"); ?>");
    +            });
    +            return;
    +        }
    +        else {
    +            editaction="qty";
    +        }
    +    }
    +    else if (number=='p'){
    +        if (editaction=='p' && editnumber!=""){
    +            $("#poslines").load("invoice.php?action=updateprice&place="+place+"&idline="+selectedline+"&number="+editnumber, function() {
    +                editnumber="";
    +                $('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +                $("#price").html("<?php echo $langs->trans("Price"); ?>");
    +            });
    +            return;
    +        }
    +        else {
    +            editaction="p";
    +        }
    +    }
    +    else if (number=='r'){
    +        if (editaction=='r' && editnumber!=""){
    +            $("#poslines").load("invoice.php?action=updatereduction&place="+place+"&idline="+selectedline+"&number="+editnumber, function() {
    +                editnumber="";
    +                $('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +                $("#reduction").html("<?php echo $langs->trans("ReductionShort"); ?>");
    +            });
    +            return;
    +        }
    +        else {
    +            editaction="r";
    +        }
    +    }
    +    else {
    +        editnumber=editnumber+number;
    +    }
    +    if (editaction=='qty'){
    +        text=text+"<?php echo $langs->trans("Modify")." -> ".$langs->trans("Qty").": "; ?>";
    +        $("#qty").html("OK");
    +        $("#price").html("<?php echo $langs->trans("Price"); ?>");
    +        $("#reduction").html("<?php echo $langs->trans("ReductionShort"); ?>");
    +    }
    +    if (editaction=='p'){
    +        text=text+"<?php echo $langs->trans("Modify")." -> ".$langs->trans("Price").": "; ?>";
    +        $("#qty").html("<?php echo $langs->trans("Qty"); ?>");
    +        $("#price").html("OK");
    +        $("#reduction").html("<?php echo $langs->trans("ReductionShort"); ?>");
    +    }
    +    if (editaction=='r'){
    +        text=text+"<?php echo $langs->trans("Modify")." -> ".$langs->trans("ReductionShort").": "; ?>";
    +        $("#qty").html("<?php echo $langs->trans("Qty"); ?>");
    +        $("#price").html("<?php echo $langs->trans("Price"); ?>");
    +        $("#reduction").html("OK");
    +    }
    +    $('#'+selectedline).find("td:first").html(text+editnumber);
    +}
    +
    +function TakeposPrintingOrder(){
    +	$("#poslines").load("invoice.php?action=order&place="+place, function() {
    +		$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
    +	});
    +}
    +
    +$( document ).ready(function() {
    +    PrintCategories(0);
    +	LoadProducts(0);
    +	Refresh();
    +});
    +</script>
    +
    +<body style="overflow: hidden; background-color:#E8E8E8;">
    +
    +<div id="poslines" style="position:absolute; top:2%; left:0.5%; height:36%; width:31%; overflow: auto;">
    +</div>
    +
    +<div style="position:absolute; top:1%; left:32.5%; height:37%; width:32.5%;">
    +    <button type="button" class="calcbutton" onclick="Edit(7);">7</button>
    +    <button type="button" class="calcbutton" onclick="Edit(8);">8</button>
    +    <button type="button" class="calcbutton" onclick="Edit(9);">9</button>
    +    <button type="button" id="qty" class="calcbutton2" onclick="Edit('qty');"><?php echo $langs->trans("Qty"); ?></button>
    +    <button type="button" class="calcbutton" onclick="Edit(4);">4</button>
    +    <button type="button" class="calcbutton" onclick="Edit(5);">5</button>
    +    <button type="button" class="calcbutton" onclick="Edit(6);">6</button>
    +    <button type="button" id="price" class="calcbutton2" onclick="Edit('p');"><?php echo $langs->trans("Price"); ?></button>
    +    <button type="button" class="calcbutton" onclick="Edit(1);">1</button>
    +    <button type="button" class="calcbutton" onclick="Edit(2);">2</button>
    +    <button type="button" class="calcbutton" onclick="Edit(3);">3</button>
    +    <button type="button" id="reduction" class="calcbutton2" onclick="Edit('r');"><?php echo $langs->trans("ReductionShort"); ?></button>
    +    <button type="button" class="calcbutton" onclick="Edit(0);">0</button>
    +    <button type="button" class="calcbutton" onclick="Edit('.');">.</button>
    +    <button type="button" class="calcbutton" onclick="Edit('c');">C</button>
    +    <button type="button" class="calcbutton2" id="delete" style="color: red;" onclick="deleteline();"><b>X</b></button>
    +</div>
    +
    +<?php
    +// User menu and external TakePOS modules
    +$menus = array();
    +$r=0;
    +$menus[$r++]=array('title'=>$langs->trans("SearchProduct"),
    +					'action'=>'Search();');
    +$menus[$r++]=array('title'=>$langs->trans("FreeZone"),
    +                   'action'=>'FreeZone();');
    +$menus[$r++]=array('title'=>$langs->trans("Customer"),
    +					'action'=>'Customer();');
    +$menus[$r++]=array('title'=>$langs->trans("BackOffice"),
    +                   'action'=>'window.open(\''.DOL_URL_ROOT.'\', \'backoffice\');');
    +$menus[$r++]=array('title'=>$langs->trans("ValidateBill"),
    +					'action'=>'CloseBill();');
    +$menus[$r++]=array('title'=>$langs->trans("Logout"),
    +                   'action'=>'window.location.href=\''.DOL_URL_ROOT.'/user/logout.php\';');
    +if($conf->global->TAKEPOS_BAR_RESTAURANT){
    +	$menus[$r++]=array('title'=>$langs->trans("Floors"),
    +					'action'=>'Floors();');
    +	if ($conf->global->TAKEPOS_ORDER_PRINTERS){
    +		$menus[$r++]=array('title'=>$langs->trans("Order"),
    +						'action'=>'TakeposPrintingOrder();');
    +	}
    +}
    +?>
    +<div style="position:absolute; top:1%; left:65.5%; height:37%; width:32.5%;">
    +<?php
    +foreach($menus as $menu) {
    +    echo '<button type="button" class="actionbutton" onclick="'.$menu['action'].'">'.$menu['title'].'</button>';
    +}
    +?>
    +</div>
    +
    +<div style="position:absolute; top:39%; left:0.3%; height:59%; width:32%;">
    +	<?php
    +	$count=0;
    +	while ($count<16)
    +	{
    +	?>
    +	<div class='wrapper' <?php if ($count==14) echo 'onclick="MoreCategories(\'less\');"'; else if ($count==15) echo 'onclick="MoreCategories(\'more\');"'; else echo 'onclick="LoadProducts('.$count.');"';?> id='catdiv<?php echo $count;?>'>
    +		<img class='imgwrapper' <?php if ($count==14) echo 'src="img/arrow-prev-top.png"'; if ($count==15) echo 'src="img/arrow-next-top.png"';?> width="98%" id='catimg<?php echo $count;?>'/>
    +		<div class='description'>
    +			<div class='description_content' id='catdesc<?php echo $count;?>'></div>
    +		</div>
    +	</div>
    +	<?php
    +    $count++;
    +	}
    +	?>
    +</div>
    +
    +<div style="position:absolute; top:39%; left:32%; height:58%; width:72%;">
    +<?php
    +$count=0;
    +while ($count<32)
    +	{
    +	?>
    +	<div class='wrapper2' id='prodiv<?php echo $count;?>' <?php if ($count==30) {?> onclick="MoreProducts('less');" <?php } if ($count==31) {?> onclick="MoreProducts('more');" <?php } else echo 'onclick="ClickProduct('.$count.');"';?>>
    +		<img class='imgwrapper' <?php if ($count==30) echo 'src="img/arrow-prev-top.png"'; if ($count==31) echo 'src="img/arrow-next-top.png"';?> width="95%" id='proimg<?php echo $count;?>'/>
    +		<div class='description'>
    +			<div class='description_content' id='prodesc<?php echo $count;?>'></div>
    +		</div>
    +	</div>
    +	<?php
    +	$count++;
    +	}
    +?>
    +</div>
    +
    +</body>
    +<?php
    +
    +llxFooter();
    +
    +$db->close();
    +
    +
    +
    diff --git a/htdocs/theme/common/octicons/build/data.json b/htdocs/theme/common/octicons/build/data.json
    index 41fa0740b8a..c70ceda6631 100644
    --- a/htdocs/theme/common/octicons/build/data.json
    +++ b/htdocs/theme/common/octicons/build/data.json
    @@ -1 +1 @@
    -{"alert":{"name":"alert","figma":{"id":"0:5","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["warning","triangle","exclamation","point"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z\"/>"},"arrow-down":{"name":"arrow-down","figma":{"id":"0:8","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 7V3H3v4H0l5 6 5-6H7z\"/>"},"arrow-left":{"name":"arrow-left","figma":{"id":"0:10","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 3L0 8l6 5v-3h4V6H6V3z\"/>"},"arrow-right":{"name":"arrow-right","figma":{"id":"0:12","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 8L4 3v3H0v4h4v3l6-5z\"/>"},"arrow-up":{"name":"arrow-up","figma":{"id":"0:14","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 3L0 9h3v4h4V9h3L5 3z\"/>"},"arrow-small-down":{"name":"arrow-small-down","figma":{"id":"0:16","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 7V5H2v2H0l3 4 3-4H4z\"/>"},"arrow-small-left":{"name":"arrow-small-left","figma":{"id":"0:18","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 7V5L0 8l4 3V9h2V7H4z\"/>"},"arrow-small-right":{"name":"arrow-small-right","figma":{"id":"0:20","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 8L2 5v2H0v2h2v2l4-3z\"/>"},"arrow-small-up":{"name":"arrow-small-up","figma":{"id":"0:22","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 5L0 9h2v2h2V9h2L3 5z\"/>"},"beaker":{"name":"beaker","figma":{"id":"0:26","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["experiment","labs","experimental","feature","test","science","education","study","development","testing"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14.84 14.59L11.46 7V3h1V2h-9v1h1v4l-3.37 7.59A1 1 0 0 0 2 16h11.94c.72 0 1.2-.75.91-1.41h-.01zM4.21 10l1.25-3V3h5v4l1.25 3h-7.5zm4.25-2h1v1h-1V8zm-1-1h-1V6h1v1zm0-3h1v1h-1V4zm0-3h-1V0h1v1z\"/>"},"bell":{"name":"bell","figma":{"id":"0:34","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["notification"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 12v1H0v-1l.73-.58c.77-.77.81-2.55 1.19-4.42C2.69 3.23 6 2 6 2c0-.55.45-1 1-1s1 .45 1 1c0 0 3.39 1.23 4.16 5 .38 1.88.42 3.66 1.19 4.42l.66.58H14zm-7 4c1.11 0 2-.89 2-2H5c0 1.11.89 2 2 2z\"/>"},"bold":{"name":"bold","figma":{"id":"0:38","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["markdown","bold","text"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1 2h3.83c2.48 0 4.3.75 4.3 2.95 0 1.14-.63 2.23-1.67 2.61v.06c1.33.3 2.3 1.23 2.3 2.86 0 2.39-1.97 3.52-4.61 3.52H1V2zm3.66 4.95c1.67 0 2.38-.66 2.38-1.69 0-1.17-.78-1.61-2.34-1.61H3.13v3.3h1.53zm.27 5.39c1.77 0 2.75-.64 2.75-1.98 0-1.27-.95-1.81-2.75-1.81h-1.8v3.8h1.8v-.01z\"/>"},"book":{"name":"book","figma":{"id":"0:43","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","wiki","readme"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z\"/>"},"bookmark":{"name":"bookmark","figma":{"id":"0:54","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["tab","star"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10 16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6 3.12 7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7 2.16 2.3.03c.23 0 .27.08.09.23h.01z\"/>"},"briefcase":{"name":"briefcase","figma":{"id":"0:58","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["suitcase","business"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 4V3c0-.55-.45-1-1-1H6c-.55 0-1 .45-1 1v1H1c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1H9zM6 3h2v1H6V3zm7 6H8v1H6V9H1V5h1v3h10V5h1v4z\"/>"},"broadcast":{"name":"broadcast","figma":{"id":"0:63","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["rss","radio","signal"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 9H8c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1H7c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1H6c-.55 0-1 .45-1 1v2h1v3c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-3h1v-2c0-.55-.45-1-1-1zM7 7h1v1H7V7zm2 4H8v4H7v-4H6v-1h3v1zm2.09-3.5c0-1.98-1.61-3.59-3.59-3.59A3.593 3.593 0 0 0 4 8.31v1.98c-.61-.77-1-1.73-1-2.8 0-2.48 2.02-4.5 4.5-4.5S12 5.01 12 7.49c0 1.06-.39 2.03-1 2.8V8.31c.06-.27.09-.53.09-.81zm3.91 0c0 2.88-1.63 5.38-4 6.63v-1.05a6.553 6.553 0 0 0 3.09-5.58A6.59 6.59 0 0 0 7.5.91 6.59 6.59 0 0 0 .91 7.5c0 2.36 1.23 4.42 3.09 5.58v1.05A7.497 7.497 0 0 1 7.5 0C11.64 0 15 3.36 15 7.5z\"/>"},"browser":{"name":"browser","figma":{"id":"0:70","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["window","web"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 3h1v1H5V3zM3 3h1v1H3V3zM1 3h1v1H1V3zm12 10H1V5h12v8zm0-9H7V3h6v1zm1-1c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V3z\"/>"},"bug":{"name":"bug","figma":{"id":"0:78","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["insect","issue"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.17 10h3V9h-3V8l3.17-1.03-.34-.94-2.83.97V6c0-.55-.45-1-1-1V4c0-.48-.36-.88-.83-.97L10.37 2h1.8V1h-2.2l-2 2h-.59L5.37 1h-2.2v1h1.8L6 3.03c-.47.09-.83.48-.83.97v1c-.55 0-1 .45-1 1v1l-2.83-.97-.34.94L4.17 8v1h-3v1h3v1L1 12.03l.34.94L4.17 12v1c0 .55.45 1 1 1h1l1-1V6h1v7l1 1h1c.55 0 1-.45 1-1v-1l2.83.97.34-.94L11.17 11v-1zm-2-5h-3V4h3v1z\"/>"},"calendar":{"name":"calendar","figma":{"id":"0:82","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["time","day","month","year","date","appointment"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 2h-1v1.5c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5V2H6v1.5c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5V2H2c-.55 0-1 .45-1 1v11c0 .55.45 1 1 1h11c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 12H2V5h11v9zM5 3H4V1h1v2zm6 0h-1V1h1v2zM6 7H5V6h1v1zm2 0H7V6h1v1zm2 0H9V6h1v1zm2 0h-1V6h1v1zM4 9H3V8h1v1zm2 0H5V8h1v1zm2 0H7V8h1v1zm2 0H9V8h1v1zm2 0h-1V8h1v1zm-8 2H3v-1h1v1zm2 0H5v-1h1v1zm2 0H7v-1h1v1zm2 0H9v-1h1v1zm2 0h-1v-1h1v1zm-8 2H3v-1h1v1zm2 0H5v-1h1v1zm2 0H7v-1h1v1zm2 0H9v-1h1v1z\"/>"},"check":{"name":"check","figma":{"id":"0:104","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["mark","yes","confirm","accept","ok","success"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 5.5l-8 8-4-4L1.5 8 4 10.5 10.5 4 12 5.5z\"/>"},"checklist":{"name":"checklist","figma":{"id":"0:108","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["todo","tasks"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 8.5l-6 6-3-3L8.5 10l1.5 1.5L14.5 7 16 8.5zM5.7 12.2l.8.8H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h7c.55 0 1 .45 1 1v6.5l-.8-.8c-.39-.39-1.03-.39-1.42 0L5.7 10.8a.996.996 0 0 0 0 1.41v-.01zM4 4h5V3H4v1zm0 2h5V5H4v1zm0 2h3V7H4v1zM3 9H2v1h1V9zm0-2H2v1h1V7zm0-2H2v1h1V5zm0-2H2v1h1V3z\"/>"},"chevron-down":{"name":"chevron-down","figma":{"id":"0:117","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 11.5l-5-5L1.5 5 5 8.75 8.5 5 10 6.5l-5 5z\"/>"},"chevron-left":{"name":"chevron-left","figma":{"id":"0:119","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 3l1.5 1.5L3.75 8l3.75 3.5L6 13 1 8l5-5z\"/>"},"chevron-right":{"name":"chevron-right","figma":{"id":"0:121","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z\"/>"},"chevron-up":{"name":"chevron-up","figma":{"id":"0:123","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 10l-1.5 1.5L5 7.75 1.5 11.5 0 10l5-5 5 5z\"/>"},"circle-slash":{"name":"circle-slash","figma":{"id":"0:127","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["no","deny","fail","failure","error","bad"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm0 1.3c1.3 0 2.5.44 3.47 1.17l-8 8A5.755 5.755 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zm0 11.41c-1.3 0-2.5-.44-3.47-1.17l8-8c.73.97 1.17 2.17 1.17 3.47 0 3.14-2.56 5.7-5.7 5.7z\"/>"},"circuit-board":{"name":"circuit-board","figma":{"id":"0:132","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["developer","hardware","electricity"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 5c0-.55.45-1 1-1s1 .45 1 1-.45 1-1 1-1-.45-1-1zm8 0c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zm0 6c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zm2-10H5v2.17c.36.19.64.47.83.83h2.34c.42-.78 1.33-1.28 2.34-1.05.75.19 1.36.8 1.53 1.55.31 1.38-.72 2.59-2.05 2.59-.8 0-1.48-.44-1.83-1.09H5.83c-.42.8-1.33 1.28-2.34 1.03-.73-.17-1.34-.78-1.52-1.52C1.72 4.49 2.2 3.59 3 3.17V1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1l5-5h2.17c.42-.78 1.33-1.28 2.34-1.05.75.19 1.36.8 1.53 1.55.31 1.38-.72 2.59-2.05 2.59-.8 0-1.48-.44-1.83-1.09H6.99L4 15h9c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1z\"/>"},"clippy":{"name":"clippy","figma":{"id":"0:138","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["copy","paste","save","capture","clipboard"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z\"/>"},"clock":{"name":"clock","figma":{"id":"0:147","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["time","hour","minute","second","watch"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 8h3v2H7c-.55 0-1-.45-1-1V4h2v4zM7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7z\"/>"},"cloud-download":{"name":"cloud-download","figma":{"id":"0:152","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save","install","get"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 12h2l-3 3-3-3h2V7h2v5zm3-8c0-.44-.91-3-4.5-3C5.08 1 3 2.92 3 5 1.02 5 0 6.52 0 8c0 1.53 1 3 3 3h3V9.7H3C1.38 9.7 1.3 8.28 1.3 8c0-.17.05-1.7 1.7-1.7h1.3V5c0-1.39 1.56-2.7 3.2-2.7 2.55 0 3.13 1.55 3.2 1.8v1.2H12c.81 0 2.7.22 2.7 2.2 0 2.09-2.25 2.2-2.7 2.2h-2V11h2c2.08 0 4-1.16 4-3.5C16 5.06 14.08 4 12 4z\"/>"},"cloud-upload":{"name":"cloud-upload","figma":{"id":"0:156","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["put","export"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 9H5l3-3 3 3H9v5H7V9zm5-4c0-.44-.91-3-4.5-3C5.08 2 3 3.92 3 6 1.02 6 0 7.52 0 9c0 1.53 1 3 3 3h3v-1.3H3c-1.62 0-1.7-1.42-1.7-1.7 0-.17.05-1.7 1.7-1.7h1.3V6c0-1.39 1.56-2.7 3.2-2.7 2.55 0 3.13 1.55 3.2 1.8v1.2H12c.81 0 2.7.22 2.7 2.2 0 2.09-2.25 2.2-2.7 2.2h-2V12h2c2.08 0 4-1.16 4-3.5C16 6.06 14.08 5 12 5z\"/>"},"code":{"name":"code","figma":{"id":"0:160","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["brackets"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z\"/>"},"comment-discussion":{"name":"comment-discussion","figma":{"id":"0:164","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["converse","talk"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 1H6c-.55 0-1 .45-1 1v2H1c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h1v3l3-3h4c.55 0 1-.45 1-1V9h1l3 3V9h1c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zM9 11H4.5L3 12.5V11H1V5h4v3c0 .55.45 1 1 1h3v2zm6-3h-2v1.5L11.5 8H6V2h9v6z\"/>"},"comment":{"name":"comment","figma":{"id":"0:169","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["speak","bubble"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 1H2c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h2v3.5L7.5 11H14c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 9H7l-2 2v-2H2V2h12v8z\"/>"},"credit-card":{"name":"credit-card","figma":{"id":"0:173","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["money","billing","payments","transactions"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 9H2V8h10v1zm4-6v9c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h14c.55 0 1 .45 1 1zm-1 3H1v6h14V6zm0-3H1v1h14V3zm-9 7H2v1h4v-1z\"/>"},"dash":{"name":"dash","figma":{"id":"0:178","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hyphen","range"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 7v2h8V7H0z\"/>"},"dashboard":{"name":"dashboard","figma":{"id":"0:182","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["speed","dial"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 5H8V4h1v1zm4 3h-1v1h1V8zM6 5H5v1h1V5zM5 8H4v1h1V8zm11-5.5l-.5-.5L9 7c-.06-.02-1 0-1 0-.55 0-1 .45-1 1v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-.92l6-5.58zm-1.59 4.09c.19.61.3 1.25.3 1.91 0 3.42-2.78 6.2-6.2 6.2-3.42 0-6.21-2.78-6.21-6.2 0-3.42 2.78-6.2 6.2-6.2 1.2 0 2.31.34 3.27.94l.94-.94A7.459 7.459 0 0 0 8.51 1C4.36 1 1 4.36 1 8.5 1 12.64 4.36 16 8.5 16c4.14 0 7.5-3.36 7.5-7.5 0-1.03-.2-2.02-.59-2.91l-1 1z\"/>"},"database":{"name":"database","figma":{"id":"0:190","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["disks","data"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 15c-3.31 0-6-.9-6-2v-2c0-.17.09-.34.21-.5.67.86 3 1.5 5.79 1.5s5.12-.64 5.79-1.5c.13.16.21.33.21.5v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V7c0-.11.04-.21.09-.31.03-.06.07-.13.12-.19C.88 7.36 3.21 8 6 8s5.12-.64 5.79-1.5c.05.06.09.13.12.19.05.1.09.21.09.31v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V4 3c0-1.1 2.69-2 6-2s6 .9 6 2v2c0 1.1-2.69 2-6 2zm0-5c-2.21 0-4 .45-4 1s1.79 1 4 1 4-.45 4-1-1.79-1-4-1z\"/>"},"desktop-download":{"name":"desktop-download","figma":{"id":"0:196","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["clone","download"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 6h3V0h2v6h3l-4 4-4-4zm11-4h-4v1h4v8H1V3h4V2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1z\"/>"},"device-camera-video":{"name":"device-camera-video","figma":{"id":"0:198","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["watch","view","media","stream"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.2 2.091L10 5.721v-2.72c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h8c.55 0 1-.45 1-1v-2.72l5.2 3.63c.33.23.8 0 .8-.41v-10c0-.41-.47-.64-.8-.41z\"/>"},"device-camera":{"name":"device-camera","figma":{"id":"0:202","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["photo","picture","image","snapshot"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 3H7c0-.55-.45-1-1-1H2c-.55 0-1 .45-1 1-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h14c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM6 5H2V4h4v1zm4.5 7C8.56 12 7 10.44 7 8.5S8.56 5 10.5 5 14 6.56 14 8.5 12.44 12 10.5 12zM13 8.5c0 1.38-1.13 2.5-2.5 2.5S8 9.87 8 8.5 9.13 6 10.5 6 13 7.13 13 8.5z\"/>"},"device-desktop":{"name":"device-desktop","figma":{"id":"0:208","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["computer","monitor"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 9H1V3h14v8z\"/>"},"device-mobile":{"name":"device-mobile","figma":{"id":"0:212","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["phone","iphone","cellphone"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 0H1C.45 0 0 .45 0 1v14c0 .55.45 1 1 1h8c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1zM5 15.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zM9 12H1V2h8v10z\"/>"},"diff-added":{"name":"diff-added","figma":{"id":"0:217","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["new","addition","plus"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z\"/>"},"diff-ignored":{"name":"diff-ignored","figma":{"id":"0:222","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["slash"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z\"/>"},"diff-modified":{"name":"diff-modified","figma":{"id":"0:227","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["dot","changed","updated"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z\"/>"},"diff-removed":{"name":"diff-removed","figma":{"id":"0:232","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["deleted","subtracted","dash"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z\"/>"},"diff-renamed":{"name":"diff-renamed","figma":{"id":"0:237","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["moved","arrow"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 9H3V7h3V4l5 4-5 4V9zm8-7v12c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h12c.55 0 1 .45 1 1zm-1 0H1v12h12V2z\"/>"},"diff":{"name":"diff","figma":{"id":"0:242","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["difference","changes","compare"],"width":13,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 7h2v1H6v2H5V8H3V7h2V5h1v2zm-3 6h5v-1H3v1zM7.5 2L11 5.5V15c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h6.5zM10 6L7 3H1v12h9V6zM8.5 0H3v1h5l4 4v8h1V4.5L8.5 0z\"/>"},"ellipsis":{"name":"ellipsis","figma":{"id":"0:249","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["dot","read","more","hidden","expand"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 5H1c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zM4 9H2V7h2v2zm3 0H5V7h2v2zm3 0H8V7h2v2z\"/>"},"eye":{"name":"eye","figma":{"id":"0:255","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["look","watch","see"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z\"/>"},"file-binary":{"name":"file-binary","figma":{"id":"0:260","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["image","video","word","powerpoint","excel"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 12h1v1H2v-1h1v-2H2V9h2v3zm8-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5zM8 4H6v1h1v2H6v1h3V7H8V4zM2 4h3v4H2V4zm1 3h1V5H3v2zm3 2h3v4H6V9zm1 3h1v-2H7v2z\"/>"},"file-code":{"name":"file-code","figma":{"id":"0:270","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["text","javascript","html","css","php","ruby","coffeescript","sass","scss"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z\"/>"},"file-directory":{"name":"file-directory","figma":{"id":"0:276","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["folder"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z\"/>"},"file-media":{"name":"file-media","figma":{"id":"0:280","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["image","video","audio"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 5h2v2H6V5zm6-.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v11l3-5 2 4 2-2 3 3V5z\"/>"},"file-pdf":{"name":"file-pdf","figma":{"id":"0:285","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["adobe"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V4.5L8.5 1zM1 2h4a.68.68 0 0 0-.31.2 1.08 1.08 0 0 0-.23.47 4.22 4.22 0 0 0-.09 1.47c.06.609.173 1.211.34 1.8A21.78 21.78 0 0 1 3.6 8.6c-.5 1-.8 1.66-.91 1.84a7.161 7.161 0 0 0-.69.3 4.19 4.19 0 0 0-1 .64V2zm4.42 4.8a5.65 5.65 0 0 0 1.17 2.09c.275.237.595.417.94.53-.64.09-1.23.2-1.81.33a12.22 12.22 0 0 0-1.81.59c-.587.243.22-.44.61-1.25.365-.74.67-1.51.91-2.3l-.01.01zM11 14H1.5a.743.743 0 0 1-.17 0 2.12 2.12 0 0 0 .73-.44 10.14 10.14 0 0 0 1.78-2.38c.31-.13.58-.23.81-.31l.42-.14c.45-.13.94-.23 1.44-.33s1-.16 1.48-.2c.447.216.912.394 1.39.53.403.11.814.188 1.23.23h.38V14H11zm0-4.86a3.74 3.74 0 0 0-.64-.28 4.22 4.22 0 0 0-.75-.11c-.411.003-.822.03-1.23.08a3 3 0 0 1-1-.64 6.07 6.07 0 0 1-1.29-2.33c.111-.662.178-1.33.2-2 .02-.25.02-.5 0-.75a1.05 1.05 0 0 0-.2-.88.82.82 0 0 0-.61-.23H8l3 3v4.14z\"/>"},"file-submodule":{"name":"file-submodule","figma":{"id":"0:292","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["folder"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 7H4v7h9c.55 0 1-.45 1-1V8h-4V7zM9 9H5V8h4v1zm4-5H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h2V7c0-.55.45-1 1-1h6c.55 0 1 .45 1 1h3V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z\"/>"},"file-symlink-directory":{"name":"file-symlink-directory","figma":{"id":"0:298","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["folder","subfolder","link","alias"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM1 3h5v1H1V3zm6 9v-2c-.98-.02-1.84.22-2.55.7-.71.48-1.19 1.25-1.45 2.3.02-1.64.39-2.88 1.13-3.73C4.86 8.43 5.82 8 7.01 8V6l4 3-4 3H7z\"/>"},"file-symlink-file":{"name":"file-symlink-file","figma":{"id":"0:303","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["link","alias"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM6 4.5l4 3-4 3v-2c-.98-.02-1.84.22-2.55.7-.71.48-1.19 1.25-1.45 2.3.02-1.64.39-2.88 1.13-3.73.73-.84 1.69-1.27 2.88-1.27v-2H6z\"/>"},"file":{"name":"file","figma":{"id":"0:308","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["file","text","words"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z\"/>"},"file-zip":{"name":"file-zip","figma":{"id":"0:316","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["compress","archive"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V4.5L8.5 1zM11 14H1V2h3v1h1V2h3l3 3v9zM5 4V3h1v1H5zM4 4h1v1H4V4zm1 2V5h1v1H5zM4 6h1v1H4V6zm1 2V7h1v1H5zM4 9.28A2 2 0 0 0 3 11v1h4v-1a2 2 0 0 0-2-2V8H4v1.28zM6 10v1H4v-1h2z\"/>"},"flame":{"name":"flame","figma":{"id":"0:325","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fire","hot","burn","trending"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5.05.01c.81 2.17.41 3.38-.52 4.31C3.55 5.37 1.98 6.15.9 7.68c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.01 8.68 2.15 5.05.02L5.03 0l.02.01z\"/>"},"fold":{"name":"fold","figma":{"id":"0:329","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["unfold","hide","collapse"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 9l3 3H8v3H6v-3H4l3-3zm3-6H8V0H6v3H4l3 3 3-3zm4 2c0-.55-.45-1-1-1h-2.5l-1 1h3l-2 2h-7l-2-2h3l-1-1H1c-.55 0-1 .45-1 1l2.5 2.5L0 10c0 .55.45 1 1 1h2.5l1-1h-3l2-2h7l2 2h-3l1 1H13c.55 0 1-.45 1-1l-2.5-2.5L14 5z\"/>"},"gear":{"name":"gear","figma":{"id":"0:334","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["settings"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 8.76v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45L7.77 1h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.22v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.74v.02zm-7 2.23c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z\"/>"},"gift":{"name":"gift","figma":{"id":"0:338","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["package","present","skill","craft","freebie"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13.02 4h-1.38c.19-.33.33-.67.36-.91.06-.67-.11-1.22-.52-1.61-.36-.38-.81-.48-1.36-.48h-.11c-.53.02-1.11.25-1.53.58-.42.33-.73.72-.97 1.2-.23-.48-.55-.88-.97-1.2-.42-.32-1-.58-1.53-.58h-.03c-.56 0-1.06.09-1.44.48-.41.39-.58.94-.52 1.61.03.23.17.58.36.91H2c-.55 0-1 .45-1 1v3h1v5c0 .55.45 1 1 1h9c.55 0 1-.45 1-1V8h1V5c0-.55-.45-1-1-1h.02zm-4.78-.88c.17-.36.42-.67.75-.92.3-.23.72-.39 1.05-.41h.09c.45 0 .66.11.8.25s.33.39.3.95c-.05.19-.25.61-.5 1h-2.9l.41-.88v.01zM4.11 2.04c.13-.13.31-.25.91-.25.31 0 .72.17 1.03.41.33.25.58.55.75.92l.42.88h-2.9c-.25-.39-.45-.81-.5-1-.03-.56.16-.81.3-.95l-.01-.01zm2.91 10.95h-4V8h4v5-.01zm0-6h-5V5h5v2-.01zm5 6h-4V8h4v5-.01zm1-6h-5V5h5v2-.01z\"/>"},"gist-secret":{"name":"gist-secret","figma":{"id":"0:347","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["gist","secret","private"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.782 10.5l1 3.5h-4l1-3.5-.75-1.5h3.5l-.75 1.5zm2-4.5h-6l-2 1h10l-2-1zm-1-4l-2 1-2-1-1 3h6l-1-3zm4.03 7.75L9.782 9l1 2-2 3h3.22c.45 0 .86-.31.97-.75l.56-2.28c.14-.53-.19-1.08-.72-1.22zM3.782 9l-3.03.75c-.53.14-.86.69-.72 1.22l.56 2.28c.11.44.52.75.97.75h3.22l-2-3 1-2z\"/>"},"gist":{"name":"gist","figma":{"id":"0:354","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["gist","github"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.5 5L10 7.5 7.5 10l-.75-.75L8.5 7.5 6.75 5.75 7.5 5zm-3 0L2 7.5 4.5 10l.75-.75L3.5 7.5l1.75-1.75L4.5 5zM0 13V2c0-.55.45-1 1-1h10c.55 0 1 .45 1 1v11c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1zm1 0h10V2H1v11z\"/>"},"git-branch":{"name":"git-branch","figma":{"id":"0:360","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fork","branch","git","duplicate"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"git-commit":{"name":"git-commit","figma":{"id":"0:366","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z\"/>"},"git-compare":{"name":"git-compare","figma":{"id":"0:370","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["difference","changes"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 12H4c-.27-.02-.48-.11-.69-.31-.21-.2-.3-.42-.31-.69V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V11c.03.78.34 1.47.94 2.06.6.59 1.28.91 2.06.94h1v2l3-3-3-3v2zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm11 9.48V5c-.03-.78-.34-1.47-.94-2.06-.6-.59-1.28-.91-2.06-.94H9V0L6 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 12 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"git-merge":{"name":"git-merge","figma":{"id":"0:376","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["join"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 7.01c-.73 0-1.38.41-1.73 1.02v-.02C7.22 7.99 6 7.65 5.14 6.99c-.75-.58-1.5-1.61-1.89-2.44A1.993 1.993 0 0 0 2 1C.89 1 0 1.9 0 3.01a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2a1.993 1.993 0 0 0 1-3.72V7.68c.67.7 1.44 1.27 2.3 1.69.86.42 2.03.63 2.97.64v-.02c.36.61 1 1.02 1.73 1.02 1.11 0 2-.89 2-2 0-1.11-.89-2-2-2zm-6.8 6c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.21c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm8 6c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"git-pull-request":{"name":"git-pull-request","figma":{"id":"0:382","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["review"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"globe":{"name":"globe","figma":{"id":"0:389","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["world","earth","planet"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 1C3.14 1 0 4.14 0 8s3.14 7 7 7c.48 0 .94-.05 1.38-.14-.17-.08-.2-.73-.02-1.09.19-.41.81-1.45.2-1.8-.61-.35-.44-.5-.81-.91-.37-.41-.22-.47-.25-.58-.08-.34.36-.89.39-.94.02-.06.02-.27 0-.33 0-.08-.27-.22-.34-.23-.06 0-.11.11-.2.13-.09.02-.5-.25-.59-.33-.09-.08-.14-.23-.27-.34-.13-.13-.14-.03-.33-.11s-.8-.31-1.28-.48c-.48-.19-.52-.47-.52-.66-.02-.2-.3-.47-.42-.67-.14-.2-.16-.47-.2-.41-.04.06.25.78.2.81-.05.02-.16-.2-.3-.38-.14-.19.14-.09-.3-.95s.14-1.3.17-1.75c.03-.45.38.17.19-.13-.19-.3 0-.89-.14-1.11-.13-.22-.88.25-.88.25.02-.22.69-.58 1.16-.92.47-.34.78-.06 1.16.05.39.13.41.09.28-.05-.13-.13.06-.17.36-.13.28.05.38.41.83.36.47-.03.05.09.11.22s-.06.11-.38.3c-.3.2.02.22.55.61s.38-.25.31-.55c-.07-.3.39-.06.39-.06.33.22.27.02.5.08.23.06.91.64.91.64-.83.44-.31.48-.17.59.14.11-.28.3-.28.3-.17-.17-.19.02-.3.08-.11.06-.02.22-.02.22-.56.09-.44.69-.42.83 0 .14-.38.36-.47.58-.09.2.25.64.06.66-.19.03-.34-.66-1.31-.41-.3.08-.94.41-.59 1.08.36.69.92-.19 1.11-.09.19.1-.06.53-.02.55.04.02.53.02.56.61.03.59.77.53.92.55.17 0 .7-.44.77-.45.06-.03.38-.28 1.03.09.66.36.98.31 1.2.47.22.16.08.47.28.58.2.11 1.06-.03 1.28.31.22.34-.88 2.09-1.22 2.28-.34.19-.48.64-.84.92s-.81.64-1.27.91c-.41.23-.47.66-.66.8 3.14-.7 5.48-3.5 5.48-6.84 0-3.86-3.14-7-7-7L7 1zm1.64 6.56c-.09.03-.28.22-.78-.08-.48-.3-.81-.23-.86-.28 0 0-.05-.11.17-.14.44-.05.98.41 1.11.41.13 0 .19-.13.41-.05.22.08.05.13-.05.14zM6.34 1.7c-.05-.03.03-.08.09-.14.03-.03.02-.11.05-.14.11-.11.61-.25.52.03-.11.27-.58.3-.66.25zm1.23.89c-.19-.02-.58-.05-.52-.14.3-.28-.09-.38-.34-.38-.25-.02-.34-.16-.22-.19.12-.03.61.02.7.08.08.06.52.25.55.38.02.13 0 .25-.17.25zm1.47-.05c-.14.09-.83-.41-.95-.52-.56-.48-.89-.31-1-.41-.11-.1-.08-.19.11-.34.19-.15.69.06 1 .09.3.03.66.27.66.55.02.25.33.5.19.63h-.01z\"/>"},"graph":{"name":"graph","figma":{"id":"0:396","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["trend","stats","statistics"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z\"/>"},"heart":{"name":"heart","figma":{"id":"0:400","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["love","beat"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.2 3c-.52-.63-1.25-.95-2.2-1-.97 0-1.69.42-2.2 1-.51.58-.78.92-.8 1-.02-.08-.28-.42-.8-1-.52-.58-1.17-1-2.2-1-.95.05-1.69.38-2.2 1-.52.61-.78 1.28-.8 2 0 .52.09 1.52.67 2.67C1.25 8.82 3.01 10.61 6 13c2.98-2.39 4.77-4.17 5.34-5.33C11.91 6.51 12 5.5 12 5c-.02-.72-.28-1.39-.8-2.02V3z\"/>"},"history":{"name":"history","figma":{"id":"0:404","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["time","past","revert","back"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 13H6V6h5v2H8v5zM7 1C4.81 1 2.87 2.02 1.59 3.59L0 2v4h4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7s7-3.14 7-7-3.14-7-7-7z\"/>"},"home":{"name":"home","figma":{"id":"0:408","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["welcome","index","house","building"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 9l-3-3V2h-2v2L8 1 0 9h2l1 5c0 .55.45 1 1 1h8c.55 0 1-.45 1-1l1-5h2zm-4 5H9v-4H7v4H4L2.81 7.69 8 2.5l5.19 5.19L12 14z\"/>"},"horizontal-rule":{"name":"horizontal-rule","figma":{"id":"0:412","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hr"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1 7h2v2h1V3H3v3H1V3H0v6h1V7zm9 2V7H9v2h1zm0-3V4H9v2h1zM7 6V4h2V3H6v6h1V7h2V6H7zm-7 7h10v-2H0v2z\"/>"},"hubot":{"name":"hubot","figma":{"id":"0:419","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["robot","bot"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 6c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h8c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1H3zm8 1.75L9.75 9h-1.5L7 7.75 5.75 9h-1.5L3 7.75V7h.75L5 8.25 6.25 7h1.5L9 8.25 10.25 7H11v.75zM5 11h4v1H5v-1zm2-9C3.14 2 0 4.91 0 8.5V13c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V8.5C14 4.91 10.86 2 7 2zm6 11H1V8.5c0-3.09 2.64-5.59 6-5.59s6 2.5 6 5.59V13z\"/>"},"inbox":{"name":"inbox","figma":{"id":"0:426","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["mail","todo","new","messages"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 9l-1.13-7.14c-.08-.48-.5-.86-1-.86H2.13c-.5 0-.92.38-1 .86L0 9v5c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V9zm-3.28.55l-.44.89c-.17.34-.52.56-.91.56H4.61c-.38 0-.72-.22-.89-.55l-.44-.91c-.17-.33-.52-.55-.89-.55H1l1-7h10l1 7h-1.38c-.39 0-.73.22-.91.55l.01.01z\"/>"},"info":{"name":"info","figma":{"id":"0:430","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["help"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.3 5.71a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 8.01c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V8v.01zM7 2.32C3.86 2.32 1.3 4.86 1.3 8c0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 1c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z\"/>"},"issue-closed":{"name":"issue-closed","figma":{"id":"0:436","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["done","complete"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5 1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14 2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1 4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z\"/>"},"issue-opened":{"name":"issue-opened","figma":{"id":"0:442","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["new"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z\"/>"},"issue-reopened":{"name":"issue-reopened","figma":{"id":"0:448","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["regression"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 9H6V4h2v5zm-2 3h2v-2H6v2zm6.33-2H10l1.5 1.5c-1.05 1.33-2.67 2.2-4.5 2.2A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7 2.19 0 4.13-1.02 5.41-2.59L14 14v-4h-1.67zM1.67 6H4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7 0 .34-.03.67-.09 1h1.31c.05-.33.08-.66.08-1 0-3.86-3.14-7-7-7-2.19 0-4.13 1.02-5.41 2.59L0 2v4h1.67z\"/>"},"italic":{"name":"italic","figma":{"id":"0:454","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["font","italic","style"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2.81 5h1.98L3 14H1l1.81-9zm.36-2.7c0-.7.58-1.3 1.33-1.3.56 0 1.13.38 1.13 1.03 0 .75-.59 1.3-1.33 1.3-.58 0-1.13-.38-1.13-1.03z\"/>"},"jersey":{"name":"jersey","figma":{"id":"0:458","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["team","game","basketball"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.5 6l-.5.5v5l.5.5h2l.5-.5v-5L6.5 6h-2zM6 11H5V7h1v4zm6.27-7.25C12.05 2.37 11.96 1.12 12 0H9.02c0 .27-.13.48-.39.69-.25.2-.63.3-1.13.3-.5 0-.88-.09-1.13-.3-.23-.2-.36-.42-.36-.69H3c.05 1.13-.03 2.38-.25 3.75C2.55 5.13 1.95 5.88 1 6v9c.02.27.11.48.31.69.2.21.42.3.69.31h11c.27-.02.48-.11.69-.31.21-.2.3-.42.31-.69V6c-.95-.13-1.53-.88-1.75-2.25h.02zM13 15H2V7c.89-.5 1.48-1.25 1.72-2.25S4.03 2.5 4 1h1c-.02.78.16 1.47.52 2.06.36.58 1.02.89 2 .94.98-.02 1.64-.33 2-.94.36-.59.5-1.28.48-2.06h1c.02 1.42.13 2.55.33 3.38.2.81.69 2 1.67 2.63v8V15zM8.5 6l-.5.5v5l.5.5h2l.5-.5v-5l-.5-.5h-2zm1.5 5H9V7h1v4z\"/>"},"keyboard":{"name":"keyboard","figma":{"id":"0:466","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["type","keys","write","shortcuts"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 5H9V4h1v1zM3 6H2v1h1V6zm5-2H7v1h1V4zM4 4H2v1h2V4zm8 7h2v-1h-2v1zM8 7h1V6H8v1zm-4 3H2v1h2v-1zm8-6h-1v1h1V4zm2 0h-1v1h1V4zm-2 5h2V6h-2v3zm4-6v9c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h14c.55 0 1 .45 1 1zm-1 0H1v9h14V3zM6 7h1V6H6v1zm0-3H5v1h1V4zM4 7h1V6H4v1zm1 4h6v-1H5v1zm5-4h1V6h-1v1zM3 8H2v1h1V8zm5 0v1h1V8H8zM6 8v1h1V8H6zM5 8H4v1h1V8zm5 1h1V8h-1v1z\"/>"},"law":{"name":"law","figma":{"id":"0:490","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["legal","bill"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 4c-.83 0-1.5-.67-1.5-1.5S6.17 1 7 1s1.5.67 1.5 1.5S7.83 4 7 4zm7 6c0 1.11-.89 2-2 2h-1c-1.11 0-2-.89-2-2l2-4h-1c-.55 0-1-.45-1-1H8v8c.42 0 1 .45 1 1h1c.42 0 1 .45 1 1H3c0-.55.58-1 1-1h1c0-.55.58-1 1-1h.03L6 5H5c0 .55-.45 1-1 1H3l2 4c0 1.11-.89 2-2 2H2c-1.11 0-2-.89-2-2l2-4H1V5h3c0-.55.45-1 1-1h4c.55 0 1 .45 1 1h3v1h-1l2 4zM2.5 7L1 10h3L2.5 7zM13 10l-1.5-3-1.5 3h3z\"/>"},"link":{"name":"link","figma":{"id":"0:496","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["connect","hyperlink"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"/>"},"list-ordered":{"name":"list-ordered","figma":{"id":"0:500","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["numbers","tasks","todo","items"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12.01 13c0 .59 0 1-.59 1H4.6c-.59 0-.59-.41-.59-1 0-.59 0-1 .59-1h6.81c.59 0 .59.41.59 1h.01zM4.6 4h6.81C12 4 12 3.59 12 3c0-.59 0-1-.59-1H4.6c-.59 0-.59.41-.59 1 0 .59 0 1 .59 1zm6.81 3H4.6c-.59 0-.59.41-.59 1 0 .59 0 1 .59 1h6.81C12 9 12 8.59 12 8c0-.59 0-1-.59-1zm-9.4-6h-.72c-.3.19-.58.25-1.03.34V2h.75v2.14H.17V5h2.84v-.86h-1V1zm.25 8.13c-.17 0-.45.03-.66.06.53-.56 1.14-1.25 1.14-1.89C2.72 6.52 2.18 6 1.38 6c-.59 0-.97.2-1.38.64l.58.58c.19-.19.38-.38.64-.38.28 0 .48.16.48.52 0 .53-.77 1.2-1.7 2.06V10h3l-.09-.88h-.66l.01.01zm-.08 3.78v-.03c.44-.19.64-.47.64-.86 0-.7-.56-1.11-1.44-1.11-.48 0-.89.19-1.28.52l.55.64c.25-.2.44-.31.69-.31.27 0 .42.13.42.36 0 .27-.2.44-.86.44v.75c.83 0 .98.17.98.47 0 .25-.23.38-.58.38-.28 0-.56-.14-.81-.38l-.48.66c.3.36.77.56 1.41.56.83 0 1.53-.41 1.53-1.16 0-.5-.31-.81-.77-.94v.01z\"/>"},"list-unordered":{"name":"list-unordered","figma":{"id":"0:508","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["bullet","point","tasks","todo","items"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 13c0 .59 0 1-.59 1H.59C0 14 0 13.59 0 13c0-.59 0-1 .59-1h.81c.59 0 .59.41.59 1H2zm2.59-9h6.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1H4.59C4 2 4 2.41 4 3c0 .59 0 1 .59 1zM1.41 7H.59C0 7 0 7.41 0 8c0 .59 0 1 .59 1h.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01zm0-5H.59C0 2 0 2.41 0 3c0 .59 0 1 .59 1h.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01zm10 5H4.59C4 7 4 7.41 4 8c0 .59 0 1 .59 1h6.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01zm0 5H4.59C4 12 4 12.41 4 13c0 .59 0 1 .59 1h6.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01z\"/>"},"location":{"name":"location","figma":{"id":"0:516","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["here","marker"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 0C2.69 0 0 2.5 0 5.5 0 10.02 6 16 6 16s6-5.98 6-10.5C12 2.5 9.31 0 6 0zm0 14.55C4.14 12.52 1 8.44 1 5.5 1 3.02 3.25 1 6 1c1.34 0 2.61.48 3.56 1.36.92.86 1.44 1.97 1.44 3.14 0 2.94-3.14 7.02-5 9.05zM8 5.5c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z\"/>"},"lock":{"name":"lock","figma":{"id":"0:521","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["secure","safe","protected"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 13H3v-1h1v1zm8-6v7c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h1V4c0-2.2 1.8-4 4-4s4 1.8 4 4v2h1c.55 0 1 .45 1 1zM3.8 6h4.41V4c0-1.22-.98-2.2-2.2-2.2-1.22 0-2.2.98-2.2 2.2v2H3.8zM11 7H2v7h9V7zM4 8H3v1h1V8zm0 2H3v1h1v-1z\"/>"},"logo-gist":{"name":"logo-gist","figma":{"id":"0:529","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["brand","github","logo"],"width":25,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.7 8.73h2.45v4.02c-.55.27-1.64.34-2.53.34-2.56 0-3.47-2.2-3.47-5.05 0-2.85.91-5.06 3.48-5.06 1.28 0 2.06.23 3.28.73V2.66C7.27 2.33 6.25 2 4.63 2 1.13 2 0 4.69 0 8.03c0 3.34 1.11 6.03 4.63 6.03 1.64 0 2.81-.27 3.59-.64V7.73H4.7v1zm6.39 3.72V6.06h-1.05v6.28c0 1.25.58 1.72 1.72 1.72v-.89c-.48 0-.67-.16-.67-.7v-.02zm.25-8.72c0-.44-.33-.78-.78-.78s-.77.34-.77.78.33.78.77.78.78-.34.78-.78zm4.34 5.69c-1.5-.13-1.78-.48-1.78-1.17 0-.77.33-1.34 1.88-1.34 1.05 0 1.66.16 2.27.36v-.94c-.69-.3-1.52-.39-2.25-.39-2.2 0-2.92 1.2-2.92 2.31 0 1.08.47 1.88 2.73 2.08 1.55.13 1.77.63 1.77 1.34 0 .73-.44 1.42-2.06 1.42-1.11 0-1.86-.19-2.33-.36v.94c.5.2 1.58.39 2.33.39 2.38 0 3.14-1.2 3.14-2.41 0-1.28-.53-2.03-2.75-2.23h-.03zm8.58-2.47v-.86h-2.42v-2.5l-1.08.31v2.11l-1.56.44v.48h1.56v5c0 1.53 1.19 2.13 2.5 2.13.19 0 .52-.02.69-.05v-.89c-.19.03-.41.03-.61.03-.97 0-1.5-.39-1.5-1.34V6.94h2.42v.02-.01z\"/>"},"logo-github":{"name":"logo-github","figma":{"id":"0:536","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["brand","github","logo"],"width":45,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M18.53 12.03h-.02c.009 0 .015.01.024.011h.006l-.01-.01zm.004.011c-.093.001-.327.05-.574.05-.78 0-1.05-.36-1.05-.83V8.13h1.59c.09 0 .16-.08.16-.19v-1.7c0-.09-.08-.17-.16-.17h-1.59V3.96c0-.08-.05-.13-.14-.13h-2.16c-.09 0-.14.05-.14.13v2.17s-1.09.27-1.16.28c-.08.02-.13.09-.13.17v1.36c0 .11.08.19.17.19h1.11v3.28c0 2.44 1.7 2.69 2.86 2.69.53 0 1.17-.17 1.27-.22.06-.02.09-.09.09-.16v-1.5a.177.177 0 0 0-.146-.18zm23.696-2.2c0-1.81-.73-2.05-1.5-1.97-.6.04-1.08.34-1.08.34v3.52s.49.34 1.22.36c1.03.03 1.36-.34 1.36-2.25zm2.43-.16c0 3.43-1.11 4.41-3.05 4.41-1.64 0-2.52-.83-2.52-.83s-.04.46-.09.52c-.03.06-.08.08-.14.08h-1.48c-.1 0-.19-.08-.19-.17l.02-11.11c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v3.77s.82-.53 2.02-.53l-.01-.02c1.2 0 2.97.45 2.97 3.88zm-8.72-3.61H33.84c-.11 0-.17.08-.17.19v5.44s-.55.39-1.3.39-.97-.34-.97-1.09V6.25c0-.09-.08-.17-.17-.17h-2.14c-.09 0-.17.08-.17.17v5.11c0 2.2 1.23 2.75 2.92 2.75 1.39 0 2.52-.77 2.52-.77s.05.39.08.45c.02.05.09.09.16.09h1.34c.11 0 .17-.08.17-.17l.02-7.47c0-.09-.08-.17-.19-.17zm-23.7-.01h-2.13c-.09 0-.17.09-.17.2v7.34c0 .2.13.27.3.27h1.92c.2 0 .25-.09.25-.27V6.23c0-.09-.08-.17-.17-.17zm-1.05-3.38c-.77 0-1.38.61-1.38 1.38 0 .77.61 1.38 1.38 1.38.75 0 1.36-.61 1.36-1.38 0-.77-.61-1.38-1.36-1.38zm16.49-.25h-2.11c-.09 0-.17.08-.17.17v4.09h-3.31V2.6c0-.09-.08-.17-.17-.17h-2.13c-.09 0-.17.08-.17.17v11.11c0 .09.09.17.17.17h2.13c.09 0 .17-.08.17-.17V8.96h3.31l-.02 4.75c0 .09.08.17.17.17h2.13c.09 0 .17-.08.17-.17V2.6c0-.09-.08-.17-.17-.17zM8.81 7.35v5.74c0 .04-.01.11-.06.13 0 0-1.25.89-3.31.89-2.49 0-5.44-.78-5.44-5.92S2.58 1.99 5.1 2c2.18 0 3.06.49 3.2.58.04.05.06.09.06.14L7.94 4.5c0 .09-.09.2-.2.17-.36-.11-.9-.33-2.17-.33-1.47 0-3.05.42-3.05 3.73s1.5 3.7 2.58 3.7c.92 0 1.25-.11 1.25-.11v-2.3H4.88c-.11 0-.19-.08-.19-.17V7.35c0-.09.08-.17.19-.17h3.74c.11 0 .19.08.19.17z\"/>"},"mail-read":{"name":"mail-read","figma":{"id":"0:547","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["email","open"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 5H4V4h2v1zm3 1H4v1h5V6zm5-.48V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V5.52c0-.33.16-.63.42-.81L2 3.58V3c0-.55.45-1 1-1h1.2L7 0l2.8 2H11c.55 0 1 .45 1 1v.58l1.58 1.13c.27.19.42.48.42.81zM3 7.5L7 10l4-2.5V3H3v4.5zm-2 6l4.5-3-4.5-3v6zm11 .5l-5-3-5 3h10zm1-6.5l-4.5 3 4.5 3v-6z\"/>"},"reply":{"name":"reply","figma":{"id":"0:554","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["reply all","back"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.5 3.5c3.92.44 8 3.125 8 10-2.312-5.062-4.75-6-8-6V11L1 5.5 6.5 0v3.5z\"/>"},"mail":{"name":"mail","figma":{"id":"0:558","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["email","unread"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 4v8c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1zm13 0L7 9 1 4h12zM1 5.5l4 3-4 3v-6zM2 12l3.5-3L7 10.5 8.5 9l3.5 3H2zm11-.5l-4-3 4-3v6z\"/>"},"mark-github":{"name":"mark-github","figma":{"id":"0:563","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["octocat","brand","github","logo"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z\"/>"},"markdown":{"name":"markdown","figma":{"id":"0:567","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["markup","style"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z\"/>"},"megaphone":{"name":"megaphone","figma":{"id":"0:572","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["bullhorn","loud","shout","broadcast"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 1c-.17 0-.36.05-.52.14C8.04 2.02 4.5 4.58 3 5c-1.38 0-3 .67-3 2.5S1.63 10 3 10c.3.08.64.23 1 .41V15h2v-3.45c1.34.86 2.69 1.83 3.48 2.31.16.09.34.14.52.14.52 0 1-.42 1-1V2c0-.58-.48-1-1-1zm0 12c-.38-.23-.89-.58-1.5-1-.16-.11-.33-.22-.5-.34V3.31c.16-.11.31-.2.47-.31.61-.41 1.16-.77 1.53-1v11zm2-6h4v1h-4V7zm0 2l4 2v1l-4-2V9zm4-6v1l-4 2V5l4-2z\"/>"},"mention":{"name":"mention","figma":{"id":"0:579","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["at","ping"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.58 15c1.25 0 2.52-.31 3.56-.94l-.42-.94c-.84.52-1.89.83-3.03.83-3.23 0-5.64-2.08-5.64-5.72 0-4.37 3.23-7.18 6.58-7.18 3.45 0 5.22 2.19 5.22 5.2 0 2.39-1.34 3.86-2.5 3.86-1.05 0-1.36-.73-1.05-2.19l.73-3.75H8.98l-.11.72c-.41-.63-.94-.83-1.56-.83-2.19 0-3.66 2.39-3.66 4.38 0 1.67.94 2.61 2.3 2.61.84 0 1.67-.53 2.3-1.25.11.94.94 1.45 1.98 1.45 1.67 0 3.77-1.67 3.77-5C14 2.61 11.59 0 7.83 0 3.66 0 0 3.33 0 8.33 0 12.71 2.92 15 6.58 15zm-.31-5c-.73 0-1.36-.52-1.36-1.67 0-1.45.94-3.22 2.41-3.22.52 0 .84.2 1.25.83l-.52 3.02c-.63.73-1.25 1.05-1.78 1.05V10z\"/>"},"milestone":{"name":"milestone","figma":{"id":"0:583","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["marker"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 2H6V0h2v2zm4 5H2c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h10l2 2-2 2zM8 4H6v2h2V4zM6 16h2V8H6v8z\"/>"},"mirror":{"name":"mirror","figma":{"id":"0:589","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["reflect"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.5 4.7L8.5 0l-7 4.7c-.3.19-.5.45-.5.8V16l7.5-4 7.5 4V5.5c0-.34-.2-.61-.5-.8zm-.5 9.8l-6-3.25V10H8v1.25L2 14.5v-9l6-4V6h1V1.5l6 4v9zM6 7h5V5l3 3-3 3V9H6v2L3 8l3-3v2z\"/>"},"mortar-board":{"name":"mortar-board","figma":{"id":"0:594","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["education","learn","teach"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.808 9.405l-3.83-1.19c-4-8 0 1.5 0 2.5s1.8 1.5 4 1.5 4-.5 4-1.5v-2.5l-3.83 1.19a.73.73 0 0 1-.36 0h.02zm.28-6.39a.34.34 0 0 0-.2 0l-7.64 2.38a.35.35 0 0 0 0 .67l1.73.55v1.77c-.3.17-.5.5-.5.86 0 .19.05.36.14.5-.08.14-.14.31-.14.5v2.58c0 .55 2 .55 2 0v-2.58c0-.19-.05-.36-.14-.5.08-.14.14-.31.14-.5 0-.38-.2-.69-.5-.86v-1.45l4.89 1.53c.06.02.14.02.2 0l7.64-2.38a.35.35 0 0 0 0-.67l-7.63-2.39.01-.01zm-.09 3.2c-.55 0-1-.22-1-.5s.45-.5 1-.5 1 .22 1 .5-.45.5-1 .5z\"/>"},"mute":{"name":"mute","figma":{"id":"0:599","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["quiet","sound","audio","turn","off"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 2.75v10.38c0 .67-.81 1-1.28.53L3 9.94H1c-.55 0-1-.45-1-1v-2c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.75 8 2.08 8 2.75zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06 1.97 1.97-1.97 1.97 1.06 1.06L12.5 9l1.97 1.97 1.06-1.06-1.97-1.97 1.97-1.97z\"/>"},"no-newline":{"name":"no-newline","figma":{"id":"0:603","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["return"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 5v3c0 .55-.45 1-1 1h-3v2L9 8l3-3v2h2V5h2zM8 8c0 2.2-1.8 4-4 4s-4-1.8-4-4 1.8-4 4-4 4 1.8 4 4zM1.5 9.66L5.66 5.5C5.18 5.19 4.61 5 4 5 2.34 5 1 6.34 1 8c0 .61.19 1.17.5 1.66zM7 8c0-.61-.19-1.17-.5-1.66L2.34 10.5c.48.31 1.05.5 1.66.5 1.66 0 3-1.34 3-3z\"/>"},"octoface":{"name":"octoface","figma":{"id":"0:609","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["octocat","brand"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14.7 5.34c.13-.32.55-1.59-.13-3.31 0 0-1.05-.33-3.44 1.3-1-.28-2.07-.32-3.13-.32s-2.13.04-3.13.32c-2.39-1.64-3.44-1.3-3.44-1.3-.68 1.72-.26 2.99-.13 3.31C.49 6.21 0 7.33 0 8.69 0 13.84 3.33 15 7.98 15S16 13.84 16 8.69c0-1.36-.49-2.48-1.3-3.35zM8 14.02c-3.3 0-5.98-.15-5.98-3.35 0-.76.38-1.48 1.02-2.07 1.07-.98 2.9-.46 4.96-.46 2.07 0 3.88-.52 4.96.46.65.59 1.02 1.3 1.02 2.07 0 3.19-2.68 3.35-5.98 3.35zM5.49 9.01c-.66 0-1.2.8-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.54-1.78-1.2-1.78zm5.02 0c-.66 0-1.2.79-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.53-1.78-1.2-1.78z\"/>"},"organization":{"name":"organization","figma":{"id":"0:613","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["people","group","team"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088A6.78 6.78 0 0 1 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z\"/>"},"package":{"name":"package","figma":{"id":"0:617","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["box","ship"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1 4.732v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97v-7.47c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0l-6.5 1.74c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59v-6.77l6 1.61v6.75zm-6-9.36l2.5-.67 6.5 1.73-2.5.67L2 4.463zm13 7.77l-6 1.59v-6.75l2-.55v2.44l2-.53v-2.44l2-.53v6.77zm-2-7.24l-6.5-1.73 2-.53 6.5 1.73-2 .53z\"/>"},"paintcan":{"name":"paintcan","figma":{"id":"0:624","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["style","theme","art","color"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 0C2.69 0 0 2.69 0 6v1c0 .55.45 1 1 1v5c0 1.1 2.24 2 5 2s5-.9 5-2V8c.55 0 1-.45 1-1V6c0-3.31-2.69-6-6-6zm3 10v.5c0 .28-.22.5-.5.5s-.5-.22-.5-.5V10c0-.28-.22-.5-.5-.5s-.5.22-.5.5v2.5c0 .28-.22.5-.5.5s-.5-.22-.5-.5v-2c0-.28-.22-.5-.5-.5s-.5.22-.5.5v.5c0 .55-.45 1-1 1s-1-.45-1-1v-1c-.55 0-1-.45-1-1V7.2c.91.49 2.36.8 4 .8 1.64 0 3.09-.31 4-.8V9c0 .55-.45 1-1 1zM6 7c-1.68 0-3.12-.41-3.71-1C2.88 5.41 4.32 5 6 5c1.68 0 3.12.41 3.71 1-.59.59-2.03 1-3.71 1zm0-3c-2.76 0-5 .89-5 2 0-2.76 2.24-5 5-5s5 2.24 5 5c0-1.1-2.24-2-5-2z\"/>"},"pencil":{"name":"pencil","figma":{"id":"0:630","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["edit","change","update","write"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 11.592v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3l-1.3 1.3-3-3 1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z\"/>"},"person":{"name":"person","figma":{"id":"0:633","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["people","man","woman","human"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 14.002a.998.998 0 0 1-.998.998H1.001A1 1 0 0 1 0 13.999V13c0-2.633 4-4 4-4s.229-.409 0-1c-.841-.62-.944-1.59-1-4 .173-2.413 1.867-3 3-3s2.827.586 3 3c-.056 2.41-.159 3.38-1 4-.229.59 0 1 0 1s4 1.367 4 4v1.002z\"/>"},"pin":{"name":"pin","figma":{"id":"0:635","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save","star","bookmark"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 1.494v.8l.5 1-4.5 3H2.2c-.44 0-.67.53-.34.86L5 10.294l-4 5 5-4 3.14 3.14a.5.5 0 0 0 .86-.34v-3.8l3-4.5 1 .5h.8c.44 0 .67-.53.34-.86l-4.28-4.28a.5.5 0 0 0-.86.34z\"/>"},"plug":{"name":"plug","figma":{"id":"0:637","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hook","webhook"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 6V5h-4V3H8v1H6c-1.03 0-1.77.81-2 2L3 7c-1.66 0-3 1.34-3 3v2h1v-2c0-1.11.89-2 2-2l1 1c.25 1.16.98 2 2 2h2v1h2v-2h4V9h-4V6h4z\"/>"},"plus":{"name":"plus","figma":{"id":"0:639","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["add","new","more"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 9H7v5H5V9H0V7h5V2h2v5h5v2z\"/>"},"primitive-dot":{"name":"primitive-dot","figma":{"id":"0:641","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["circle"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 8c0-2.2 1.8-4 4-4s4 1.8 4 4-1.8 4-4 4-4-1.8-4-4z\"/>"},"primitive-square":{"name":"primitive-square","figma":{"id":"0:643","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["box"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 12H0V4h8v8z\"/>"},"pulse":{"name":"pulse","figma":{"id":"0:645","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["graph","trend","line","activity"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.5 8.4L8.8 5.8 6.6 8.9 5.5 2 2.38 8.4H0v2h3.6l.9-1.8.9 5.4L9 8.9l1.6 1.5H14v-2h-2.5z\"/>"},"question":{"name":"question","figma":{"id":"0:649","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["help","explain"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 10h2v2H6v-2zm4-3.5C10 8.64 8 9 8 9H6c0-.55.45-1 1-1h.5c.28 0 .5-.22.5-.5v-1c0-.28-.22-.5-.5-.5h-1c-.28 0-.5.22-.5.5V7H4c0-1.5 1.5-3 3-3s3 1 3 2.5zM7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7z\"/>"},"quote":{"name":"quote","figma":{"id":"0:655","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["quotation"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.16 3.84C3.73 5.4 2.55 7.01 2.55 9.7c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.9 0-2.99-1.52-2.99-4.25C0 6.62 1.75 3.89 5.02 2l1.14 1.84zm7 0C10.73 5.4 9.55 7.01 9.55 9.7c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.89 0-2.98-1.52-2.98-4.25 0-3.8 1.75-6.53 5.02-8.42l1.14 1.84h-.01z\"/>"},"radio-tower":{"name":"radio-tower","figma":{"id":"0:659","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["broadcast"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.78 5.78c.25-.25.25-.67 0-.92-.32-.33-.48-.76-.48-1.19 0-.43.16-.86.48-1.19.25-.26.25-.67 0-.92a.613.613 0 0 0-.45-.19c-.16 0-.33.06-.45.19-.57.58-.85 1.35-.85 2.11 0 .76.29 1.53.85 2.11.25.25.66.25.9 0zM2.32.19a.651.651 0 0 0-.92 0C.47 1.15 0 2.41 0 3.66c0 1.26.47 2.52 1.4 3.48.25.26.66.26.91 0s.25-.68 0-.94c-.68-.7-1.02-1.62-1.02-2.54 0-.92.34-1.84 1.02-2.54a.66.66 0 0 0 .01-.93zm5.69 5.1a1.62 1.62 0 1 0-1.62-1.62c-.01.89.72 1.62 1.62 1.62zM14.58.2a.628.628 0 0 0-.91 0c-.25.26-.25.68 0 .94.68.7 1.02 1.62 1.02 2.54 0 .92-.34 1.83-1.02 2.54-.25.26-.25.68 0 .94a.651.651 0 0 0 .92 0c.93-.96 1.4-2.22 1.4-3.48A5.048 5.048 0 0 0 14.58.2zM8.01 6.59c-.41 0-.83-.1-1.2-.3l-3.15 8.37h1.49l.86-1h4l.84 1h1.49L9.2 6.29c-.38.2-.78.3-1.19.3zM8 7.07l1.01 3.6h-2L8 7.07zm-1.99 5.59l1-1h2l1 1h-4zm5.19-11.1c-.25.25-.25.67 0 .92.32.33.48.76.48 1.19 0 .43-.16.86-.48 1.19-.25.26-.25.67 0 .92a.63.63 0 0 0 .9 0c.57-.58.85-1.35.85-2.11 0-.76-.28-1.53-.85-2.11a.634.634 0 0 0-.9 0z\"/>"},"repo-clone":{"name":"repo-clone","figma":{"id":"0:669","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","repository"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 0H9v7c0 .55.45 1 1 1h1v1h1V8h3c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1zm-4 7h-1V6h1v1zm4 0h-3V6h3v1zm0-2h-4V1h4v4zM4 5H3V4h1v1zm0-2H3V2h1v1zM2 1h6V0H1C.45 0 0 .45 0 1v12c0 .55.45 1 1 1h2v2l1.5-1.5L6 16v-2h5c.55 0 1-.45 1-1v-3H2V1zm9 10v2H6v-1H3v1H1v-2h10zM3 8h1v1H3V8zm1-1H3V6h1v1z\"/>"},"repo-force-push":{"name":"repo-force-push","figma":{"id":"0:681","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","put"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 9H8v7H6V9H4l2.25-3H4l3-4 3 4H7.75L10 9zm1-9H1C.45 0 0 .45 0 1v12c0 .55.45 1 1 1h4v-1H1v-2h4v-1H2V1h9v9H9v1h2v2H9v1h2c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1z\"/>"},"repo-forked":{"name":"repo-forked","figma":{"id":"0:685","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","copy"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"repo-pull":{"name":"repo-pull","figma":{"id":"0:691","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","get"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 8V6H7V4h6V2l3 3-3 3zM4 2H3v1h1V2zm7 5h1v6c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1v2h-1V1H2v9h9V7zm0 4H1v2h2v-1h3v1h5v-2zM4 6H3v1h1V6zm0-2H3v1h1V4zM3 9h1V8H3v1z\"/>"},"repo-push":{"name":"repo-push","figma":{"id":"0:700","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","repository","put"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 3H3V2h1v1zM3 5h1V4H3v1zm4 0L4 9h2v7h2V9h2L7 5zm4-5H1C.45 0 0 .45 0 1v12c0 .55.45 1 1 1h4v-1H1v-2h4v-1H2V1h9.02L11 10H9v1h2v2H9v1h2c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1z\"/>"},"repo":{"name":"repo","figma":{"id":"0:706","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","repository"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z\"/>"},"rocket":{"name":"rocket","figma":{"id":"0:715","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["staff","stafftools","blast","off","space","launch","ship"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12.17 3.83c-.27-.27-.47-.55-.63-.88-.16-.31-.27-.66-.34-1.02-.58.33-1.16.7-1.73 1.13-.58.44-1.14.94-1.69 1.48-.7.7-1.33 1.81-1.78 2.45H3L0 10h3l2-2c-.34.77-1.02 2.98-1 3l1 1c.02.02 2.23-.64 3-1l-2 2v3l3-3v-3c.64-.45 1.75-1.09 2.45-1.78.55-.55 1.05-1.13 1.47-1.7.44-.58.81-1.16 1.14-1.72-.36-.08-.7-.19-1.03-.34a3.39 3.39 0 0 1-.86-.63zM16 0s-.09.38-.3 1.06c-.2.7-.55 1.58-1.06 2.66-.7-.08-1.27-.33-1.66-.72-.39-.39-.63-.94-.7-1.64C13.36.84 14.23.48 14.92.28 15.62.08 16 0 16 0z\"/>"},"rss":{"name":"rss","figma":{"id":"0:719","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["broadcast","feed","atom"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 13H0v-2c1.11 0 2 .89 2 2zM0 3v1a9 9 0 0 1 9 9h1C10 7.48 5.52 3 0 3zm0 4v1c2.75 0 5 2.25 5 5h1c0-3.31-2.69-6-6-6z\"/>"},"ruby":{"name":"ruby","figma":{"id":"0:724","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["code","language"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 6l-5 5V4h3l2 2zm3 0l-8 8-8-8 4-4h8l4 4zm-8 6.5L14.5 6l-3-3h-7l-3 3L8 12.5z\"/>"},"search":{"name":"search","figma":{"id":"0:729","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["magnifying","glass"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z\"/>"},"server":{"name":"server","figma":{"id":"0:733","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["computers","racks","ops"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 6H1c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1zM2 9H1V7h1v2zm2 0H3V7h1v2zm2 0H5V7h1v2zm2 0H7V7h1v2zm3-8H1c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zM2 4H1V2h1v2zm2 0H3V2h1v2zm2 0H5V2h1v2zm2 0H7V2h1v2zm3-1h-1V2h1v1zm0 8H1c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h10c.55 0 1-.45 1-1v-2c0-.55-.45-1-1-1zm-9 3H1v-2h1v2zm2 0H3v-2h1v2zm2 0H5v-2h1v2zm2 0H7v-2h1v2z\"/>"},"settings":{"name":"settings","figma":{"id":"0:751","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["sliders","filters","controls","levels"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 7H3V2h1v5zm-1 7h1v-3H3v3zm5 0h1V8H8v6zm5 0h1v-2h-1v2zm1-12h-1v6h1V2zM9 2H8v2h1V2zM5 8H2c-.55 0-1 .45-1 1s.45 1 1 1h3c.55 0 1-.45 1-1s-.45-1-1-1zm5-3H7c-.55 0-1 .45-1 1s.45 1 1 1h3c.55 0 1-.45 1-1s-.45-1-1-1zm5 4h-3c-.55 0-1 .45-1 1s.45 1 1 1h3c.55 0 1-.45 1-1s-.45-1-1-1z\"/>"},"shield":{"name":"shield","figma":{"id":"0:762","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["protect","shield","lock"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 0L0 2v6.02C0 12.69 5.31 16 7 16c1.69 0 7-3.31 7-7.98V2L7 0zM5 11l1.14-2.8a.568.568 0 0 0-.25-.59C5.33 7.25 5 6.66 5 6c0-1.09.89-2 1.98-2C8.06 4 9 4.91 9 6c0 .66-.33 1.25-.89 1.61-.19.13-.3.36-.25.59L9 11H5z\"/>"},"sign-in":{"name":"sign-in","figma":{"id":"0:764","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["door","arrow","direction","enter","log in"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 6.75V12h4V8h1v4c0 .55-.45 1-1 1H7v3l-5.45-2.72c-.33-.17-.55-.52-.55-.91V1c0-.55.45-1 1-1h9c.55 0 1 .45 1 1v3h-1V1H3l4 2v2.25L10 3v2h4v2h-4v2L7 6.75z\"/>"},"sign-out":{"name":"sign-out","figma":{"id":"0:768","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["door","arrow","direction","leave","log out"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 9V7H8V5h4V3l4 3-4 3zm-2 3H6V3L2 1h8v3h1V1c0-.55-.45-1-1-1H1C.45 0 0 .45 0 1v11.38c0 .39.22.73.55.91L6 16.01V13h4c.55 0 1-.45 1-1V8h-1v4z\"/>"},"smiley":{"name":"smiley","figma":{"id":"0:772","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["emoji","smile","mood","emotion"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm4.81 12.81a6.72 6.72 0 0 1-2.17 1.45c-.83.36-1.72.53-2.64.53-.92 0-1.81-.17-2.64-.53-.81-.34-1.55-.83-2.17-1.45a6.773 6.773 0 0 1-1.45-2.17A6.59 6.59 0 0 1 1.21 8c0-.92.17-1.81.53-2.64.34-.81.83-1.55 1.45-2.17.62-.62 1.36-1.11 2.17-1.45A6.59 6.59 0 0 1 8 1.21c.92 0 1.81.17 2.64.53.81.34 1.55.83 2.17 1.45.62.62 1.11 1.36 1.45 2.17.36.83.53 1.72.53 2.64 0 .92-.17 1.81-.53 2.64-.34.81-.83 1.55-1.45 2.17zM4 6.8v-.59c0-.66.53-1.19 1.2-1.19h.59c.66 0 1.19.53 1.19 1.19v.59c0 .67-.53 1.2-1.19 1.2H5.2C4.53 8 4 7.47 4 6.8zm5 0v-.59c0-.66.53-1.19 1.2-1.19h.59c.66 0 1.19.53 1.19 1.19v.59c0 .67-.53 1.2-1.19 1.2h-.59C9.53 8 9 7.47 9 6.8zm4 3.2c-.72 1.88-2.91 3-5 3s-4.28-1.13-5-3c-.14-.39.23-1 .66-1h8.59c.41 0 .89.61.75 1z\"/>"},"squirrel":{"name":"squirrel","figma":{"id":"0:779","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["ship","shipit","launch"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.75 1c-2.21 0-4 1.31-4 2.92 0 1.94.5 3.03 0 6.08 0-4.5-2.77-6.34-4-6.34.05-.5-.48-.66-.48-.66s-.22.11-.3.34c-.27-.31-.56-.27-.56-.27l-.13.58S.45 4.29.43 6.87c.2.33 1.53.6 2.47.43.89.05.67.79.47.99C2.53 9.13 1.75 8 .75 8s-1 1 0 1 1 1 3 1c-3.09 1.2 0 4 0 4h-1c-1 0-1 1-1 1h6c3 0 5-1 5-3.47 0-.85-.43-1.79-1-2.53-1.11-1.46.23-2.68 1-2 .77.68 3 1 3-2 0-2.21-1.79-4-4-4zm-9.5 5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5z\"/>"},"star":{"name":"star","figma":{"id":"0:781","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save","remember","like"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z\"/>"},"stop":{"name":"stop","figma":{"id":"0:785","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["block","spam","report"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 1H4L0 5v6l4 4h6l4-4V5l-4-4zm3 9.5L9.5 14h-5L1 10.5v-5L4.5 2h5L13 5.5v5zM6 4h2v5H6V4zm0 6h2v2H6v-2z\"/>"},"sync":{"name":"sync","figma":{"id":"0:791","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["cycle","refresh","loop"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10.236 7.4a4.15 4.15 0 0 1-1.2 3.6 4.346 4.346 0 0 1-5.41.54l1.17-1.14-4.3-.6.6 4.2 1.31-1.26c2.36 1.74 5.7 1.57 7.84-.54a5.876 5.876 0 0 0 1.74-4.46l-1.75-.34zM2.956 5a4.346 4.346 0 0 1 5.41-.54L7.196 5.6l4.3.6-.6-4.2-1.31 1.26c-2.36-1.74-5.7-1.57-7.85.54-1.24 1.23-1.8 2.85-1.73 4.46l1.75.35A4.17 4.17 0 0 1 2.956 5z\"/>"},"tag":{"name":"tag","figma":{"id":"0:795","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["release"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.73 1.73C7.26 1.26 6.62 1 5.96 1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39 1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38 7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16 1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z\"/>"},"tasklist":{"name":"tasklist","figma":{"id":"0:800","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["todo"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.41 9H7.59C7 9 7 8.59 7 8c0-.59 0-1 .59-1h7.81c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM9.59 4C9 4 9 3.59 9 3c0-.59 0-1 .59-1h5.81c.59 0 .59.41.59 1 0 .59 0 1-.59 1H9.59zM0 3.91l1.41-1.3L3 4.2 7.09 0 8.5 1.41 3 6.91l-3-3zM7.59 12h7.81c.59 0 .59.41.59 1 0 .59 0 1-.59 1H7.59C7 14 7 13.59 7 13c0-.59 0-1 .59-1z\"/>"},"telescope":{"name":"telescope","figma":{"id":"0:806","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["science","space","look","view","explore"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.59 9l3 6h-1l-2-4v5h-1v-6l-2 5h-1l2-5 2-1zm-1-9h-1v1h1V0zm-2 3h-1v1h1V3zm-3-2h-1v1h1V1zM.22 9a.52.52 0 0 0-.16.67l.55.92c.13.23.41.31.64.2l1.39-.66-1.16-2-1.27.86.01.01zm7.89-5.39l-5.8 3.95L3.54 9.7l6.33-3.03L8.1 3.61h.01zm4.22 1.28l-1.47-2.52a.51.51 0 0 0-.72-.17l-1.2.83 1.84 3.2 1.33-.64c.27-.13.36-.44.22-.7z\"/>"},"terminal":{"name":"terminal","figma":{"id":"0:815","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["code","ops","shell"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 10h4v1H7v-1zm-3 1l3-3-3-3-.75.75L5.5 8l-2.25 2.25L4 11zm10-8v10c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h12c.55 0 1 .45 1 1zm-1 0H1v10h12V3z\"/>"},"text-size":{"name":"text-size","figma":{"id":"0:821","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["font","size","text"],"width":18,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13.62 9.08L12.1 3.66h-.06l-1.5 5.42h3.08zM5.7 10.13S4.68 6.52 4.53 6.02h-.08l-1.13 4.11H5.7zM17.31 14h-2.25l-.95-3.25h-4.07L9.09 14H6.84l-.69-2.33H2.87L2.17 14H0l3.3-9.59h2.5l2.17 6.34L10.86 2h2.52l3.94 12h-.01z\"/>"},"three-bars":{"name":"three-bars","figma":{"id":"0:826","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hamburger","menu","dropdown"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.41 9H.59C0 9 0 8.59 0 8c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zm0-4H.59C0 5 0 4.59 0 4c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM.59 11H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1H.59C0 13 0 12.59 0 12c0-.59 0-1 .59-1z\"/>"},"thumbsdown":{"name":"thumbsdown","figma":{"id":"0:831","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["thumb","thumbsdown","rejected","dislike"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.98 7.83l-.97-5.95C14.84.5 13.13 0 12 0H5.69c-.2 0-.38.05-.53.14L3.72 1H2C.94 1 0 1.94 0 3v4c0 1.06.94 2.02 2 2h2c.91 0 1.39.45 2.39 1.55.91 1 .88 1.8.63 3.27-.08.5.06 1 .42 1.42.39.47.98.77 1.56.77 1.83 0 3-3.72 3-5.02l-.02-.98h2.04c1.16 0 1.95-.8 1.98-1.97 0-.06.02-.13-.02-.2v-.01zm-1.97 1.19h-1.99c-.7 0-1.03.28-1.03.97l.03 1.03c0 1.27-1.17 4-2 4-.5 0-1.08-.5-1-1 .25-1.58.34-2.78-.89-4.14C6.11 8.75 5.36 8 4 8V2l1.67-1H12c.73 0 1.95.31 2 1l.02.02 1 6c-.03.64-.38 1-1 1h-.01z\"/>"},"thumbsup":{"name":"thumbsup","figma":{"id":"0:835","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["thumb","thumbsup","prop","ship","like"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 14c-.05.69-1.27 1-2 1H5.67L4 14V8c1.36 0 2.11-.75 3.13-1.88 1.23-1.36 1.14-2.56.88-4.13-.08-.5.5-1 1-1 .83 0 2 2.73 2 4l-.02 1.03c0 .69.33.97 1.02.97h2c.63 0 .98.36 1 1l-1 6L14 14zm0-8h-2.02l.02-.98C12 3.72 10.83 0 9 0c-.58 0-1.17.3-1.56.77-.36.41-.5.91-.42 1.41.25 1.48.28 2.28-.63 3.28-1 1.09-1.48 1.55-2.39 1.55H2C.94 7 0 7.94 0 9v4c0 1.06.94 2 2 2h1.72l1.44.86c.16.09.33.14.52.14h6.33c1.13 0 2.84-.5 3-1.88l.98-5.95c.02-.08.02-.14.02-.2-.03-1.17-.84-1.97-2-1.97H14z\"/>"},"tools":{"name":"tools","figma":{"id":"0:839","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["screwdriver","wrench","settings"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.48 7.27c.26.26 1.28 1.33 1.28 1.33l.56-.58-.88-.91 1.69-1.8s-.76-.74-.43-.45c.32-1.19.03-2.51-.87-3.44C4.93.5 3.66.2 2.52.51l1.93 2-.51 1.96-1.89.52-1.93-2C-.19 4.17.1 5.48 1 6.4c.94.98 2.29 1.26 3.48.87zm6.44 1.94l-2.33 2.3 3.84 3.98c.31.33.73.49 1.14.49.41 0 .82-.16 1.14-.49.63-.65.63-1.7 0-2.35l-3.79-3.93zM16 2.53L13.55 0 6.33 7.46l.88.91-4.31 4.46-.99.53-1.39 2.27.35.37 2.2-1.44.51-1.02L7.9 9.08l.88.91L16 2.53z\"/>"},"trashcan":{"name":"trashcan","figma":{"id":"0:844","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["garbage","rubbish","recycle","delete"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z\"/>"},"triangle-down":{"name":"triangle-down","figma":{"id":"0:847","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 5l6 6 6-6H0z\"/>"},"triangle-left":{"name":"triangle-left","figma":{"id":"0:849","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 2L0 8l6 6V2z\"/>"},"triangle-right":{"name":"triangle-right","figma":{"id":"0:851","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 14l6-6-6-6v12z\"/>"},"triangle-up":{"name":"triangle-up","figma":{"id":"0:853","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 11L6 5l-6 6h12z\"/>"},"unfold":{"name":"unfold","figma":{"id":"0:857","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["expand","open","reveal"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.5 7.5L14 10c0 .55-.45 1-1 1H9v-1h3.5l-2-2h-7l-2 2H5v1H1c-.55 0-1-.45-1-1l2.5-2.5L0 5c0-.55.45-1 1-1h4v1H1.5l2 2h7l2-2H9V4h4c.55 0 1 .45 1 1l-2.5 2.5zM6 6h2V3h2L7 0 4 3h2v3zm2 3H6v3H4l3 3 3-3H8V9z\"/>"},"unmute":{"name":"unmute","figma":{"id":"0:862","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["loud","volume","audio","sound","play"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 7.96c0 1.09-.45 2.09-1.17 2.83l-.67-.67c.55-.56.89-1.31.89-2.16 0-.85-.34-1.61-.89-2.16l.67-.67A3.99 3.99 0 0 1 12 7.96zM7.72 2.22L4 5.94H2c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h2l3.72 3.72c.47.47 1.28.14 1.28-.53V2.75c0-.67-.81-1-1.28-.53zm5.94.08l-.67.67a6.996 6.996 0 0 1 2.06 4.98c0 1.94-.78 3.7-2.06 4.98l.67.67A7.973 7.973 0 0 0 16 7.94c0-2.22-.89-4.22-2.34-5.66v.02zm-1.41 1.41l-.69.67a5.05 5.05 0 0 1 1.48 3.58c0 1.39-.56 2.66-1.48 3.56l.69.67A5.97 5.97 0 0 0 14 7.96c0-1.65-.67-3.16-1.75-4.25z\"/>"},"project":{"name":"project","figma":{"id":"0:868","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["board","kanban","columns","scrum"],"width":15,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z\"/>"},"kebab-horizontal":{"name":"kebab-horizontal","figma":{"id":"0:875","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["kebab","dot","menu","more"],"width":13,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z\"/>"},"kebab-vertical":{"name":"kebab-vertical","figma":{"id":"0:880","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["kebab","dot","menu","more"],"width":3,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 2.5a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0zm0 5a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0zM1.5 14a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"/>"},"report":{"name":"report","figma":{"id":"0:885","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["report","abuse","flag"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 2a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H7l-4 4v-4H1a1 1 0 0 1-1-1V2zm1 0h14v9H6.5L4 13.5V11H1V2zm6 6h2v2H7V8zm0-5h2v4H7V3z\"/>"},"note":{"name":"note","figma":{"id":"0:891","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["card","paper","ticket"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 10h4V9H3v1zm0-2h6V7H3v1zm0-2h8V5H3v1zm10 6H1V3h12v9zM1 2c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1H1z\"/>"},"screen-full":{"name":"screen-full","figma":{"id":"0:898","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fullscreen","expand"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 10h1v3c0 .547-.453 1-1 1h-3v-1h3v-3zM1 10H0v3c0 .547.453 1 1 1h3v-1H1v-3zm0-7h3V2H1c-.547 0-1 .453-1 1v3h1V3zm1 1h10v8H2V4zm2 6h6V6H4v4zm6-8v1h3v3h1V3c0-.547-.453-1-1-1h-3z\"/>"},"screen-normal":{"name":"screen-normal","figma":{"id":"0:906","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fullscreen","expand","exit"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 4H0V3h2V1h1v2c0 .547-.453 1-1 1zm0 8H0v1h2v2h1v-2c0-.547-.453-1-1-1zm9-2c0 .547-.453 1-1 1H4c-.547 0-1-.453-1-1V6c0-.547.453-1 1-1h6c.547 0 1 .453 1 1v4zM9 7H5v2h4V7zm2 6v2h1v-2h2v-1h-2c-.547 0-1 .453-1 1zm1-10V1h-1v2c0 .547.453 1 1 1h2V3h-2z\"/>"},"unverified":{"name":"unverified","figma":{"id":"0:914","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["insecure","untrusted","signed"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.68 7.07L14.6 5.73c-.17-.22-.28-.48-.31-.77l-.19-1.7a1.51 1.51 0 0 0-1.33-1.33l-1.7-.19c-.3-.03-.56-.16-.78-.33L8.95.33c-.55-.44-1.33-.44-1.88 0L5.73 1.41c-.22.17-.48.28-.77.31l-1.7.19c-.7.08-1.25.63-1.33 1.33l-.19 1.7c-.03.3-.16.56-.33.78L.33 7.06c-.44.55-.44 1.33 0 1.88l1.08 1.34c.17.22.28.48.31.77l.19 1.7c.08.7.63 1.25 1.33 1.33l1.7.19c.3.03.56.16.78.33l1.34 1.08c.55.44 1.33.44 1.88 0l1.34-1.08c.22-.17.48-.28.77-.31l1.7-.19c.7-.08 1.25-.63 1.33-1.33l.19-1.7c.03-.3.16-.56.33-.78l1.08-1.34c.44-.55.44-1.33 0-1.88zm-6.67 4.44c0 .28-.22.5-.5.5h-1c-.27 0-.5-.22-.5-.5v-1c0-.28.23-.5.5-.5h1c.28 0 .5.22.5.5v1zm1.56-4.89c-.06.17-.17.33-.3.47-.13.16-.14.19-.33.38-.16.17-.31.3-.52.45-.11.09-.2.19-.28.27-.08.08-.14.17-.19.27-.05.1-.08.19-.11.3-.03.11-.03.13-.03.25H7.14c0-.22 0-.31.03-.48.03-.19.08-.36.14-.52.06-.14.14-.28.25-.42.11-.13.23-.25.41-.38.27-.19.36-.3.48-.52.12-.22.2-.38.2-.59 0-.27-.06-.45-.2-.58-.13-.13-.31-.19-.58-.19-.09 0-.19.02-.3.05-.11.03-.17.09-.25.16-.08.07-.14.11-.2.2a.41.41 0 0 0-.09.28h-2c0-.38.13-.56.27-.83.16-.27.36-.5.61-.67.25-.17.55-.3.88-.38.33-.08.7-.13 1.09-.13.44 0 .83.05 1.17.13.34.09.63.22.88.39.23.17.41.38.55.63.13.25.19.55.19.88 0 .22 0 .42-.08.59l-.02-.01z\"/>"},"verified":{"name":"verified","figma":{"id":"0:919","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["trusted","secure","trustworthy","signed"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.68 7.07L14.6 5.73c-.17-.22-.28-.48-.31-.77l-.19-1.7a1.51 1.51 0 0 0-1.33-1.33l-1.7-.19c-.3-.03-.56-.16-.78-.33L8.95.33c-.55-.44-1.33-.44-1.88 0L5.73 1.41c-.22.17-.48.28-.77.31l-1.7.19c-.7.08-1.25.63-1.33 1.33l-.19 1.7c-.03.3-.16.56-.33.78L.33 7.06c-.44.55-.44 1.33 0 1.88l1.08 1.34c.17.22.28.48.31.77l.19 1.7c.08.7.63 1.25 1.33 1.33l1.7.19c.3.03.56.16.78.33l1.34 1.08c.55.44 1.33.44 1.88 0l1.34-1.08c.22-.17.48-.28.77-.31l1.7-.19c.7-.08 1.25-.63 1.33-1.33l.19-1.7c.03-.3.16-.56.33-.78l1.08-1.34c.44-.55.44-1.33 0-1.88zm-9.17 4.94l-3.5-3.5 1.5-1.5 2 2 5-5 1.5 1.55-6.5 6.45z\"/>"},"versions":{"name":"versions","figma":{"id":"0:923","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["history","commits"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 3H7c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zm-1 8H8V5h4v6zM4 4h1v1H4v6h1v1H4c-.55 0-1-.45-1-1V5c0-.55.45-1 1-1zM1 5h1v1H1v4h1v1H1c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1z\"/>"},"watch":{"name":"watch","figma":{"id":"0:929","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["wait","hourglass","time","date"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 8h2v1H5V5h1v3zm6 0c0 2.22-1.2 4.16-3 5.19V15c0 .55-.45 1-1 1H4c-.55 0-1-.45-1-1v-1.81C1.2 12.16 0 10.22 0 8s1.2-4.16 3-5.19V1c0-.55.45-1 1-1h4c.55 0 1 .45 1 1v1.81c1.8 1.03 3 2.97 3 5.19zm-1 0c0-2.77-2.23-5-5-5S1 5.23 1 8s2.23 5 5 5 5-2.23 5-5z\"/>"},"x":{"name":"x","figma":{"id":"0:932","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["remove","close","delete"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.71 8.23l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75L1 11.98l3.75-3.75L1 4.48 2.48 3l3.75 3.75L9.98 3l1.48 1.48-3.75 3.75z\"/>"},"zap":{"name":"zap","figma":{"id":"0:934","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["electricity","lightning","props","like","star","save"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 7H6l3-7-9 9h4l-3 7 9-9z\"/>"},"key":{"name":"key","figma":{"id":"0:938","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["key","lock","secure","safe"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12.83 2.17C12.08 1.42 11.14 1.03 10 1c-1.13.03-2.08.42-2.83 1.17S6.04 3.86 6.01 5c0 .3.03.59.09.89L0 12v1l1 1h2l1-1v-1h1v-1h1v-1h2l1.09-1.11c.3.08.59.11.91.11 1.14-.03 2.08-.42 2.83-1.17S13.97 6.14 14 5c-.03-1.14-.42-2.08-1.17-2.83zM11 5.38c-.77 0-1.38-.61-1.38-1.38 0-.77.61-1.38 1.38-1.38.77 0 1.38.61 1.38 1.38 0 .77-.61 1.38-1.38 1.38z\"/>"},"grabber":{"name":"grabber","figma":{"id":"0:942","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["mover","drap","drop","sort"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 4v1H0V4h8zM0 8h8V7H0v1zm0 3h8v-1H0v1z\"/>"},"plus-small":{"name":"plus-small","figma":{"id":"0:947","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["add","new","more","small"],"width":7,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 4H3v3H0v1h3v3h1V8h3V7H4V4z\"/>"},"light-bulb":{"name":"light-bulb","figma":{"id":"0:951","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["idea"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z\"/>"},"link-external":{"name":"link-external","figma":{"id":"0:956","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["out","see","more","go","to"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 10h1v3c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h3v1H1v10h10v-3zM6 2l2.25 2.25L5 7.5 6.5 9l3.25-3.25L12 8V2H6z\"/>"}}
    \ No newline at end of file
    +{"alert":{"name":"alert","figma":{"id":"0:5","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["warning","triangle","exclamation","point"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z\"/>"},"arrow-down":{"name":"arrow-down","figma":{"id":"0:8","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 7V3H3v4H0l5 6 5-6H7z\"/>"},"arrow-left":{"name":"arrow-left","figma":{"id":"0:10","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 3L0 8l6 5v-3h4V6H6V3z\"/>"},"arrow-right":{"name":"arrow-right","figma":{"id":"0:12","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 8L4 3v3H0v4h4v3l6-5z\"/>"},"arrow-up":{"name":"arrow-up","figma":{"id":"0:14","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 3L0 9h3v4h4V9h3L5 3z\"/>"},"arrow-both":{"name":"arrow-both","figma":{"id":"7345:13","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","left","right"],"width":20,"height":16,"path":"<path d=\"M0 8l6-5v3h8V3l6 5-6 5v-3H6v3L0 8z\"/>"},"arrow-small-down":{"name":"arrow-small-down","figma":{"id":"0:16","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 7V5H2v2H0l3 4 3-4H4z\"/>"},"arrow-small-left":{"name":"arrow-small-left","figma":{"id":"0:18","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 7V5L0 8l4 3V9h2V7H4z\"/>"},"arrow-small-right":{"name":"arrow-small-right","figma":{"id":"0:20","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 8L2 5v2H0v2h2v2l4-3z\"/>"},"arrow-small-up":{"name":"arrow-small-up","figma":{"id":"0:22","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["point","direction","little","tiny"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 5L0 9h2v2h2V9h2L3 5z\"/>"},"beaker":{"name":"beaker","figma":{"id":"0:26","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["experiment","labs","experimental","feature","test","science","education","study","development","testing"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14.38 14.59L11 7V3h1V2H3v1h1v4L.63 14.59A1 1 0 0 0 1.54 16h11.94c.72 0 1.2-.75.91-1.41h-.01zM3.75 10L5 7V3h5v4l1.25 3h-7.5zM8 8h1v1H8V8zM7 7H6V6h1v1zm0-3h1v1H7V4zm0-3H6V0h1v1z\"/>"},"bell":{"name":"bell","figma":{"id":"0:34","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["notification"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13.99 11.991v1H0v-1l.73-.58c.769-.769.809-2.547 1.189-4.416.77-3.767 4.077-4.996 4.077-4.996 0-.55.45-1 .999-1 .55 0 1 .45 1 1 0 0 3.387 1.229 4.156 4.996.38 1.879.42 3.657 1.19 4.417l.659.58h-.01zM6.995 15.99c1.11 0 1.999-.89 1.999-1.999H4.996c0 1.11.89 1.999 1.999 1.999z\"/>"},"bold":{"name":"bold","figma":{"id":"0:38","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["markdown","bold","text"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1 2h3.83c2.48 0 4.3.75 4.3 2.95 0 1.14-.63 2.23-1.67 2.61v.06c1.33.3 2.3 1.23 2.3 2.86 0 2.39-1.97 3.52-4.61 3.52H1V2zm3.66 4.95c1.67 0 2.38-.66 2.38-1.69 0-1.17-.78-1.61-2.34-1.61H3.13v3.3h1.53zm.27 5.39c1.77 0 2.75-.64 2.75-1.98 0-1.27-.95-1.81-2.75-1.81h-1.8v3.8h1.8v-.01z\"/>"},"book":{"name":"book","figma":{"id":"0:43","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","wiki","readme"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 5h4v1H3V5zm0 3h4V7H3v1zm0 2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1 1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45 1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z\"/>"},"bookmark":{"name":"bookmark","figma":{"id":"0:54","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["tab","star"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10 16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6 3.12 7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7 2.16 2.3.03c.23 0 .27.08.09.23h.01z\"/>"},"briefcase":{"name":"briefcase","figma":{"id":"0:58","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["suitcase","business"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 4V3c0-.55-.45-1-1-1H6c-.55 0-1 .45-1 1v1H1c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1H9zM6 3h2v1H6V3zm7 6H8v1H6V9H1V5h1v3h10V5h1v4z\"/>"},"broadcast":{"name":"broadcast","figma":{"id":"0:63","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["rss","radio","signal"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 9H8c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1H7c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1H6c-.55 0-1 .45-1 1v2h1v3c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-3h1v-2c0-.55-.45-1-1-1zM7 7h1v1H7V7zm2 4H8v4H7v-4H6v-1h3v1zm2.09-3.5c0-1.98-1.61-3.59-3.59-3.59A3.593 3.593 0 0 0 4 8.31v1.98c-.61-.77-1-1.73-1-2.8 0-2.48 2.02-4.5 4.5-4.5S12 5.01 12 7.49c0 1.06-.39 2.03-1 2.8V8.31c.06-.27.09-.53.09-.81zm3.91 0c0 2.88-1.63 5.38-4 6.63v-1.05a6.553 6.553 0 0 0 3.09-5.58A6.59 6.59 0 0 0 7.5.91 6.59 6.59 0 0 0 .91 7.5c0 2.36 1.23 4.42 3.09 5.58v1.05A7.497 7.497 0 0 1 7.5 0C11.64 0 15 3.36 15 7.5z\"/>"},"browser":{"name":"browser","figma":{"id":"0:70","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["window","web"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 3h1v1H5V3zM3 3h1v1H3V3zM1 3h1v1H1V3zm12 10H1V5h12v8zm0-9H7V3h6v1zm1-1c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V3z\"/>"},"bug":{"name":"bug","figma":{"id":"0:78","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["insect","issue"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 10h3V9h-3V8l3.17-1.03-.34-.94L11 7V6c0-.55-.45-1-1-1V4c0-.48-.36-.88-.83-.97L10.2 2H12V1H9.8l-2 2h-.59L5.2 1H3v1h1.8l1.03 1.03C5.36 3.12 5 3.51 5 4v1c-.55 0-1 .45-1 1v1l-2.83-.97-.34.94L4 8v1H1v1h3v1L.83 12.03l.34.94L4 12v1c0 .55.45 1 1 1h1l1-1V6h1v7l1 1h1c.55 0 1-.45 1-1v-1l2.83.97.34-.94L11 11v-1zM9 5H6V4h3v1z\"/>"},"calendar":{"name":"calendar","figma":{"id":"0:82","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["time","day","month","year","date","appointment"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 2h-1v1.5c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5V2H6v1.5c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5V2H2c-.55 0-1 .45-1 1v11c0 .55.45 1 1 1h11c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 12H2V5h11v9zM5 3H4V1h1v2zm6 0h-1V1h1v2zM6 7H5V6h1v1zm2 0H7V6h1v1zm2 0H9V6h1v1zm2 0h-1V6h1v1zM4 9H3V8h1v1zm2 0H5V8h1v1zm2 0H7V8h1v1zm2 0H9V8h1v1zm2 0h-1V8h1v1zm-8 2H3v-1h1v1zm2 0H5v-1h1v1zm2 0H7v-1h1v1zm2 0H9v-1h1v1zm2 0h-1v-1h1v1zm-8 2H3v-1h1v1zm2 0H5v-1h1v1zm2 0H7v-1h1v1zm2 0H9v-1h1v1z\"/>"},"check":{"name":"check","figma":{"id":"0:104","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["mark","yes","confirm","accept","ok","success"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z\"/>"},"checklist":{"name":"checklist","figma":{"id":"0:108","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["todo","tasks"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 8.5l-6 6-3-3L8.5 10l1.5 1.5L14.5 7 16 8.5zM5.7 12.2l.8.8H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h7c.55 0 1 .45 1 1v6.5l-.8-.8c-.39-.39-1.03-.39-1.42 0L5.7 10.8a.996.996 0 0 0 0 1.41v-.01zM4 4h5V3H4v1zm0 2h5V5H4v1zm0 2h3V7H4v1zM3 9H2v1h1V9zm0-2H2v1h1V7zm0-2H2v1h1V5zm0-2H2v1h1V3z\"/>"},"chevron-down":{"name":"chevron-down","figma":{"id":"0:117","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 11L0 6l1.5-1.5L5 8.25 8.5 4.5 10 6l-5 5z\"/>"},"chevron-left":{"name":"chevron-left","figma":{"id":"0:119","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5.5 3L7 4.5 3.25 8 7 11.5 5.5 13l-5-5 5-5z\"/>"},"chevron-right":{"name":"chevron-right","figma":{"id":"0:121","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z\"/>"},"chevron-up":{"name":"chevron-up","figma":{"id":"0:123","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["triangle","arrow"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 10l-1.5 1.5L5 7.75 1.5 11.5 0 10l5-5 5 5z\"/>"},"circle-slash":{"name":"circle-slash","figma":{"id":"0:127","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["no","deny","fail","failure","error","bad"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm0 1.3c1.3 0 2.5.44 3.47 1.17l-8 8A5.755 5.755 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zm0 11.41c-1.3 0-2.5-.44-3.47-1.17l8-8c.73.97 1.17 2.17 1.17 3.47 0 3.14-2.56 5.7-5.7 5.7z\"/>"},"circuit-board":{"name":"circuit-board","figma":{"id":"0:132","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["developer","hardware","electricity"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 5c0-.55.45-1 1-1s1 .45 1 1-.45 1-1 1-1-.45-1-1zm8 0c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zm0 6c0-.55-.45-1-1-1s-1 .45-1 1 .45 1 1 1 1-.45 1-1zm2-10H5v2.17c.36.19.64.47.83.83h2.34c.42-.78 1.33-1.28 2.34-1.05.75.19 1.36.8 1.53 1.55.31 1.38-.72 2.59-2.05 2.59-.8 0-1.48-.44-1.83-1.09H5.83c-.42.8-1.33 1.28-2.34 1.03-.73-.17-1.34-.78-1.52-1.52C1.72 4.49 2.2 3.59 3 3.17V1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1l5-5h2.17c.42-.78 1.33-1.28 2.34-1.05.75.19 1.36.8 1.53 1.55.31 1.38-.72 2.59-2.05 2.59-.8 0-1.48-.44-1.83-1.09H6.99L4 15h9c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1z\"/>"},"clippy":{"name":"clippy","figma":{"id":"0:138","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["copy","paste","save","capture","clipboard"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z\"/>"},"clock":{"name":"clock","figma":{"id":"0:147","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["time","hour","minute","second","watch"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 8h3v2H7c-.55 0-1-.45-1-1V4h2v4zM7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7z\"/>"},"cloud-download":{"name":"cloud-download","figma":{"id":"0:152","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save","install","get"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 12h2l-3 3-3-3h2V7h2v5zm3-8c0-.44-.91-3-4.5-3C5.08 1 3 2.92 3 5 1.02 5 0 6.52 0 8c0 1.53 1 3 3 3h3V9.7H3C1.38 9.7 1.3 8.28 1.3 8c0-.17.05-1.7 1.7-1.7h1.3V5c0-1.39 1.56-2.7 3.2-2.7 2.55 0 3.13 1.55 3.2 1.8v1.2H12c.81 0 2.7.22 2.7 2.2 0 2.09-2.25 2.2-2.7 2.2h-2V11h2c2.08 0 4-1.16 4-3.5C16 5.06 14.08 4 12 4z\"/>"},"cloud-upload":{"name":"cloud-upload","figma":{"id":"0:156","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["put","export"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 9H5l3-3 3 3H9v5H7V9zm5-4c0-.44-.91-3-4.5-3C5.08 2 3 3.92 3 6 1.02 6 0 7.52 0 9c0 1.53 1 3 3 3h3v-1.3H3c-1.62 0-1.7-1.42-1.7-1.7 0-.17.05-1.7 1.7-1.7h1.3V6c0-1.39 1.56-2.7 3.2-2.7 2.55 0 3.13 1.55 3.2 1.8v1.2H12c.81 0 2.7.22 2.7 2.2 0 2.09-2.25 2.2-2.7 2.2h-2V12h2c2.08 0 4-1.16 4-3.5C16 6.06 14.08 5 12 5z\"/>"},"code":{"name":"code","figma":{"id":"0:160","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["brackets"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z\"/>"},"comment-discussion":{"name":"comment-discussion","figma":{"id":"0:164","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["converse","talk"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 1H6c-.55 0-1 .45-1 1v2H1c-.55 0-1 .45-1 1v6c0 .55.45 1 1 1h1v3l3-3h4c.55 0 1-.45 1-1V9h1l3 3V9h1c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zM9 11H4.5L3 12.5V11H1V5h4v3c0 .55.45 1 1 1h3v2zm6-3h-2v1.5L11.5 8H6V2h9v6z\"/>"},"comment":{"name":"comment","figma":{"id":"0:169","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["speak","bubble"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 1H2c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h2v3.5L7.5 11H14c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 9H7l-2 2v-2H2V2h12v8z\"/>"},"credit-card":{"name":"credit-card","figma":{"id":"0:173","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["money","billing","payments","transactions"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 9H2V8h10v1zm4-6v9c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h14c.55 0 1 .45 1 1zm-1 3H1v6h14V6zm0-3H1v1h14V3zm-9 7H2v1h4v-1z\"/>"},"dash":{"name":"dash","figma":{"id":"0:178","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hyphen","range"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 7v2h8V7H0z\"/>"},"dashboard":{"name":"dashboard","figma":{"id":"0:182","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["speed","dial"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 5H8V4h1v1zm4 3h-1v1h1V8zM6 5H5v1h1V5zM5 8H4v1h1V8zm11-5.5l-.5-.5L9 7c-.06-.02-1 0-1 0-.55 0-1 .45-1 1v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-.92l6-5.58zm-1.59 4.09c.19.61.3 1.25.3 1.91 0 3.42-2.78 6.2-6.2 6.2-3.42 0-6.21-2.78-6.21-6.2 0-3.42 2.78-6.2 6.2-6.2 1.2 0 2.31.34 3.27.94l.94-.94A7.459 7.459 0 0 0 8.51 1C4.36 1 1 4.36 1 8.5 1 12.64 4.36 16 8.5 16c4.14 0 7.5-3.36 7.5-7.5 0-1.03-.2-2.02-.59-2.91l-1 1z\"/>"},"database":{"name":"database","figma":{"id":"0:190","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["disks","data"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 15c-3.31 0-6-.9-6-2v-2c0-.17.09-.34.21-.5.67.86 3 1.5 5.79 1.5s5.12-.64 5.79-1.5c.13.16.21.33.21.5v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V7c0-.11.04-.21.09-.31.03-.06.07-.13.12-.19C.88 7.36 3.21 8 6 8s5.12-.64 5.79-1.5c.05.06.09.13.12.19.05.1.09.21.09.31v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V3c0-1.1 2.69-2 6-2s6 .9 6 2v2c0 1.1-2.69 2-6 2zm0-5c-2.21 0-4 .45-4 1s1.79 1 4 1 4-.45 4-1-1.79-1-4-1z\"/>"},"desktop-download":{"name":"desktop-download","figma":{"id":"0:196","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["clone","download"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 6h3V0h2v6h3l-4 4-4-4zm11-4h-4v1h4v8H1V3h4V2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1z\"/>"},"device-camera-video":{"name":"device-camera-video","figma":{"id":"0:198","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["watch","view","media","stream"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.2 2.09L10 5.72V3c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h8c.55 0 1-.45 1-1V9.28l5.2 3.63c.33.23.8 0 .8-.41v-10c0-.41-.47-.64-.8-.41z\"/>"},"device-camera":{"name":"device-camera","figma":{"id":"0:202","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["photo","picture","image","snapshot"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 3H7c0-.55-.45-1-1-1H2c-.55 0-1 .45-1 1-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h14c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zM6 5H2V4h4v1zm4.5 7C8.56 12 7 10.44 7 8.5S8.56 5 10.5 5 14 6.56 14 8.5 12.44 12 10.5 12zM13 8.5c0 1.38-1.13 2.5-2.5 2.5S8 9.87 8 8.5 9.13 6 10.5 6 13 7.13 13 8.5z\"/>"},"device-desktop":{"name":"device-desktop","figma":{"id":"0:208","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["computer","monitor"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 2H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h5.34c-.25.61-.86 1.39-2.34 2h8c-1.48-.61-2.09-1.39-2.34-2H15c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm0 9H1V3h14v8z\"/>"},"device-mobile":{"name":"device-mobile","figma":{"id":"0:212","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["phone","iphone","cellphone"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 0H1C.45 0 0 .45 0 1v14c0 .55.45 1 1 1h8c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1zM5 15.3c-.72 0-1.3-.58-1.3-1.3 0-.72.58-1.3 1.3-1.3.72 0 1.3.58 1.3 1.3 0 .72-.58 1.3-1.3 1.3zM9 12H1V2h8v10z\"/>"},"diff-added":{"name":"diff-added","figma":{"id":"0:217","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["new","addition","plus"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM6 9H3V7h3V4h2v3h3v2H8v3H6V9z\"/>"},"diff-ignored":{"name":"diff-ignored","figma":{"id":"0:222","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["slash"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-8.5-2H3v-1.5L9.5 4H11v1.5L4.5 12z\"/>"},"diff-modified":{"name":"diff-modified","figma":{"id":"0:227","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["dot","changed","updated"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zM4 8c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3-3-1.34-3-3z\"/>"},"diff-removed":{"name":"diff-removed","figma":{"id":"0:232","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["deleted","subtracted","dash"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 13H1V2h12v12zm-2-5H3V7h8v2z\"/>"},"diff-renamed":{"name":"diff-renamed","figma":{"id":"0:237","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["moved","arrow"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 9H3V7h3V4l5 4-5 4V9zm8-7v12c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h12c.55 0 1 .45 1 1zm-1 0H1v12h12V2z\"/>"},"diff":{"name":"diff","figma":{"id":"0:242","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["difference","changes","compare"],"width":13,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 7h2v1H6v2H5V8H3V7h2V5h1v2zm-3 6h5v-1H3v1zM7.5 2L11 5.5V15c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h6.5zM10 6L7 3H1v12h9V6zM8.5 0H3v1h5l4 4v8h1V4.5L8.5 0z\"/>"},"ellipsis":{"name":"ellipsis","figma":{"id":"0:249","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["dot","read","more","hidden","expand"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 5H1c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V6c0-.55-.45-1-1-1zM4 9H2V7h2v2zm3 0H5V7h2v2zm3 0H8V7h2v2z\"/>"},"eye":{"name":"eye","figma":{"id":"0:255","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["look","watch","see"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z\"/>"},"file-binary":{"name":"file-binary","figma":{"id":"0:260","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["image","video","word","powerpoint","excel"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 12h1v1H2v-1h1v-2H2V9h2v3zm8-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5zM8 4H6v1h1v2H6v1h3V7H8V4zM2 4h3v4H2V4zm1 3h1V5H3v2zm3 2h3v4H6V9zm1 3h1v-2H7v2z\"/>"},"file-code":{"name":"file-code","figma":{"id":"0:270","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["text","javascript","html","css","php","ruby","coffeescript","sass","scss"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z\"/>"},"file-directory":{"name":"file-directory","figma":{"id":"0:276","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["folder"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z\"/>"},"file-media":{"name":"file-media","figma":{"id":"0:280","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["image","video","audio"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 5h2v2H6V5zm6-.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v11l3-5 2 4 2-2 3 3V5z\"/>"},"file-pdf":{"name":"file-pdf","figma":{"id":"0:285","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["adobe"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V4.5L8.5 1zM1 2h4a.68.68 0 0 0-.31.2 1.08 1.08 0 0 0-.23.47 4.22 4.22 0 0 0-.09 1.47c.06.609.173 1.211.34 1.8A21.78 21.78 0 0 1 3.6 8.6c-.5 1-.8 1.66-.91 1.84a7.156 7.156 0 0 0-.69.3c-.362.165-.699.38-1 .64V2zm4.42 4.8a5.65 5.65 0 0 0 1.17 2.09c.275.237.595.417.94.53-.64.09-1.23.2-1.81.33-.618.15-1.223.347-1.81.59s.22-.44.61-1.25c.365-.74.67-1.51.91-2.3l-.01.01zM11 14H1.5a.743.743 0 0 1-.17 0 2.12 2.12 0 0 0 .73-.44 10.14 10.14 0 0 0 1.78-2.38c.31-.13.58-.23.81-.31l.42-.14c.45-.13.94-.23 1.44-.33s1-.16 1.48-.2c.447.216.912.394 1.39.53.403.11.814.188 1.23.23h.38V14H11zm0-4.86a3.743 3.743 0 0 0-.64-.28 4.221 4.221 0 0 0-.75-.11c-.411.003-.822.03-1.23.08a3 3 0 0 1-1-.64 6.07 6.07 0 0 1-1.29-2.33c.111-.661.178-1.33.2-2 .02-.25.02-.5 0-.75a1.05 1.05 0 0 0-.2-.88.82.82 0 0 0-.61-.23H8l3 3v4.14z\"/>"},"file-submodule":{"name":"file-submodule","figma":{"id":"0:292","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["folder"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 7H4v7h9c.55 0 1-.45 1-1V8h-4V7zM9 9H5V8h4v1zm4-5H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h2V7c0-.55.45-1 1-1h6c.55 0 1 .45 1 1h3V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z\"/>"},"file-symlink-directory":{"name":"file-symlink-directory","figma":{"id":"0:298","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["folder","subfolder","link","alias"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM1 3h5v1H1V3zm6 9v-2c-.98-.02-1.84.22-2.55.7-.71.48-1.19 1.25-1.45 2.3.02-1.64.39-2.88 1.13-3.73C4.86 8.43 5.82 8 7.01 8V6l4 3-4 3H7z\"/>"},"file-symlink-file":{"name":"file-symlink-file","figma":{"id":"0:303","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["link","alias"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM6 4.5l4 3-4 3v-2c-.98-.02-1.84.22-2.55.7-.71.48-1.19 1.25-1.45 2.3.02-1.64.39-2.88 1.13-3.73.73-.84 1.69-1.27 2.88-1.27v-2H6z\"/>"},"file":{"name":"file","figma":{"id":"0:308","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["file","text","words"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z\"/>"},"file-zip":{"name":"file-zip","figma":{"id":"0:316","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["compress","archive"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8.5 1H1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V4.5L8.5 1zM11 14H1V2h3v1h1V2h3l3 3v9zM5 4V3h1v1H5zM4 4h1v1H4V4zm1 2V5h1v1H5zM4 6h1v1H4V6zm1 2V7h1v1H5zM4 9.28A2 2 0 0 0 3 11v1h4v-1a2 2 0 0 0-2-2V8H4v1.28zM6 10v1H4v-1h2z\"/>"},"flame":{"name":"flame","figma":{"id":"0:325","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fire","hot","burn","trending"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z\"/>"},"fold":{"name":"fold","figma":{"id":"0:329","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["unfold","hide","collapse"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 9l3 3H8v3H6v-3H4l3-3zm3-6H8V0H6v3H4l3 3 3-3zm4 2c0-.55-.45-1-1-1h-2.5l-1 1h3l-2 2h-7l-2-2h3l-1-1H1c-.55 0-1 .45-1 1l2.5 2.5L0 10c0 .55.45 1 1 1h2.5l1-1h-3l2-2h7l2 2h-3l1 1H13c.55 0 1-.45 1-1l-2.5-2.5L14 5z\"/>"},"gear":{"name":"gear","figma":{"id":"0:334","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["settings"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 8.77v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45-.69-1.92h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.23v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.75v.02zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z\"/>"},"gift":{"name":"gift","figma":{"id":"0:338","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["package","present","skill","craft","freebie"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 4h-1.38c.19-.33.33-.67.36-.91.06-.67-.11-1.22-.52-1.61C11.1 1.1 10.65 1 10.1 1h-.11c-.53.02-1.11.25-1.53.58-.42.33-.73.72-.97 1.2-.23-.48-.55-.88-.97-1.2-.42-.32-1-.58-1.53-.58h-.03c-.56 0-1.06.09-1.44.48-.41.39-.58.94-.52 1.61.03.23.17.58.36.91H1.98c-.55 0-1 .45-1 1v3h1v5c0 .55.45 1 1 1h9c.55 0 1-.45 1-1V8h1V5c0-.55-.45-1-1-1H13zm-4.78-.88c.17-.36.42-.67.75-.92.3-.23.72-.39 1.05-.41h.09c.45 0 .66.11.8.25s.33.39.3.95c-.05.19-.25.61-.5 1h-2.9l.41-.88v.01zM4.09 2.04c.13-.13.31-.25.91-.25.31 0 .72.17 1.03.41.33.25.58.55.75.92L7.2 4H4.3c-.25-.39-.45-.81-.5-1-.03-.56.16-.81.3-.95l-.01-.01zM7 12.99H3V8h4v5-.01zm0-6H2V5h5v2-.01zm5 6H8V8h4v5-.01zm1-6H8V5h5v2-.01z\"/>"},"gist-secret":{"name":"gist-secret","figma":{"id":"0:347","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["gist","secret","private"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 10.5L9 14H5l1-3.5L5.25 9h3.5L8 10.5zM10 6H4L2 7h10l-2-1zM9 2L7 3 5 2 4 5h6L9 2zm4.03 7.75L10 9l1 2-2 3h3.22c.45 0 .86-.31.97-.75l.56-2.28c.14-.53-.19-1.08-.72-1.22zM4 9l-3.03.75c-.53.14-.86.69-.72 1.22l.56 2.28c.11.44.52.75.97.75H5l-2-3 1-2z\"/>"},"gist":{"name":"gist","figma":{"id":"0:354","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["gist","github"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.5 5L10 7.5 7.5 10l-.75-.75L8.5 7.5 6.75 5.75 7.5 5zm-3 0L2 7.5 4.5 10l.75-.75L3.5 7.5l1.75-1.75L4.5 5zM0 13V2c0-.55.45-1 1-1h10c.55 0 1 .45 1 1v11c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1zm1 0h10V2H1v11z\"/>"},"git-branch":{"name":"git-branch","figma":{"id":"0:360","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fork","branch","git","duplicate"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"git-commit":{"name":"git-commit","figma":{"id":"0:366","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z\"/>"},"git-compare":{"name":"git-compare","figma":{"id":"0:370","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["difference","changes"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M5 12H4c-.27-.02-.48-.11-.69-.31-.21-.2-.3-.42-.31-.69V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V11c.03.78.34 1.47.94 2.06.6.59 1.28.91 2.06.94h1v2l3-3-3-3v2zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm11 9.48V5c-.03-.78-.34-1.47-.94-2.06-.6-.59-1.28-.91-2.06-.94H9V0L6 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 12 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"git-merge":{"name":"git-merge","figma":{"id":"0:376","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["join"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 7c-.73 0-1.38.41-1.73 1.02V8C7.22 7.98 6 7.64 5.14 6.98c-.75-.58-1.5-1.61-1.89-2.44A1.993 1.993 0 0 0 2 .99C.89.99 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2a1.993 1.993 0 0 0 1-3.72V7.67c.67.7 1.44 1.27 2.3 1.69.86.42 2.03.63 2.97.64v-.02c.36.61 1 1.02 1.73 1.02 1.11 0 2-.89 2-2 0-1.11-.89-2-2-2zm-6.8 6c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm8 6c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"git-pull-request":{"name":"git-pull-request","figma":{"id":"0:382","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["review"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"globe":{"name":"globe","figma":{"id":"0:389","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["world","earth","planet"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 1C3.14 1 0 4.14 0 8s3.14 7 7 7c.48 0 .94-.05 1.38-.14-.17-.08-.2-.73-.02-1.09.19-.41.81-1.45.2-1.8-.61-.35-.44-.5-.81-.91-.37-.41-.22-.47-.25-.58-.08-.34.36-.89.39-.94.02-.06.02-.27 0-.33 0-.08-.27-.22-.34-.23-.06 0-.11.11-.2.13-.09.02-.5-.25-.59-.33-.09-.08-.14-.23-.27-.34-.13-.13-.14-.03-.33-.11s-.8-.31-1.28-.48c-.48-.19-.52-.47-.52-.66-.02-.2-.3-.47-.42-.67-.14-.2-.16-.47-.2-.41-.04.06.25.78.2.81-.05.02-.16-.2-.3-.38-.14-.19.14-.09-.3-.95s.14-1.3.17-1.75c.03-.45.38.17.19-.13-.19-.3 0-.89-.14-1.11-.13-.22-.88.25-.88.25.02-.22.69-.58 1.16-.92.47-.34.78-.06 1.16.05.39.13.41.09.28-.05-.13-.13.06-.17.36-.13.28.05.38.41.83.36.47-.03.05.09.11.22s-.06.11-.38.3c-.3.2.02.22.55.61s.38-.25.31-.55c-.07-.3.39-.06.39-.06.33.22.27.02.5.08.23.06.91.64.91.64-.83.44-.31.48-.17.59.14.11-.28.3-.28.3-.17-.17-.19.02-.3.08-.11.06-.02.22-.02.22-.56.09-.44.69-.42.83 0 .14-.38.36-.47.58-.09.2.25.64.06.66-.19.03-.34-.66-1.31-.41-.3.08-.94.41-.59 1.08.36.69.92-.19 1.11-.09.19.1-.06.53-.02.55.04.02.53.02.56.61.03.59.77.53.92.55.17 0 .7-.44.77-.45.06-.03.38-.28 1.03.09.66.36.98.31 1.2.47.22.16.08.47.28.58.2.11 1.06-.03 1.28.31.22.34-.88 2.09-1.22 2.28-.34.19-.48.64-.84.92s-.81.64-1.27.91c-.41.23-.47.66-.66.8 3.14-.7 5.48-3.5 5.48-6.84 0-3.86-3.14-7-7-7L7 1zm1.64 6.56c-.09.03-.28.22-.78-.08-.48-.3-.81-.23-.86-.28 0 0-.05-.11.17-.14.44-.05.98.41 1.11.41.13 0 .19-.13.41-.05.22.08.05.13-.05.14zM6.34 1.7c-.05-.03.03-.08.09-.14.03-.03.02-.11.05-.14.11-.11.61-.25.52.03-.11.27-.58.3-.66.25zm1.23.89c-.19-.02-.58-.05-.52-.14.3-.28-.09-.38-.34-.38-.25-.02-.34-.16-.22-.19.12-.03.61.02.7.08.08.06.52.25.55.38.02.13 0 .25-.17.25zm1.47-.05c-.14.09-.83-.41-.95-.52-.56-.48-.89-.31-1-.41-.11-.1-.08-.19.11-.34.19-.15.69.06 1 .09.3.03.66.27.66.55.02.25.33.5.19.63h-.01z\"/>"},"graph":{"name":"graph","figma":{"id":"0:396","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["trend","stats","statistics"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z\"/>"},"heart":{"name":"heart","figma":{"id":"0:400","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["love","beat"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M9 2c-.97 0-1.69.42-2.2 1-.51.58-.78.92-.8 1-.02-.08-.28-.42-.8-1-.52-.58-1.17-1-2.2-1-1.632.086-2.954 1.333-3 3 0 .52.09 1.52.67 2.67C1.25 8.82 3.01 10.61 6 13c2.98-2.39 4.77-4.17 5.34-5.33C11.91 6.51 12 5.5 12 5c-.047-1.69-1.342-2.913-3-3z\"/>"},"history":{"name":"history","figma":{"id":"0:404","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["time","past","revert","back"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 13H6V6h5v2H8v5zM7 1C4.81 1 2.87 2.02 1.59 3.59L0 2v4h4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7s7-3.14 7-7-3.14-7-7-7z\"/>"},"home":{"name":"home","figma":{"id":"0:408","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["welcome","index","house","building"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 9l-3-3V2h-2v2L8 1 0 9h2l1 5c0 .55.45 1 1 1h8c.55 0 1-.45 1-1l1-5h2zm-4 5H9v-4H7v4H4L2.81 7.69 8 2.5l5.19 5.19L12 14z\"/>"},"horizontal-rule":{"name":"horizontal-rule","figma":{"id":"0:412","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hr"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1 7h2v2h1V3H3v3H1V3H0v6h1V7zm9 2V7H9v2h1zm0-3V4H9v2h1zM7 6V4h2V3H6v6h1V7h2V6H7zm-7 7h10v-2H0v2z\"/>"},"hubot":{"name":"hubot","figma":{"id":"0:419","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["robot","bot"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 6c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h8c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1H3zm8 1.75L9.75 9h-1.5L7 7.75 5.75 9h-1.5L3 7.75V7h.75L5 8.25 6.25 7h1.5L9 8.25 10.25 7H11v.75zM5 11h4v1H5v-1zm2-9C3.14 2 0 4.91 0 8.5V13c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V8.5C14 4.91 10.86 2 7 2zm6 11H1V8.5c0-3.09 2.64-5.59 6-5.59s6 2.5 6 5.59V13z\"/>"},"inbox":{"name":"inbox","figma":{"id":"0:426","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["mail","todo","new","messages"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 9l-1.13-7.14c-.08-.48-.5-.86-1-.86H2.13c-.5 0-.92.38-1 .86L0 9v5c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V9zm-3.28.55l-.44.89c-.17.34-.52.56-.91.56H4.61c-.38 0-.72-.22-.89-.55l-.44-.91c-.17-.33-.52-.55-.89-.55H1l1-7h10l1 7h-1.38c-.39 0-.73.22-.91.55l.01.01z\"/>"},"info":{"name":"info","figma":{"id":"0:430","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["help"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z\"/>"},"issue-closed":{"name":"issue-closed","figma":{"id":"0:436","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["done","complete"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5 1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14 2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1 4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z\"/>"},"issue-opened":{"name":"issue-opened","figma":{"id":"0:442","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["new"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z\"/>"},"issue-reopened":{"name":"issue-reopened","figma":{"id":"0:448","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["regression"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 9H6V4h2v5zm-2 3h2v-2H6v2zm6.33-2H10l1.5 1.5c-1.05 1.33-2.67 2.2-4.5 2.2A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7 2.19 0 4.13-1.02 5.41-2.59L14 14v-4h-1.67zM1.67 6H4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7 0 .34-.03.67-.09 1h1.31c.05-.33.08-.66.08-1 0-3.86-3.14-7-7-7-2.19 0-4.13 1.02-5.41 2.59L0 2v4h1.67z\"/>"},"italic":{"name":"italic","figma":{"id":"0:454","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["font","italic","style"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2.81 5h1.98L3 14H1l1.81-9zm.36-2.7c0-.7.58-1.3 1.33-1.3.56 0 1.13.38 1.13 1.03 0 .75-.59 1.3-1.33 1.3-.58 0-1.13-.38-1.13-1.03z\"/>"},"jersey":{"name":"jersey","figma":{"id":"0:458","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["team","game","basketball"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.5 6l-.5.5v5l.5.5h2l.5-.5v-5L6.5 6h-2zM6 11H5V7h1v4zm6.27-7.25C12.05 2.37 11.96 1.12 12 0H9.02c0 .27-.13.48-.39.69-.25.2-.63.3-1.13.3-.5 0-.88-.09-1.13-.3-.23-.2-.36-.42-.36-.69H3c.05 1.13-.03 2.38-.25 3.75C2.55 5.13 1.95 5.88 1 6v9c.02.27.11.48.31.69.2.21.42.3.69.31h11c.27-.02.48-.11.69-.31.21-.2.3-.42.31-.69V6c-.95-.13-1.53-.88-1.75-2.25h.02zM13 15H2V7c.89-.5 1.48-1.25 1.72-2.25S4.03 2.5 4 1h1c-.02.78.16 1.47.52 2.06.36.58 1.02.89 2 .94.98-.02 1.64-.33 2-.94.36-.59.5-1.28.48-2.06h1c.02 1.42.13 2.55.33 3.38.2.81.69 2 1.67 2.63v8V15zM8.5 6l-.5.5v5l.5.5h2l.5-.5v-5l-.5-.5h-2zm1.5 5H9V7h1v4z\"/>"},"keyboard":{"name":"keyboard","figma":{"id":"0:466","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["type","keys","write","shortcuts"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 5H9V4h1v1zM3 6H2v1h1V6zm5-2H7v1h1V4zM4 4H2v1h2V4zm8 7h2v-1h-2v1zM8 7h1V6H8v1zm-4 3H2v1h2v-1zm8-6h-1v1h1V4zm2 0h-1v1h1V4zm-2 5h2V6h-2v3zm4-6v9c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h14c.55 0 1 .45 1 1zm-1 0H1v9h14V3zM6 7h1V6H6v1zm0-3H5v1h1V4zM4 7h1V6H4v1zm1 4h6v-1H5v1zm5-4h1V6h-1v1zM3 8H2v1h1V8zm5 0v1h1V8H8zM6 8v1h1V8H6zM5 8H4v1h1V8zm5 1h1V8h-1v1z\"/>"},"law":{"name":"law","figma":{"id":"0:490","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["legal","bill"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 4c-.83 0-1.5-.67-1.5-1.5S6.17 1 7 1s1.5.67 1.5 1.5S7.83 4 7 4zm7 6c0 1.11-.89 2-2 2h-1c-1.11 0-2-.89-2-2l2-4h-1c-.55 0-1-.45-1-1H8v8c.42 0 1 .45 1 1h1c.42 0 1 .45 1 1H3c0-.55.58-1 1-1h1c0-.55.58-1 1-1h.03L6 5H5c0 .55-.45 1-1 1H3l2 4c0 1.11-.89 2-2 2H2c-1.11 0-2-.89-2-2l2-4H1V5h3c0-.55.45-1 1-1h4c.55 0 1 .45 1 1h3v1h-1l2 4zM2.5 7L1 10h3L2.5 7zM13 10l-1.5-3-1.5 3h3z\"/>"},"link":{"name":"link","figma":{"id":"0:496","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["connect","hyperlink"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"/>"},"list-ordered":{"name":"list-ordered","figma":{"id":"0:500","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["numbers","tasks","todo","items"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 12.99c0 .589 0 .998-.59.998H4.597c-.59 0-.59-.41-.59-.999 0-.59 0-.999.59-.999H11.4c.59 0 .59.41.59 1H12zM4.596 3.996H11.4c.59 0 .59-.41.59-1 0-.589 0-.999-.59-.999H4.596c-.59 0-.59.41-.59 1 0 .589 0 .999.59.999zM11.4 6.994H4.596c-.59 0-.59.41-.59 1 0 .589 0 .999.59.999H11.4c.59 0 .59-.41.59-1 0-.59 0-.999-.59-.999zM2.008 1h-.72C.99 1.19.71 1.25.26 1.34V2h.75v2.138H.17v.859h2.837v-.86h-.999V1zm.25 8.123c-.17 0-.45.03-.66.06.53-.56 1.14-1.249 1.14-1.888-.02-.78-.56-1.299-1.36-1.299-.589 0-.968.2-1.378.64l.58.579c.19-.19.38-.38.639-.38.28 0 .48.16.48.52 0 .53-.77 1.199-1.699 2.058v.58h2.998l-.09-.88h-.66l.01.01zm-.08 3.777v-.03c.44-.19.64-.47.64-.859 0-.7-.56-1.11-1.44-1.11-.479 0-.888.19-1.278.52l.55.64c.25-.2.44-.31.689-.31.27 0 .42.13.42.36 0 .27-.2.44-.86.44v.749c.83 0 .98.17.98.47 0 .25-.23.38-.58.38-.28 0-.56-.14-.81-.38l-.479.659c.3.36.77.56 1.409.56.83 0 1.529-.41 1.529-1.16 0-.5-.31-.809-.77-.939v.01z\"/>"},"list-unordered":{"name":"list-unordered","figma":{"id":"0:508","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["bullet","point","tasks","todo","items"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 13c0 .59 0 1-.59 1H.59C0 14 0 13.59 0 13c0-.59 0-1 .59-1h.81c.59 0 .59.41.59 1H2zm2.59-9h6.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1H4.59C4 2 4 2.41 4 3c0 .59 0 1 .59 1zM1.41 7H.59C0 7 0 7.41 0 8c0 .59 0 1 .59 1h.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01zm0-5H.59C0 2 0 2.41 0 3c0 .59 0 1 .59 1h.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01zm10 5H4.59C4 7 4 7.41 4 8c0 .59 0 1 .59 1h6.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01zm0 5H4.59C4 12 4 12.41 4 13c0 .59 0 1 .59 1h6.81c.59 0 .59-.41.59-1 0-.59 0-1-.59-1h.01z\"/>"},"location":{"name":"location","figma":{"id":"0:516","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["here","marker"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 0C2.69 0 0 2.5 0 5.5 0 10.02 6 16 6 16s6-5.98 6-10.5C12 2.5 9.31 0 6 0zm0 14.55C4.14 12.52 1 8.44 1 5.5 1 3.02 3.25 1 6 1c1.34 0 2.61.48 3.56 1.36.92.86 1.44 1.97 1.44 3.14 0 2.94-3.14 7.02-5 9.05zM8 5.5c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z\"/>"},"lock":{"name":"lock","figma":{"id":"0:521","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["secure","safe","protected"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 13H3v-1h1v1zm8-6v7c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h1V4c0-2.2 1.8-4 4-4s4 1.8 4 4v2h1c.55 0 1 .45 1 1zM3.8 6h4.41V4c0-1.22-.98-2.2-2.2-2.2-1.22 0-2.2.98-2.2 2.2v2H3.8zM11 7H2v7h9V7zM4 8H3v1h1V8zm0 2H3v1h1v-1z\"/>"},"logo-gist":{"name":"logo-gist","figma":{"id":"0:529","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["brand","github","logo"],"width":25,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.7 8.73h2.45v4.02c-.55.27-1.64.34-2.53.34-2.56 0-3.47-2.2-3.47-5.05 0-2.85.91-5.06 3.48-5.06 1.28 0 2.06.23 3.28.73V2.66C7.27 2.33 6.25 2 4.63 2 1.13 2 0 4.69 0 8.03c0 3.34 1.11 6.03 4.63 6.03 1.64 0 2.81-.27 3.59-.64V7.73H4.7v1zm6.39 3.72V6.06h-1.05v6.28c0 1.25.58 1.72 1.72 1.72v-.89c-.48 0-.67-.16-.67-.7v-.02zm.25-8.72c0-.44-.33-.78-.78-.78s-.77.34-.77.78.33.78.77.78.78-.34.78-.78zm4.34 5.69c-1.5-.13-1.78-.48-1.78-1.17 0-.77.33-1.34 1.88-1.34 1.05 0 1.66.16 2.27.36v-.94c-.69-.3-1.52-.39-2.25-.39-2.2 0-2.92 1.2-2.92 2.31 0 1.08.47 1.88 2.73 2.08 1.55.13 1.77.63 1.77 1.34 0 .73-.44 1.42-2.06 1.42-1.11 0-1.86-.19-2.33-.36v.94c.5.2 1.58.39 2.33.39 2.38 0 3.14-1.2 3.14-2.41 0-1.28-.53-2.03-2.75-2.23h-.03zm8.58-2.47v-.86h-2.42v-2.5l-1.08.31v2.11l-1.56.44v.48h1.56v5c0 1.53 1.19 2.13 2.5 2.13.19 0 .52-.02.69-.05v-.89c-.19.03-.41.03-.61.03-.97 0-1.5-.39-1.5-1.34V6.94h2.42v.02-.01z\"/>"},"logo-github":{"name":"logo-github","figma":{"id":"0:536","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["brand","github","logo"],"width":45,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M18.53 12.03h-.02c.009 0 .015.01.024.011h.006l-.01-.01zm.004.011c-.093.001-.327.05-.574.05-.78 0-1.05-.36-1.05-.83V8.13h1.59c.09 0 .16-.08.16-.19v-1.7c0-.09-.08-.17-.16-.17h-1.59V3.96c0-.08-.05-.13-.14-.13h-2.16c-.09 0-.14.05-.14.13v2.17s-1.09.27-1.16.28c-.08.02-.13.09-.13.17v1.36c0 .11.08.19.17.19h1.11v3.28c0 2.44 1.7 2.69 2.86 2.69.53 0 1.17-.17 1.27-.22.06-.02.09-.09.09-.16v-1.5a.177.177 0 0 0-.146-.18zm23.696-2.2c0-1.81-.73-2.05-1.5-1.97-.6.04-1.08.34-1.08.34v3.52s.49.34 1.22.36c1.03.03 1.36-.34 1.36-2.25zm2.43-.16c0 3.43-1.11 4.41-3.05 4.41-1.64 0-2.52-.83-2.52-.83s-.04.46-.09.52c-.03.06-.08.08-.14.08h-1.48c-.1 0-.19-.08-.19-.17l.02-11.11c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v3.77s.82-.53 2.02-.53l-.01-.02c1.2 0 2.97.45 2.97 3.88zm-8.72-3.61h-2.1c-.11 0-.17.08-.17.19v5.44s-.55.39-1.3.39-.97-.34-.97-1.09V6.25c0-.09-.08-.17-.17-.17h-2.14c-.09 0-.17.08-.17.17v5.11c0 2.2 1.23 2.75 2.92 2.75 1.39 0 2.52-.77 2.52-.77s.05.39.08.45c.02.05.09.09.16.09h1.34c.11 0 .17-.08.17-.17l.02-7.47c0-.09-.08-.17-.19-.17zm-23.7-.01h-2.13c-.09 0-.17.09-.17.2v7.34c0 .2.13.27.3.27h1.92c.2 0 .25-.09.25-.27V6.23c0-.09-.08-.17-.17-.17zm-1.05-3.38c-.77 0-1.38.61-1.38 1.38 0 .77.61 1.38 1.38 1.38.75 0 1.36-.61 1.36-1.38 0-.77-.61-1.38-1.36-1.38zm16.49-.25h-2.11c-.09 0-.17.08-.17.17v4.09h-3.31V2.6c0-.09-.08-.17-.17-.17h-2.13c-.09 0-.17.08-.17.17v11.11c0 .09.09.17.17.17h2.13c.09 0 .17-.08.17-.17V8.96h3.31l-.02 4.75c0 .09.08.17.17.17h2.13c.09 0 .17-.08.17-.17V2.6c0-.09-.08-.17-.17-.17zM8.81 7.35v5.74c0 .04-.01.11-.06.13 0 0-1.25.89-3.31.89-2.49 0-5.44-.78-5.44-5.92S2.58 1.99 5.1 2c2.18 0 3.06.49 3.2.58.04.05.06.09.06.14L7.94 4.5c0 .09-.09.2-.2.17-.36-.11-.9-.33-2.17-.33-1.47 0-3.05.42-3.05 3.73s1.5 3.7 2.58 3.7c.92 0 1.25-.11 1.25-.11v-2.3H4.88c-.11 0-.19-.08-.19-.17V7.35c0-.09.08-.17.19-.17h3.74c.11 0 .19.08.19.17z\"/>"},"mail-read":{"name":"mail-read","figma":{"id":"0:547","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["email","open"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 5H4V4h2v1zm3 1H4v1h5V6zm5-.48V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V5.52c0-.33.16-.63.42-.81L2 3.58V3c0-.55.45-1 1-1h1.2L7 0l2.8 2H11c.55 0 1 .45 1 1v.58l1.58 1.13c.27.19.42.48.42.81zM3 7.5L7 10l4-2.5V3H3v4.5zm-2 6l4.5-3-4.5-3v6zm11 .5l-5-3-5 3h10zm1-6.5l-4.5 3 4.5 3v-6z\"/>"},"reply":{"name":"reply","figma":{"id":"0:554","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["reply all","back"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 3.5c3.92.44 8 3.125 8 10-2.312-5.062-4.75-6-8-6V11L.5 5.5 6 0v3.5z\"/>"},"mail":{"name":"mail","figma":{"id":"0:558","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["email","unread"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 4v8c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1zm13 0L7 9 1 4h12zM1 5.5l4 3-4 3v-6zM2 12l3.5-3L7 10.5 8.5 9l3.5 3H2zm11-.5l-4-3 4-3v6z\"/>"},"mark-github":{"name":"mark-github","figma":{"id":"0:563","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["octocat","brand","github","logo"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z\"/>"},"markdown":{"name":"markdown","figma":{"id":"0:567","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["markup","style"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z\"/>"},"megaphone":{"name":"megaphone","figma":{"id":"0:572","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["bullhorn","loud","shout","broadcast"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 1c-.17 0-.36.05-.52.14C8.04 2.02 4.5 4.58 3 5c-1.38 0-3 .67-3 2.5S1.63 10 3 10c.3.08.64.23 1 .41V15h2v-3.45c1.34.86 2.69 1.83 3.48 2.31.16.09.34.14.52.14.52 0 1-.42 1-1V2c0-.58-.48-1-1-1zm0 12c-.38-.23-.89-.58-1.5-1-.16-.11-.33-.22-.5-.34V3.31c.16-.11.31-.2.47-.31.61-.41 1.16-.77 1.53-1v11zm2-6h4v1h-4V7zm0 2l4 2v1l-4-2V9zm4-6v1l-4 2V5l4-2z\"/>"},"mention":{"name":"mention","figma":{"id":"0:579","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["at","ping"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.58 15c1.25 0 2.52-.31 3.56-.94l-.42-.94c-.84.52-1.89.83-3.03.83-3.23 0-5.64-2.08-5.64-5.72 0-4.37 3.23-7.18 6.58-7.18 3.45 0 5.22 2.19 5.22 5.2 0 2.39-1.34 3.86-2.5 3.86-1.05 0-1.36-.73-1.05-2.19l.73-3.75H8.98l-.11.72c-.41-.63-.94-.83-1.56-.83-2.19 0-3.66 2.39-3.66 4.38 0 1.67.94 2.61 2.3 2.61.84 0 1.67-.53 2.3-1.25.11.94.94 1.45 1.98 1.45 1.67 0 3.77-1.67 3.77-5C14 2.61 11.59 0 7.83 0 3.66 0 0 3.33 0 8.33 0 12.71 2.92 15 6.58 15zm-.31-5c-.73 0-1.36-.52-1.36-1.67 0-1.45.94-3.22 2.41-3.22.52 0 .84.2 1.25.83l-.52 3.02c-.63.73-1.25 1.05-1.78 1.05V10z\"/>"},"milestone":{"name":"milestone","figma":{"id":"0:583","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["marker"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 2H6V0h2v2zm4 5H2c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h10l2 2-2 2zM8 4H6v2h2V4zM6 16h2V8H6v8z\"/>"},"mirror":{"name":"mirror","figma":{"id":"0:589","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["reflect"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.5 4.7L8.5 0l-7 4.7c-.3.19-.5.45-.5.8V16l7.5-4 7.5 4V5.5c0-.34-.2-.61-.5-.8zm-.5 9.8l-6-3.25V10H8v1.25L2 14.5v-9l6-4V6h1V1.5l6 4v9zM6 7h5V5l3 3-3 3V9H6v2L3 8l3-3v2z\"/>"},"mortar-board":{"name":"mortar-board","figma":{"id":"0:594","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["education","learn","teach"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.83 9.19L4 8c-4-8 0 1.5 0 2.5S5.8 12 8 12s4-.5 4-1.5V8L8.17 9.19a.73.73 0 0 1-.36 0h.02zm.28-6.39a.34.34 0 0 0-.2 0L.27 5.18a.35.35 0 0 0 0 .67L2 6.4v1.77c-.3.17-.5.5-.5.86 0 .19.05.36.14.5-.08.14-.14.31-.14.5v2.58c0 .55 2 .55 2 0v-2.58c0-.19-.05-.36-.14-.5.08-.14.14-.31.14-.5 0-.38-.2-.69-.5-.86V6.72l4.89 1.53c.06.02.14.02.2 0l7.64-2.38a.35.35 0 0 0 0-.67L8.1 2.81l.01-.01zM8.02 6c-.55 0-1-.22-1-.5s.45-.5 1-.5 1 .22 1 .5-.45.5-1 .5z\"/>"},"mute":{"name":"mute","figma":{"id":"0:599","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["quiet","sound","audio","turn","off"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z\"/>"},"no-newline":{"name":"no-newline","figma":{"id":"0:603","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["return"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 5v3c0 .55-.45 1-1 1h-3v2L9 8l3-3v2h2V5h2zM8 8c0 2.2-1.8 4-4 4s-4-1.8-4-4 1.8-4 4-4 4 1.8 4 4zM1.5 9.66L5.66 5.5C5.18 5.19 4.61 5 4 5 2.34 5 1 6.34 1 8c0 .61.19 1.17.5 1.66zM7 8c0-.61-.19-1.17-.5-1.66L2.34 10.5c.48.31 1.05.5 1.66.5 1.66 0 3-1.34 3-3z\"/>"},"octoface":{"name":"octoface","figma":{"id":"0:609","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["octocat","brand"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14.7 5.34c.13-.32.55-1.59-.13-3.31 0 0-1.05-.33-3.44 1.3-1-.28-2.07-.32-3.13-.32s-2.13.04-3.13.32c-2.39-1.64-3.44-1.3-3.44-1.3-.68 1.72-.26 2.99-.13 3.31C.49 6.21 0 7.33 0 8.69 0 13.84 3.33 15 7.98 15S16 13.84 16 8.69c0-1.36-.49-2.48-1.3-3.35zM8 14.02c-3.3 0-5.98-.15-5.98-3.35 0-.76.38-1.48 1.02-2.07 1.07-.98 2.9-.46 4.96-.46 2.07 0 3.88-.52 4.96.46.65.59 1.02 1.3 1.02 2.07 0 3.19-2.68 3.35-5.98 3.35zM5.49 9.01c-.66 0-1.2.8-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.54-1.78-1.2-1.78zm5.02 0c-.66 0-1.2.79-1.2 1.78s.54 1.79 1.2 1.79c.66 0 1.2-.8 1.2-1.79s-.53-1.78-1.2-1.78z\"/>"},"organization":{"name":"organization","figma":{"id":"0:613","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["people","group","team"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z\"/>"},"package":{"name":"package","figma":{"id":"0:617","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["box","ship"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z\"/>"},"paintcan":{"name":"paintcan","figma":{"id":"0:624","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["style","theme","art","color"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 0C2.69 0 0 2.69 0 6v1c0 .55.45 1 1 1v5c0 1.1 2.24 2 5 2s5-.9 5-2V8c.55 0 1-.45 1-1V6c0-3.31-2.69-6-6-6zm3 10v.5c0 .28-.22.5-.5.5s-.5-.22-.5-.5V10c0-.28-.22-.5-.5-.5s-.5.22-.5.5v2.5c0 .28-.22.5-.5.5s-.5-.22-.5-.5v-2c0-.28-.22-.5-.5-.5s-.5.22-.5.5v.5c0 .55-.45 1-1 1s-1-.45-1-1v-1c-.55 0-1-.45-1-1V7.2c.91.49 2.36.8 4 .8 1.64 0 3.09-.31 4-.8V9c0 .55-.45 1-1 1zM6 7c-1.68 0-3.12-.41-3.71-1C2.88 5.41 4.32 5 6 5c1.68 0 3.12.41 3.71 1-.59.59-2.03 1-3.71 1zm0-3c-2.76 0-5 .89-5 2 0-2.76 2.24-5 5-5s5 2.24 5 5c0-1.1-2.24-2-5-2z\"/>"},"pencil":{"name":"pencil","figma":{"id":"0:630","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["edit","change","update","write"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z\"/>"},"person":{"name":"person","figma":{"id":"0:633","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["people","man","woman","human"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 14.002a.998.998 0 0 1-.998.998H1.001A1 1 0 0 1 0 13.999V13c0-2.633 4-4 4-4s.229-.409 0-1c-.841-.62-.944-1.59-1-4 .173-2.413 1.867-3 3-3s2.827.586 3 3c-.056 2.41-.159 3.38-1 4-.229.59 0 1 0 1s4 1.367 4 4v1.002z\"/>"},"pin":{"name":"pin","figma":{"id":"0:635","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save","star","bookmark"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 1.2V2l.5 1L6 6H2.2c-.44 0-.67.53-.34.86L5 10l-4 5 5-4 3.14 3.14a.5.5 0 0 0 .86-.34V10l3-4.5 1 .5h.8c.44 0 .67-.53.34-.86L10.86.86a.5.5 0 0 0-.86.34z\"/>"},"plug":{"name":"plug","figma":{"id":"0:637","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hook","webhook"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 6V5h-4V3H8v1H6c-1.03 0-1.77.81-2 2L3 7c-1.66 0-3 1.34-3 3v2h1v-2c0-1.11.89-2 2-2l1 1c.25 1.16.98 2 2 2h2v1h2v-2h4V9h-4V6h4z\"/>"},"plus":{"name":"plus","figma":{"id":"0:639","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["add","new","more"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 9H7v5H5V9H0V7h5V2h2v5h5v2z\"/>"},"primitive-dot":{"name":"primitive-dot","figma":{"id":"0:641","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["circle"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 8c0-2.2 1.8-4 4-4s4 1.8 4 4-1.8 4-4 4-4-1.8-4-4z\"/>"},"primitive-square":{"name":"primitive-square","figma":{"id":"0:643","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["box"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 12H0V4h8v8z\"/>"},"pulse":{"name":"pulse","figma":{"id":"0:645","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["graph","trend","line","activity"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8h-2.5z\"/>"},"question":{"name":"question","figma":{"id":"0:649","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["help","explain"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 10h2v2H6v-2zm4-3.5C10 8.64 8 9 8 9H6c0-.55.45-1 1-1h.5c.28 0 .5-.22.5-.5v-1c0-.28-.22-.5-.5-.5h-1c-.28 0-.5.22-.5.5V7H4c0-1.5 1.5-3 3-3s3 1 3 2.5zM7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7z\"/>"},"quote":{"name":"quote","figma":{"id":"0:655","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["quotation"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.16 3.5C3.73 5.06 2.55 6.67 2.55 9.36c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.9 0-2.99-1.52-2.99-4.25 0-3.8 1.75-6.53 5.02-8.42L6.16 3.5zm7 0c-2.43 1.56-3.61 3.17-3.61 5.86.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.89 0-2.98-1.52-2.98-4.25 0-3.8 1.75-6.53 5.02-8.42l1.14 1.84h-.01z\"/>"},"radio-tower":{"name":"radio-tower","figma":{"id":"0:659","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["broadcast"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.79 6.11c.25-.25.25-.67 0-.92-.32-.33-.48-.76-.48-1.19 0-.43.16-.86.48-1.19.25-.26.25-.67 0-.92a.613.613 0 0 0-.45-.19c-.16 0-.33.06-.45.19-.57.58-.85 1.35-.85 2.11 0 .76.29 1.53.85 2.11.25.25.66.25.9 0zM2.33.52a.651.651 0 0 0-.92 0C.48 1.48.01 2.74.01 3.99c0 1.26.47 2.52 1.4 3.48.25.26.66.26.91 0s.25-.68 0-.94c-.68-.7-1.02-1.62-1.02-2.54 0-.92.34-1.84 1.02-2.54a.66.66 0 0 0 .01-.93zm5.69 5.1A1.62 1.62 0 1 0 6.4 4c-.01.89.72 1.62 1.62 1.62zM14.59.53a.628.628 0 0 0-.91 0c-.25.26-.25.68 0 .94.68.7 1.02 1.62 1.02 2.54 0 .92-.34 1.83-1.02 2.54-.25.26-.25.68 0 .94a.651.651 0 0 0 .92 0c.93-.96 1.4-2.22 1.4-3.48A5.048 5.048 0 0 0 14.59.53zM8.02 6.92c-.41 0-.83-.1-1.2-.3l-3.15 8.37h1.49l.86-1h4l.84 1h1.49L9.21 6.62c-.38.2-.78.3-1.19.3zm-.01.48L9.02 11h-2l.99-3.6zm-1.99 5.59l1-1h2l1 1h-4zm5.19-11.1c-.25.25-.25.67 0 .92.32.33.48.76.48 1.19 0 .43-.16.86-.48 1.19-.25.26-.25.67 0 .92a.63.63 0 0 0 .9 0c.57-.58.85-1.35.85-2.11 0-.76-.28-1.53-.85-2.11a.634.634 0 0 0-.9 0z\"/>"},"repo-clone":{"name":"repo-clone","figma":{"id":"0:669","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","repository"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15 0H9v7c0 .55.45 1 1 1h1v1h1V8h3c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1zm-4 7h-1V6h1v1zm4 0h-3V6h3v1zm0-2h-4V1h4v4zM4 5H3V4h1v1zm0-2H3V2h1v1zM2 1h6V0H1C.45 0 0 .45 0 1v12c0 .55.45 1 1 1h2v2l1.5-1.5L6 16v-2h5c.55 0 1-.45 1-1v-3H2V1zm9 10v2H6v-1H3v1H1v-2h10zM3 8h1v1H3V8zm1-1H3V6h1v1z\"/>"},"repo-force-push":{"name":"repo-force-push","figma":{"id":"0:681","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","put"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 9H8v7H6V9H4l2.25-3H4l3-4 3 4H7.75L10 9zm1-9H1C.45 0 0 .45 0 1v12c0 .55.45 1 1 1h4v-1H1v-2h4v-1H2V1h9v9H9v1h2v2H9v1h2c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1z\"/>"},"repo-forked":{"name":"repo-forked","figma":{"id":"0:685","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","copy"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z\"/>"},"repo-pull":{"name":"repo-pull","figma":{"id":"0:691","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","get"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 8V6H7V4h6V2l3 3-3 3zM4 2H3v1h1V2zm7 5h1v6c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1v2h-1V1H2v9h9V7zm0 4H1v2h2v-1h3v1h5v-2zM4 6H3v1h1V6zm0-2H3v1h1V4zM3 9h1V8H3v1z\"/>"},"repo-push":{"name":"repo-push","figma":{"id":"0:700","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","repository","put"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 3H3V2h1v1zM3 5h1V4H3v1zm4 0L4 9h2v7h2V9h2L7 5zm4-5H1C.45 0 0 .45 0 1v12c0 .55.45 1 1 1h4v-1H1v-2h4v-1H2V1h9.02L11 10H9v1h2v2H9v1h2c.55 0 1-.45 1-1V1c0-.55-.45-1-1-1z\"/>"},"repo":{"name":"repo","figma":{"id":"0:706","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["book","journal","repository"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z\"/>"},"rocket":{"name":"rocket","figma":{"id":"0:715","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["staff","stafftools","blast","off","space","launch","ship"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12.17 3.83c-.27-.27-.47-.55-.63-.88-.16-.31-.27-.66-.34-1.02-.58.33-1.16.7-1.73 1.13-.58.44-1.14.94-1.69 1.48-.7.7-1.33 1.81-1.78 2.45H3L0 10h3l2-2c-.34.77-1.02 2.98-1 3l1 1c.02.02 2.23-.64 3-1l-2 2v3l3-3v-3c.64-.45 1.75-1.09 2.45-1.78.55-.55 1.05-1.13 1.47-1.7.44-.58.81-1.16 1.14-1.72-.36-.08-.7-.19-1.03-.34a3.39 3.39 0 0 1-.86-.63zM16 0s-.09.38-.3 1.06c-.2.7-.55 1.58-1.06 2.66-.7-.08-1.27-.33-1.66-.72-.39-.39-.63-.94-.7-1.64C13.36.84 14.23.48 14.92.28 15.62.08 16 0 16 0z\"/>"},"rss":{"name":"rss","figma":{"id":"0:719","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["broadcast","feed","atom"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 13H0v-2c1.11 0 2 .89 2 2zM0 3v1a9 9 0 0 1 9 9h1C10 7.48 5.52 3 0 3zm0 4v1c2.75 0 5 2.25 5 5h1c0-3.31-2.69-6-6-6z\"/>"},"ruby":{"name":"ruby","figma":{"id":"0:724","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["code","language"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 6l-5 5V4h3l2 2zm3 0l-8 8-8-8 4-4h8l4 4zm-8 6.5L14.5 6l-3-3h-7l-3 3L8 12.5z\"/>"},"search":{"name":"search","figma":{"id":"0:729","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["magnifying","glass"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z\"/>"},"server":{"name":"server","figma":{"id":"0:733","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["computers","racks","ops"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 6H1c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V7c0-.55-.45-1-1-1zM2 9H1V7h1v2zm2 0H3V7h1v2zm2 0H5V7h1v2zm2 0H7V7h1v2zm3-8H1c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zM2 4H1V2h1v2zm2 0H3V2h1v2zm2 0H5V2h1v2zm2 0H7V2h1v2zm3-1h-1V2h1v1zm0 8H1c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h10c.55 0 1-.45 1-1v-2c0-.55-.45-1-1-1zm-9 3H1v-2h1v2zm2 0H3v-2h1v2zm2 0H5v-2h1v2zm2 0H7v-2h1v2z\"/>"},"settings":{"name":"settings","figma":{"id":"0:751","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["sliders","filters","controls","levels"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 7H3V2h1v5zm-1 7h1v-3H3v3zm5 0h1V8H8v6zm5 0h1v-2h-1v2zm1-12h-1v6h1V2zM9 2H8v2h1V2zM5 8H2c-.55 0-1 .45-1 1s.45 1 1 1h3c.55 0 1-.45 1-1s-.45-1-1-1zm5-3H7c-.55 0-1 .45-1 1s.45 1 1 1h3c.55 0 1-.45 1-1s-.45-1-1-1zm5 4h-3c-.55 0-1 .45-1 1s.45 1 1 1h3c.55 0 1-.45 1-1s-.45-1-1-1z\"/>"},"shield":{"name":"shield","figma":{"id":"0:762","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["protect","shield","lock"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 0L0 2v6.02C0 12.69 5.31 16 7 16c1.69 0 7-3.31 7-7.98V2L7 0zM5 11l1.14-2.8a.568.568 0 0 0-.25-.59C5.33 7.25 5 6.66 5 6c0-1.09.89-2 1.98-2C8.06 4 9 4.91 9 6c0 .66-.33 1.25-.89 1.61-.19.13-.3.36-.25.59L9 11H5z\"/>"},"sign-in":{"name":"sign-in","figma":{"id":"0:764","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["door","arrow","direction","enter","log in"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 6.75V12h4V8h1v4c0 .55-.45 1-1 1H7v3l-5.45-2.72c-.33-.17-.55-.52-.55-.91V1c0-.55.45-1 1-1h9c.55 0 1 .45 1 1v3h-1V1H3l4 2v2.25L10 3v2h4v2h-4v2L7 6.75z\"/>"},"sign-out":{"name":"sign-out","figma":{"id":"0:768","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["door","arrow","direction","leave","log out"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.992 8.994V6.996H7.995v-2h3.997V2.999l3.998 2.998-3.998 2.998zm-1.998 2.998H5.996V2.998L2 1h7.995v2.998h1V1c0-.55-.45-.999-1-.999H.999A1.001 1.001 0 0 0 0 1v11.372c0 .39.22.73.55.91L5.996 16v-3.008h3.998c.55 0 1-.45 1-1V7.995h-1v3.997z\"/>"},"smiley":{"name":"smiley","figma":{"id":"0:772","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["emoji","smile","mood","emotion"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 0C3.58 0 0 3.58 0 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm4.81 12.81a6.72 6.72 0 0 1-2.17 1.45c-.83.36-1.72.53-2.64.53-.92 0-1.81-.17-2.64-.53-.81-.34-1.55-.83-2.17-1.45a6.773 6.773 0 0 1-1.45-2.17A6.59 6.59 0 0 1 1.21 8c0-.92.17-1.81.53-2.64.34-.81.83-1.55 1.45-2.17.62-.62 1.36-1.11 2.17-1.45A6.59 6.59 0 0 1 8 1.21c.92 0 1.81.17 2.64.53.81.34 1.55.83 2.17 1.45.62.62 1.11 1.36 1.45 2.17.36.83.53 1.72.53 2.64 0 .92-.17 1.81-.53 2.64-.34.81-.83 1.55-1.45 2.17zM4 6.8v-.59c0-.66.53-1.19 1.2-1.19h.59c.66 0 1.19.53 1.19 1.19v.59c0 .67-.53 1.2-1.19 1.2H5.2C4.53 8 4 7.47 4 6.8zm5 0v-.59c0-.66.53-1.19 1.2-1.19h.59c.66 0 1.19.53 1.19 1.19v.59c0 .67-.53 1.2-1.19 1.2h-.59C9.53 8 9 7.47 9 6.8zm4 3.2c-.72 1.88-2.91 3-5 3s-4.28-1.13-5-3c-.14-.39.23-1 .66-1h8.59c.41 0 .89.61.75 1z\"/>"},"squirrel":{"name":"squirrel","figma":{"id":"0:779","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["ship","shipit","launch"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 1C9.79 1 8 2.31 8 3.92c0 1.94.5 3.03 0 6.08 0-4.5-2.77-6.34-4-6.34.05-.5-.48-.66-.48-.66s-.22.11-.3.34c-.27-.31-.56-.27-.56-.27l-.13.58S.7 4.29.68 6.87c.2.33 1.53.6 2.47.43.89.05.67.79.47.99C2.78 9.13 2 8 1 8S0 9 1 9s1 1 3 1c-3.09 1.2 0 4 0 4H3c-1 0-1 1-1 1h6c3 0 5-1 5-3.47 0-.85-.43-1.79-1-2.53-1.11-1.46.23-2.68 1-2 .77.68 3 1 3-2 0-2.21-1.79-4-4-4zM2.5 6c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5z\"/>"},"star":{"name":"star","figma":{"id":"0:781","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["save","remember","like"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z\"/>"},"stop":{"name":"stop","figma":{"id":"0:785","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["block","spam","report"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 1H4L0 5v6l4 4h6l4-4V5l-4-4zm3 9.5L9.5 14h-5L1 10.5v-5L4.5 2h5L13 5.5v5zM6 4h2v5H6V4zm0 6h2v2H6v-2z\"/>"},"sync":{"name":"sync","figma":{"id":"0:791","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["cycle","refresh","loop"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10.24 7.4a4.15 4.15 0 0 1-1.2 3.6 4.346 4.346 0 0 1-5.41.54L4.8 10.4.5 9.8l.6 4.2 1.31-1.26c2.36 1.74 5.7 1.57 7.84-.54a5.876 5.876 0 0 0 1.74-4.46l-1.75-.34zM2.96 5a4.346 4.346 0 0 1 5.41-.54L7.2 5.6l4.3.6-.6-4.2-1.31 1.26c-2.36-1.74-5.7-1.57-7.85.54C.5 5.03-.06 6.65.01 8.26l1.75.35A4.17 4.17 0 0 1 2.96 5z\"/>"},"tag":{"name":"tag","figma":{"id":"0:795","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["release"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.685 1.72a2.49 2.49 0 0 0-1.76-.726H3.48A2.5 2.5 0 0 0 .994 3.48v2.456c0 .656.269 1.292.726 1.76l6.024 6.024a.99.99 0 0 0 1.402 0l4.563-4.563a.99.99 0 0 0 0-1.402L7.685 1.72zM2.366 7.048a1.54 1.54 0 0 1-.467-1.123V3.48c0-.874.716-1.58 1.58-1.58h2.456c.418 0 .825.159 1.123.467l6.104 6.094-4.702 4.702-6.094-6.114zm.626-4.066h1.989v1.989H2.982V2.982h.01z\"/>"},"tasklist":{"name":"tasklist","figma":{"id":"0:800","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["todo"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.41 9H7.59C7 9 7 8.59 7 8c0-.59 0-1 .59-1h7.81c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM9.59 4C9 4 9 3.59 9 3c0-.59 0-1 .59-1h5.81c.59 0 .59.41.59 1 0 .59 0 1-.59 1H9.59zM0 3.91l1.41-1.3L3 4.2 7.09 0 8.5 1.41 3 6.91l-3-3zM7.59 12h7.81c.59 0 .59.41.59 1 0 .59 0 1-.59 1H7.59C7 14 7 13.59 7 13c0-.59 0-1 .59-1z\"/>"},"telescope":{"name":"telescope","figma":{"id":"0:806","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["science","space","look","view","explore"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 9l3 6h-1l-2-4v5H7v-6l-2 5H4l2-5 2-1zM7 0H6v1h1V0zM5 3H4v1h1V3zM2 1H1v1h1V1zM.63 9a.52.52 0 0 0-.16.67l.55.92c.13.23.41.31.64.2l1.39-.66-1.16-2-1.27.86.01.01zm7.89-5.39l-5.8 3.95L3.95 9.7l6.33-3.03-1.77-3.06h.01zm4.22 1.28l-1.47-2.52a.51.51 0 0 0-.72-.17l-1.2.83 1.84 3.2 1.33-.64c.27-.13.36-.44.22-.7z\"/>"},"terminal":{"name":"terminal","figma":{"id":"0:815","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["code","ops","shell"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7 10h4v1H7v-1zm-3 1l3-3-3-3-.75.75L5.5 8l-2.25 2.25L4 11zm10-8v10c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h12c.55 0 1 .45 1 1zm-1 0H1v10h12V3z\"/>"},"text-size":{"name":"text-size","figma":{"id":"0:821","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["font","size","text"],"width":18,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13.62 9.08L12.1 3.66h-.06l-1.5 5.42h3.08zM5.7 10.13S4.68 6.52 4.53 6.02h-.08l-1.13 4.11H5.7zM17.31 14h-2.25l-.95-3.25h-4.07L9.09 14H6.84l-.69-2.33H2.87L2.17 14H0l3.3-9.59h2.5l2.17 6.34L10.86 2h2.52l3.94 12h-.01z\"/>"},"three-bars":{"name":"three-bars","figma":{"id":"0:826","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["hamburger","menu","dropdown"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.41 9H.59C0 9 0 8.59 0 8c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zm0-4H.59C0 5 0 4.59 0 4c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM.59 11H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1H.59C0 13 0 12.59 0 12c0-.59 0-1 .59-1z\"/>"},"thumbsdown":{"name":"thumbsdown","figma":{"id":"0:831","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["thumb","thumbsdown","rejected","dislike"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.97 7.825L15 1.88C14.83.499 13.123 0 11.993 0H5.686c-.2 0-.38.05-.53.14L3.719 1h-1.72C.94 1 0 1.938 0 2.997v3.998c0 1.059.94 2.018 1.999 1.998h1.998c.91 0 1.39.45 2.389 1.55.91.999.88 1.798.63 3.267-.08.5.06 1 .42 1.42.39.47.979.769 1.558.769 1.83 0 2.998-3.718 2.998-5.017l-.02-.98h2.04c1.159 0 1.948-.799 1.978-1.968 0-.06.02-.13-.02-.2v-.01zm-1.969 1.19h-1.989c-.7 0-1.029.28-1.029.969l.03 1.03c0 1.268-1.17 3.997-1.999 3.997-.5 0-1.079-.5-.999-1 .25-1.579.34-2.778-.89-4.137-1.019-1.13-1.768-1.879-3.127-1.879V1.999l1.668-1h6.326c.73 0 1.95.31 2 1l.02.02.999 5.996c-.03.64-.38 1-1 1h-.01z\"/>"},"thumbsup":{"name":"thumbsup","figma":{"id":"0:835","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["thumb","thumbsup","prop","ship","like"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13.991 13.991c-.05.69-1.269 1-1.998 1H5.665l-1.669-1V7.995c1.36 0 2.11-.75 3.129-1.879 1.229-1.359 1.139-2.558.879-4.127-.08-.5.5-1 1-1 .829 0 1.998 2.729 1.998 3.998l-.02 1.03c0 .689.33.969 1.02.969H14c.63 0 .98.36 1 .999l-1 5.996-.01.01zm0-7.995h-2.018l.02-.98C11.992 3.719 10.822 0 8.993 0c-.58 0-1.169.3-1.559.77-.36.41-.5.909-.42 1.409.25 1.479.28 2.278-.629 3.278-1 1.089-1.48 1.549-2.389 1.549H2c-1.061-.01-2 .929-2 1.988v3.998c0 1.06.94 1.999 1.999 1.999h1.719l1.439.86c.16.089.33.139.52.139h6.325c1.13 0 2.839-.5 2.999-1.879l.979-5.946c.02-.08.02-.14.02-.2-.03-1.17-.84-1.969-1.999-1.969h-.01z\"/>"},"tools":{"name":"tools","figma":{"id":"0:839","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["screwdriver","wrench","settings"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4.48 7.27c.26.26 1.28 1.33 1.28 1.33l.56-.58-.88-.91 1.69-1.8s-.76-.74-.43-.45c.32-1.19.03-2.51-.87-3.44C4.93.5 3.66.2 2.52.51l1.93 2-.51 1.96-1.89.52-1.93-2C-.19 4.17.1 5.48 1 6.4c.94.98 2.29 1.26 3.48.87zm6.44 1.94l-2.33 2.3 3.84 3.98c.31.33.73.49 1.14.49.41 0 .82-.16 1.14-.49.63-.65.63-1.7 0-2.35l-3.79-3.93zM16 2.53L13.55 0 6.33 7.46l.88.91-4.31 4.46-.99.53-1.39 2.27.35.37 2.2-1.44.51-1.02L7.9 9.08l.88.91L16 2.53z\"/>"},"trashcan":{"name":"trashcan","figma":{"id":"0:844","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["garbage","rubbish","recycle","delete"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z\"/>"},"triangle-down":{"name":"triangle-down","figma":{"id":"0:847","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 5l6 6 6-6H0z\"/>"},"triangle-left":{"name":"triangle-left","figma":{"id":"0:849","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 2L0 8l6 6V2z\"/>"},"triangle-right":{"name":"triangle-right","figma":{"id":"0:851","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":6,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 14l6-6-6-6v12z\"/>"},"triangle-up":{"name":"triangle-up","figma":{"id":"0:853","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["arrow","point","direction"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 11L6 5l-6 6h12z\"/>"},"unfold":{"name":"unfold","figma":{"id":"0:857","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["expand","open","reveal"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11.5 7.5L14 10c0 .55-.45 1-1 1H9v-1h3.5l-2-2h-7l-2 2H5v1H1c-.55 0-1-.45-1-1l2.5-2.5L0 5c0-.55.45-1 1-1h4v1H1.5l2 2h7l2-2H9V4h4c.55 0 1 .45 1 1l-2.5 2.5zM6 6h2V3h2L7 0 4 3h2v3zm2 3H6v3H4l3 3 3-3H8V9z\"/>"},"unmute":{"name":"unmute","figma":{"id":"0:862","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["loud","volume","audio","sound","play"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12 8.02c0 1.09-.45 2.09-1.17 2.83l-.67-.67c.55-.56.89-1.31.89-2.16 0-.85-.34-1.61-.89-2.16l.67-.67A3.99 3.99 0 0 1 12 8.02zM7.72 2.28L4 6H2c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h2l3.72 3.72c.47.47 1.28.14 1.28-.53V2.81c0-.67-.81-1-1.28-.53zm5.94.08l-.67.67a6.996 6.996 0 0 1 2.06 4.98c0 1.94-.78 3.7-2.06 4.98l.67.67A7.973 7.973 0 0 0 16 8c0-2.22-.89-4.22-2.34-5.66v.02zm-1.41 1.41l-.69.67a5.05 5.05 0 0 1 1.48 3.58c0 1.39-.56 2.66-1.48 3.56l.69.67A5.971 5.971 0 0 0 14 8.02c0-1.65-.67-3.16-1.75-4.25z\"/>"},"project":{"name":"project","figma":{"id":"0:868","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["board","kanban","columns","scrum"],"width":15,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z\"/>"},"kebab-horizontal":{"name":"kebab-horizontal","figma":{"id":"0:875","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["kebab","dot","menu","more"],"width":13,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z\"/>"},"kebab-vertical":{"name":"kebab-vertical","figma":{"id":"0:880","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["kebab","dot","menu","more"],"width":3,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 2.5a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0zm0 5a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0zM1.5 14a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z\"/>"},"report":{"name":"report","figma":{"id":"0:885","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["report","abuse","flag"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M0 2a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H7l-4 4v-4H1a1 1 0 0 1-1-1V2zm1 0h14v9H6.5L4 13.5V11H1V2zm6 6h2v2H7V8zm0-5h2v4H7V3z\"/>"},"note":{"name":"note","figma":{"id":"0:891","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["card","paper","ticket"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M3 10h4V9H3v1zm0-2h6V7H3v1zm0-2h8V5H3v1zm10 6H1V3h12v9zM1 2c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1H1z\"/>"},"screen-full":{"name":"screen-full","figma":{"id":"0:898","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fullscreen","expand"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 10h1v3c0 .547-.453 1-1 1h-3v-1h3v-3zM1 10H0v3c0 .547.453 1 1 1h3v-1H1v-3zm0-7h3V2H1c-.547 0-1 .453-1 1v3h1V3zm1 1h10v8H2V4zm2 6h6V6H4v4zm6-8v1h3v3h1V3c0-.547-.453-1-1-1h-3z\"/>"},"screen-normal":{"name":"screen-normal","figma":{"id":"0:906","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["fullscreen","expand","exit"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M2 4H0V3h2V1h1v2c0 .547-.453 1-1 1zm0 8H0v1h2v2h1v-2c0-.547-.453-1-1-1zm9-2c0 .547-.453 1-1 1H4c-.547 0-1-.453-1-1V6c0-.547.453-1 1-1h6c.547 0 1 .453 1 1v4zM9 7H5v2h4V7zm2 6v2h1v-2h2v-1h-2c-.547 0-1 .453-1 1zm1-10V1h-1v2c0 .547.453 1 1 1h2V3h-2z\"/>"},"unverified":{"name":"unverified","figma":{"id":"0:914","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["insecure","untrusted","signed"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.67 7.066l-1.08-1.34a1.5 1.5 0 0 1-.309-.77l-.19-1.698a1.51 1.51 0 0 0-1.329-1.33l-1.699-.19c-.3-.03-.56-.159-.78-.329L8.945.33a1.504 1.504 0 0 0-1.878 0l-1.34 1.08a1.5 1.5 0 0 1-.77.31l-1.698.19c-.7.08-1.25.63-1.33 1.329l-.19 1.699c-.03.3-.159.56-.329.78L.33 7.055a1.504 1.504 0 0 0 0 1.878l1.08 1.34c.17.22.28.48.31.77l.19 1.698c.08.7.63 1.25 1.329 1.33l1.699.19c.3.03.56.159.78.329l1.339 1.08c.55.439 1.329.439 1.878 0l1.34-1.08c.22-.17.48-.28.77-.31l1.698-.19c.7-.08 1.25-.63 1.33-1.329l.19-1.699c.03-.3.159-.56.329-.78l1.08-1.339a1.504 1.504 0 0 0 0-1.878zm-6.666 4.437c0 .28-.22.5-.5.5h-.999c-.27 0-.5-.22-.5-.5v-1c0-.28.23-.5.5-.5h1c.28 0 .5.22.5.5v1zm1.56-4.887c-.06.17-.17.33-.3.47-.13.16-.14.19-.33.38-.16.17-.31.3-.52.449-.11.09-.2.19-.28.27-.08.08-.14.17-.19.27-.05.1-.08.19-.11.3-.03.11-.03.13-.03.25H7.136c0-.22 0-.31.03-.48.03-.19.08-.36.14-.52.06-.14.14-.28.25-.42.11-.13.23-.25.409-.38.27-.19.36-.3.48-.52.12-.219.2-.379.2-.589 0-.27-.06-.45-.2-.58-.13-.13-.31-.19-.58-.19-.09 0-.19.02-.3.05-.11.03-.17.09-.25.16-.08.07-.14.11-.2.2a.41.41 0 0 0-.09.28H5.028c0-.38.13-.56.27-.83.16-.27.36-.499.61-.669.25-.17.549-.3.879-.38.33-.08.7-.13 1.09-.13.439 0 .829.05 1.168.13.34.09.63.22.88.39.23.17.41.38.55.63.13.25.19.55.19.88 0 .22 0 .419-.08.589l-.02-.01z\"/>"},"verified":{"name":"verified","figma":{"id":"0:919","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["trusted","secure","trustworthy","signed"],"width":16,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M15.67 7.066l-1.08-1.34a1.5 1.5 0 0 1-.309-.77l-.19-1.698a1.51 1.51 0 0 0-1.329-1.33l-1.699-.19c-.3-.03-.56-.159-.78-.329L8.945.33a1.504 1.504 0 0 0-1.878 0l-1.34 1.08a1.5 1.5 0 0 1-.77.31l-1.698.19c-.7.08-1.25.63-1.33 1.329l-.19 1.699c-.03.3-.159.56-.329.78L.33 7.055a1.504 1.504 0 0 0 0 1.878l1.08 1.34c.17.22.28.48.31.77l.19 1.698c.08.7.63 1.25 1.329 1.33l1.699.19c.3.03.56.159.78.329l1.339 1.08c.55.439 1.329.439 1.878 0l1.34-1.08c.22-.17.48-.28.77-.31l1.698-.19c.7-.08 1.25-.63 1.33-1.329l.19-1.699c.03-.3.159-.56.329-.78l1.08-1.339a1.504 1.504 0 0 0 0-1.878zm-9.164 4.936L3.008 8.505l1.5-1.5 1.998 2 4.997-4.998 1.499 1.55-6.496 6.445z\"/>"},"versions":{"name":"versions","figma":{"id":"0:923","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["history","commits"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 3H7c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V4c0-.55-.45-1-1-1zm-1 8H8V5h4v6zM4 4h1v1H4v6h1v1H4c-.55 0-1-.45-1-1V5c0-.55.45-1 1-1zM1 5h1v1H1v4h1v1H1c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1z\"/>"},"watch":{"name":"watch","figma":{"id":"0:929","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["wait","hourglass","time","date"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6 8h2v1H5V5h1v3zm6 0c0 2.22-1.2 4.16-3 5.19V15c0 .55-.45 1-1 1H4c-.55 0-1-.45-1-1v-1.81C1.2 12.16 0 10.22 0 8s1.2-4.16 3-5.19V1c0-.55.45-1 1-1h4c.55 0 1 .45 1 1v1.81c1.8 1.03 3 2.97 3 5.19zm-1 0c0-2.77-2.23-5-5-5S1 5.23 1 8s2.23 5 5 5 5-2.23 5-5z\"/>"},"x":{"name":"x","figma":{"id":"0:932","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["remove","close","delete"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z\"/>"},"zap":{"name":"zap","figma":{"id":"0:934","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["electricity","lightning","props","like","star","save"],"width":10,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M10 7H6l3-7-9 9h4l-3 7 9-9z\"/>"},"key":{"name":"key","figma":{"id":"0:938","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["key","lock","secure","safe"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M12.83 2.17C12.08 1.42 11.14 1.03 10 1c-1.13.03-2.08.42-2.83 1.17S6.04 3.86 6.01 5c0 .3.03.59.09.89L0 12v1l1 1h2l1-1v-1h1v-1h1v-1h2l1.09-1.11c.3.08.59.11.91.11 1.14-.03 2.08-.42 2.83-1.17S13.97 6.14 14 5c-.03-1.14-.42-2.08-1.17-2.83zM11 5.38c-.77 0-1.38-.61-1.38-1.38 0-.77.61-1.38 1.38-1.38.77 0 1.38.61 1.38 1.38 0 .77-.61 1.38-1.38 1.38z\"/>"},"grabber":{"name":"grabber","figma":{"id":"0:942","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["mover","drap","drop","sort"],"width":8,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M8 4v1H0V4h8zM0 8h8V7H0v1zm0 3h8v-1H0v1z\"/>"},"plus-small":{"name":"plus-small","figma":{"id":"0:947","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["add","new","more","small"],"width":7,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M4 4H3v3H0v1h3v3h1V8h3V7H4V4z\"/>"},"light-bulb":{"name":"light-bulb","figma":{"id":"0:951","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["idea"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z\"/>"},"link-external":{"name":"link-external","figma":{"id":"0:956","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["out","see","more","go","to"],"width":12,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M11 10h1v3c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h3v1H1v10h10v-3zM6 2l2.25 2.25L5 7.5 6.5 9l3.25-3.25L12 8V2H6z\"/>"},"archive":{"name":"archive","figma":{"id":"2228:2","file":"FP7lqd1V00LUaT5zvdklkkZr"},"keywords":["box","catalog"],"width":14,"height":16,"path":"<path fill-rule=\"evenodd\" d=\"M13 2H1v2h12V2zM0 4a1 1 0 0 0 1 1v9a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H1a1 1 0 0 0-1 1v2zm2 1h10v9H2V5zm2 3h6V7H4v1z\"/>"}}
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/archive.svg b/htdocs/theme/common/octicons/build/svg/archive.svg
    new file mode 100644
    index 00000000000..d1eaa21f97b
    --- /dev/null
    +++ b/htdocs/theme/common/octicons/build/svg/archive.svg
    @@ -0,0 +1 @@
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13 2H1v2h12V2zM0 4a1 1 0 0 0 1 1v9a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H1a1 1 0 0 0-1 1v2zm2 1h10v9H2V5zm2 3h6V7H4v1z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/arrow-both.svg b/htdocs/theme/common/octicons/build/svg/arrow-both.svg
    new file mode 100644
    index 00000000000..4167746d84b
    --- /dev/null
    +++ b/htdocs/theme/common/octicons/build/svg/arrow-both.svg
    @@ -0,0 +1 @@
    +<svg xmlns="http://www.w3.org/2000/svg" width="20" height="16" viewBox="0 0 20 16"><path d="M0 8l6-5v3h8V3l6 5-6 5v-3H6v3L0 8z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/beaker.svg b/htdocs/theme/common/octicons/build/svg/beaker.svg
    index 19377609a5d..0997bb0931c 100644
    --- a/htdocs/theme/common/octicons/build/svg/beaker.svg
    +++ b/htdocs/theme/common/octicons/build/svg/beaker.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14.84 14.59L11.46 7V3h1V2h-9v1h1v4l-3.37 7.59A1 1 0 0 0 2 16h11.94c.72 0 1.2-.75.91-1.41h-.01zM4.21 10l1.25-3V3h5v4l1.25 3h-7.5zm4.25-2h1v1h-1V8zm-1-1h-1V6h1v1zm0-3h1v1h-1V4zm0-3h-1V0h1v1z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14.38 14.59L11 7V3h1V2H3v1h1v4L.63 14.59A1 1 0 0 0 1.54 16h11.94c.72 0 1.2-.75.91-1.41h-.01zM3.75 10L5 7V3h5v4l1.25 3h-7.5zM8 8h1v1H8V8zM7 7H6V6h1v1zm0-3h1v1H7V4zm0-3H6V0h1v1z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/bell.svg b/htdocs/theme/common/octicons/build/svg/bell.svg
    index d076a0c2129..171f84f1e0f 100644
    --- a/htdocs/theme/common/octicons/build/svg/bell.svg
    +++ b/htdocs/theme/common/octicons/build/svg/bell.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M14 12v1H0v-1l.73-.58c.77-.77.81-2.55 1.19-4.42C2.69 3.23 6 2 6 2c0-.55.45-1 1-1s1 .45 1 1c0 0 3.39 1.23 4.16 5 .38 1.88.42 3.66 1.19 4.42l.66.58H14zm-7 4c1.11 0 2-.89 2-2H5c0 1.11.89 2 2 2z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13.99 11.991v1H0v-1l.73-.58c.769-.769.809-2.547 1.189-4.416.77-3.767 4.077-4.996 4.077-4.996 0-.55.45-1 .999-1 .55 0 1 .45 1 1 0 0 3.387 1.229 4.156 4.996.38 1.879.42 3.657 1.19 4.417l.659.58h-.01zM6.995 15.99c1.11 0 1.999-.89 1.999-1.999H4.996c0 1.11.89 1.999 1.999 1.999z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/bug.svg b/htdocs/theme/common/octicons/build/svg/bug.svg
    index bd533f829e7..75188298bdc 100644
    --- a/htdocs/theme/common/octicons/build/svg/bug.svg
    +++ b/htdocs/theme/common/octicons/build/svg/bug.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.17 10h3V9h-3V8l3.17-1.03-.34-.94-2.83.97V6c0-.55-.45-1-1-1V4c0-.48-.36-.88-.83-.97L10.37 2h1.8V1h-2.2l-2 2h-.59L5.37 1h-2.2v1h1.8L6 3.03c-.47.09-.83.48-.83.97v1c-.55 0-1 .45-1 1v1l-2.83-.97-.34.94L4.17 8v1h-3v1h3v1L1 12.03l.34.94L4.17 12v1c0 .55.45 1 1 1h1l1-1V6h1v7l1 1h1c.55 0 1-.45 1-1v-1l2.83.97.34-.94L11.17 11v-1zm-2-5h-3V4h3v1z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11 10h3V9h-3V8l3.17-1.03-.34-.94L11 7V6c0-.55-.45-1-1-1V4c0-.48-.36-.88-.83-.97L10.2 2H12V1H9.8l-2 2h-.59L5.2 1H3v1h1.8l1.03 1.03C5.36 3.12 5 3.51 5 4v1c-.55 0-1 .45-1 1v1l-2.83-.97-.34.94L4 8v1H1v1h3v1L.83 12.03l.34.94L4 12v1c0 .55.45 1 1 1h1l1-1V6h1v7l1 1h1c.55 0 1-.45 1-1v-1l2.83.97.34-.94L11 11v-1zM9 5H6V4h3v1z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/check.svg b/htdocs/theme/common/octicons/build/svg/check.svg
    index 2d59600912e..2df5deeef92 100644
    --- a/htdocs/theme/common/octicons/build/svg/check.svg
    +++ b/htdocs/theme/common/octicons/build/svg/check.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 5.5l-8 8-4-4L1.5 8 4 10.5 10.5 4 12 5.5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/chevron-down.svg b/htdocs/theme/common/octicons/build/svg/chevron-down.svg
    index 3a4e0aad5c6..32eab7b007f 100644
    --- a/htdocs/theme/common/octicons/build/svg/chevron-down.svg
    +++ b/htdocs/theme/common/octicons/build/svg/chevron-down.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="10" height="16" viewBox="0 0 10 16"><path fill-rule="evenodd" d="M5 11.5l-5-5L1.5 5 5 8.75 8.5 5 10 6.5l-5 5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="10" height="16" viewBox="0 0 10 16"><path fill-rule="evenodd" d="M5 11L0 6l1.5-1.5L5 8.25 8.5 4.5 10 6l-5 5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/chevron-left.svg b/htdocs/theme/common/octicons/build/svg/chevron-left.svg
    index 2de62df36b3..680c9a0740c 100644
    --- a/htdocs/theme/common/octicons/build/svg/chevron-left.svg
    +++ b/htdocs/theme/common/octicons/build/svg/chevron-left.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="8" height="16" viewBox="0 0 8 16"><path fill-rule="evenodd" d="M6 3l1.5 1.5L3.75 8l3.75 3.5L6 13 1 8l5-5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="8" height="16" viewBox="0 0 8 16"><path fill-rule="evenodd" d="M5.5 3L7 4.5 3.25 8 7 11.5 5.5 13l-5-5 5-5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/database.svg b/htdocs/theme/common/octicons/build/svg/database.svg
    index 08b036d9aee..e686d98e4c7 100644
    --- a/htdocs/theme/common/octicons/build/svg/database.svg
    +++ b/htdocs/theme/common/octicons/build/svg/database.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6 15c-3.31 0-6-.9-6-2v-2c0-.17.09-.34.21-.5.67.86 3 1.5 5.79 1.5s5.12-.64 5.79-1.5c.13.16.21.33.21.5v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V7c0-.11.04-.21.09-.31.03-.06.07-.13.12-.19C.88 7.36 3.21 8 6 8s5.12-.64 5.79-1.5c.05.06.09.13.12.19.05.1.09.21.09.31v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V4 3c0-1.1 2.69-2 6-2s6 .9 6 2v2c0 1.1-2.69 2-6 2zm0-5c-2.21 0-4 .45-4 1s1.79 1 4 1 4-.45 4-1-1.79-1-4-1z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6 15c-3.31 0-6-.9-6-2v-2c0-.17.09-.34.21-.5.67.86 3 1.5 5.79 1.5s5.12-.64 5.79-1.5c.13.16.21.33.21.5v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V7c0-.11.04-.21.09-.31.03-.06.07-.13.12-.19C.88 7.36 3.21 8 6 8s5.12-.64 5.79-1.5c.05.06.09.13.12.19.05.1.09.21.09.31v2c0 1.1-2.69 2-6 2zm0-4c-3.31 0-6-.9-6-2V3c0-1.1 2.69-2 6-2s6 .9 6 2v2c0 1.1-2.69 2-6 2zm0-5c-2.21 0-4 .45-4 1s1.79 1 4 1 4-.45 4-1-1.79-1-4-1z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/device-camera-video.svg b/htdocs/theme/common/octicons/build/svg/device-camera-video.svg
    index 8f989c86e9c..dc0e55e6f0b 100644
    --- a/htdocs/theme/common/octicons/build/svg/device-camera-video.svg
    +++ b/htdocs/theme/common/octicons/build/svg/device-camera-video.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.2 2.091L10 5.721v-2.72c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h8c.55 0 1-.45 1-1v-2.72l5.2 3.63c.33.23.8 0 .8-.41v-10c0-.41-.47-.64-.8-.41z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.2 2.09L10 5.72V3c0-.55-.45-1-1-1H1c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h8c.55 0 1-.45 1-1V9.28l5.2 3.63c.33.23.8 0 .8-.41v-10c0-.41-.47-.64-.8-.41z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/file-pdf.svg b/htdocs/theme/common/octicons/build/svg/file-pdf.svg
    index 1b1703e19fd..6d04a046024 100644
    --- a/htdocs/theme/common/octicons/build/svg/file-pdf.svg
    +++ b/htdocs/theme/common/octicons/build/svg/file-pdf.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M8.5 1H1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V4.5L8.5 1zM1 2h4a.68.68 0 0 0-.31.2 1.08 1.08 0 0 0-.23.47 4.22 4.22 0 0 0-.09 1.47c.06.609.173 1.211.34 1.8A21.78 21.78 0 0 1 3.6 8.6c-.5 1-.8 1.66-.91 1.84a7.161 7.161 0 0 0-.69.3 4.19 4.19 0 0 0-1 .64V2zm4.42 4.8a5.65 5.65 0 0 0 1.17 2.09c.275.237.595.417.94.53-.64.09-1.23.2-1.81.33a12.22 12.22 0 0 0-1.81.59c-.587.243.22-.44.61-1.25.365-.74.67-1.51.91-2.3l-.01.01zM11 14H1.5a.743.743 0 0 1-.17 0 2.12 2.12 0 0 0 .73-.44 10.14 10.14 0 0 0 1.78-2.38c.31-.13.58-.23.81-.31l.42-.14c.45-.13.94-.23 1.44-.33s1-.16 1.48-.2c.447.216.912.394 1.39.53.403.11.814.188 1.23.23h.38V14H11zm0-4.86a3.74 3.74 0 0 0-.64-.28 4.22 4.22 0 0 0-.75-.11c-.411.003-.822.03-1.23.08a3 3 0 0 1-1-.64 6.07 6.07 0 0 1-1.29-2.33c.111-.662.178-1.33.2-2 .02-.25.02-.5 0-.75a1.05 1.05 0 0 0-.2-.88.82.82 0 0 0-.61-.23H8l3 3v4.14z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M8.5 1H1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V4.5L8.5 1zM1 2h4a.68.68 0 0 0-.31.2 1.08 1.08 0 0 0-.23.47 4.22 4.22 0 0 0-.09 1.47c.06.609.173 1.211.34 1.8A21.78 21.78 0 0 1 3.6 8.6c-.5 1-.8 1.66-.91 1.84a7.156 7.156 0 0 0-.69.3c-.362.165-.699.38-1 .64V2zm4.42 4.8a5.65 5.65 0 0 0 1.17 2.09c.275.237.595.417.94.53-.64.09-1.23.2-1.81.33-.618.15-1.223.347-1.81.59s.22-.44.61-1.25c.365-.74.67-1.51.91-2.3l-.01.01zM11 14H1.5a.743.743 0 0 1-.17 0 2.12 2.12 0 0 0 .73-.44 10.14 10.14 0 0 0 1.78-2.38c.31-.13.58-.23.81-.31l.42-.14c.45-.13.94-.23 1.44-.33s1-.16 1.48-.2c.447.216.912.394 1.39.53.403.11.814.188 1.23.23h.38V14H11zm0-4.86a3.743 3.743 0 0 0-.64-.28 4.221 4.221 0 0 0-.75-.11c-.411.003-.822.03-1.23.08a3 3 0 0 1-1-.64 6.07 6.07 0 0 1-1.29-2.33c.111-.661.178-1.33.2-2 .02-.25.02-.5 0-.75a1.05 1.05 0 0 0-.2-.88.82.82 0 0 0-.61-.23H8l3 3v4.14z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/flame.svg b/htdocs/theme/common/octicons/build/svg/flame.svg
    index 49507a1073a..1fcb94b429a 100644
    --- a/htdocs/theme/common/octicons/build/svg/flame.svg
    +++ b/htdocs/theme/common/octicons/build/svg/flame.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.01c.81 2.17.41 3.38-.52 4.31C3.55 5.37 1.98 6.15.9 7.68c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.01 8.68 2.15 5.05.02L5.03 0l.02.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/gear.svg b/htdocs/theme/common/octicons/build/svg/gear.svg
    index aded0c46675..bf82007a485 100644
    --- a/htdocs/theme/common/octicons/build/svg/gear.svg
    +++ b/htdocs/theme/common/octicons/build/svg/gear.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M14 8.76v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45L7.77 1h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.22v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.74v.02zm-7 2.23c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M14 8.77v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45-.69-1.92h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.23v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.75v.02zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/gift.svg b/htdocs/theme/common/octicons/build/svg/gift.svg
    index 761be5473ca..4539ce60945 100644
    --- a/htdocs/theme/common/octicons/build/svg/gift.svg
    +++ b/htdocs/theme/common/octicons/build/svg/gift.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13.02 4h-1.38c.19-.33.33-.67.36-.91.06-.67-.11-1.22-.52-1.61-.36-.38-.81-.48-1.36-.48h-.11c-.53.02-1.11.25-1.53.58-.42.33-.73.72-.97 1.2-.23-.48-.55-.88-.97-1.2-.42-.32-1-.58-1.53-.58h-.03c-.56 0-1.06.09-1.44.48-.41.39-.58.94-.52 1.61.03.23.17.58.36.91H2c-.55 0-1 .45-1 1v3h1v5c0 .55.45 1 1 1h9c.55 0 1-.45 1-1V8h1V5c0-.55-.45-1-1-1h.02zm-4.78-.88c.17-.36.42-.67.75-.92.3-.23.72-.39 1.05-.41h.09c.45 0 .66.11.8.25s.33.39.3.95c-.05.19-.25.61-.5 1h-2.9l.41-.88v.01zM4.11 2.04c.13-.13.31-.25.91-.25.31 0 .72.17 1.03.41.33.25.58.55.75.92l.42.88h-2.9c-.25-.39-.45-.81-.5-1-.03-.56.16-.81.3-.95l-.01-.01zm2.91 10.95h-4V8h4v5-.01zm0-6h-5V5h5v2-.01zm5 6h-4V8h4v5-.01zm1-6h-5V5h5v2-.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M13 4h-1.38c.19-.33.33-.67.36-.91.06-.67-.11-1.22-.52-1.61C11.1 1.1 10.65 1 10.1 1h-.11c-.53.02-1.11.25-1.53.58-.42.33-.73.72-.97 1.2-.23-.48-.55-.88-.97-1.2-.42-.32-1-.58-1.53-.58h-.03c-.56 0-1.06.09-1.44.48-.41.39-.58.94-.52 1.61.03.23.17.58.36.91H1.98c-.55 0-1 .45-1 1v3h1v5c0 .55.45 1 1 1h9c.55 0 1-.45 1-1V8h1V5c0-.55-.45-1-1-1H13zm-4.78-.88c.17-.36.42-.67.75-.92.3-.23.72-.39 1.05-.41h.09c.45 0 .66.11.8.25s.33.39.3.95c-.05.19-.25.61-.5 1h-2.9l.41-.88v.01zM4.09 2.04c.13-.13.31-.25.91-.25.31 0 .72.17 1.03.41.33.25.58.55.75.92L7.2 4H4.3c-.25-.39-.45-.81-.5-1-.03-.56.16-.81.3-.95l-.01-.01zM7 12.99H3V8h4v5-.01zm0-6H2V5h5v2-.01zm5 6H8V8h4v5-.01zm1-6H8V5h5v2-.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/gist-secret.svg b/htdocs/theme/common/octicons/build/svg/gist-secret.svg
    index a6459e19bf2..6495281267c 100644
    --- a/htdocs/theme/common/octicons/build/svg/gist-secret.svg
    +++ b/htdocs/theme/common/octicons/build/svg/gist-secret.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7.782 10.5l1 3.5h-4l1-3.5-.75-1.5h3.5l-.75 1.5zm2-4.5h-6l-2 1h10l-2-1zm-1-4l-2 1-2-1-1 3h6l-1-3zm4.03 7.75L9.782 9l1 2-2 3h3.22c.45 0 .86-.31.97-.75l.56-2.28c.14-.53-.19-1.08-.72-1.22zM3.782 9l-3.03.75c-.53.14-.86.69-.72 1.22l.56 2.28c.11.44.52.75.97.75h3.22l-2-3 1-2z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M8 10.5L9 14H5l1-3.5L5.25 9h3.5L8 10.5zM10 6H4L2 7h10l-2-1zM9 2L7 3 5 2 4 5h6L9 2zm4.03 7.75L10 9l1 2-2 3h3.22c.45 0 .86-.31.97-.75l.56-2.28c.14-.53-.19-1.08-.72-1.22zM4 9l-3.03.75c-.53.14-.86.69-.72 1.22l.56 2.28c.11.44.52.75.97.75H5l-2-3 1-2z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/git-merge.svg b/htdocs/theme/common/octicons/build/svg/git-merge.svg
    index fedb516064a..63c43f76936 100644
    --- a/htdocs/theme/common/octicons/build/svg/git-merge.svg
    +++ b/htdocs/theme/common/octicons/build/svg/git-merge.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M10 7.01c-.73 0-1.38.41-1.73 1.02v-.02C7.22 7.99 6 7.65 5.14 6.99c-.75-.58-1.5-1.61-1.89-2.44A1.993 1.993 0 0 0 2 1C.89 1 0 1.9 0 3.01a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2a1.993 1.993 0 0 0 1-3.72V7.68c.67.7 1.44 1.27 2.3 1.69.86.42 2.03.63 2.97.64v-.02c.36.61 1 1.02 1.73 1.02 1.11 0 2-.89 2-2 0-1.11-.89-2-2-2zm-6.8 6c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.21c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm8 6c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M10 7c-.73 0-1.38.41-1.73 1.02V8C7.22 7.98 6 7.64 5.14 6.98c-.75-.58-1.5-1.61-1.89-2.44A1.993 1.993 0 0 0 2 .99C.89.99 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2a1.993 1.993 0 0 0 1-3.72V7.67c.67.7 1.44 1.27 2.3 1.69.86.42 2.03.63 2.97.64v-.02c.36.61 1 1.02 1.73 1.02 1.11 0 2-.89 2-2 0-1.11-.89-2-2-2zm-6.8 6c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm8 6c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/heart.svg b/htdocs/theme/common/octicons/build/svg/heart.svg
    index 8b81f8845fe..e9407b514c7 100644
    --- a/htdocs/theme/common/octicons/build/svg/heart.svg
    +++ b/htdocs/theme/common/octicons/build/svg/heart.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M11.2 3c-.52-.63-1.25-.95-2.2-1-.97 0-1.69.42-2.2 1-.51.58-.78.92-.8 1-.02-.08-.28-.42-.8-1-.52-.58-1.17-1-2.2-1-.95.05-1.69.38-2.2 1-.52.61-.78 1.28-.8 2 0 .52.09 1.52.67 2.67C1.25 8.82 3.01 10.61 6 13c2.98-2.39 4.77-4.17 5.34-5.33C11.91 6.51 12 5.5 12 5c-.02-.72-.28-1.39-.8-2.02V3z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M9 2c-.97 0-1.69.42-2.2 1-.51.58-.78.92-.8 1-.02-.08-.28-.42-.8-1-.52-.58-1.17-1-2.2-1-1.632.086-2.954 1.333-3 3 0 .52.09 1.52.67 2.67C1.25 8.82 3.01 10.61 6 13c2.98-2.39 4.77-4.17 5.34-5.33C11.91 6.51 12 5.5 12 5c-.047-1.69-1.342-2.913-3-3z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/info.svg b/htdocs/theme/common/octicons/build/svg/info.svg
    index 745ef337a3d..26db463ff03 100644
    --- a/htdocs/theme/common/octicons/build/svg/info.svg
    +++ b/htdocs/theme/common/octicons/build/svg/info.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.71a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 8.01c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V8v.01zM7 2.32C3.86 2.32 1.3 4.86 1.3 8c0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 1c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/list-ordered.svg b/htdocs/theme/common/octicons/build/svg/list-ordered.svg
    index 64126c3b8ef..2450532b491 100644
    --- a/htdocs/theme/common/octicons/build/svg/list-ordered.svg
    +++ b/htdocs/theme/common/octicons/build/svg/list-ordered.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12.01 13c0 .59 0 1-.59 1H4.6c-.59 0-.59-.41-.59-1 0-.59 0-1 .59-1h6.81c.59 0 .59.41.59 1h.01zM4.6 4h6.81C12 4 12 3.59 12 3c0-.59 0-1-.59-1H4.6c-.59 0-.59.41-.59 1 0 .59 0 1 .59 1zm6.81 3H4.6c-.59 0-.59.41-.59 1 0 .59 0 1 .59 1h6.81C12 9 12 8.59 12 8c0-.59 0-1-.59-1zm-9.4-6h-.72c-.3.19-.58.25-1.03.34V2h.75v2.14H.17V5h2.84v-.86h-1V1zm.25 8.13c-.17 0-.45.03-.66.06.53-.56 1.14-1.25 1.14-1.89C2.72 6.52 2.18 6 1.38 6c-.59 0-.97.2-1.38.64l.58.58c.19-.19.38-.38.64-.38.28 0 .48.16.48.52 0 .53-.77 1.2-1.7 2.06V10h3l-.09-.88h-.66l.01.01zm-.08 3.78v-.03c.44-.19.64-.47.64-.86 0-.7-.56-1.11-1.44-1.11-.48 0-.89.19-1.28.52l.55.64c.25-.2.44-.31.69-.31.27 0 .42.13.42.36 0 .27-.2.44-.86.44v.75c.83 0 .98.17.98.47 0 .25-.23.38-.58.38-.28 0-.56-.14-.81-.38l-.48.66c.3.36.77.56 1.41.56.83 0 1.53-.41 1.53-1.16 0-.5-.31-.81-.77-.94v.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M12 12.99c0 .589 0 .998-.59.998H4.597c-.59 0-.59-.41-.59-.999 0-.59 0-.999.59-.999H11.4c.59 0 .59.41.59 1H12zM4.596 3.996H11.4c.59 0 .59-.41.59-1 0-.589 0-.999-.59-.999H4.596c-.59 0-.59.41-.59 1 0 .589 0 .999.59.999zM11.4 6.994H4.596c-.59 0-.59.41-.59 1 0 .589 0 .999.59.999H11.4c.59 0 .59-.41.59-1 0-.59 0-.999-.59-.999zM2.008 1h-.72C.99 1.19.71 1.25.26 1.34V2h.75v2.138H.17v.859h2.837v-.86h-.999V1zm.25 8.123c-.17 0-.45.03-.66.06.53-.56 1.14-1.249 1.14-1.888-.02-.78-.56-1.299-1.36-1.299-.589 0-.968.2-1.378.64l.58.579c.19-.19.38-.38.639-.38.28 0 .48.16.48.52 0 .53-.77 1.199-1.699 2.058v.58h2.998l-.09-.88h-.66l.01.01zm-.08 3.777v-.03c.44-.19.64-.47.64-.859 0-.7-.56-1.11-1.44-1.11-.479 0-.888.19-1.278.52l.55.64c.25-.2.44-.31.689-.31.27 0 .42.13.42.36 0 .27-.2.44-.86.44v.749c.83 0 .98.17.98.47 0 .25-.23.38-.58.38-.28 0-.56-.14-.81-.38l-.479.659c.3.36.77.56 1.409.56.83 0 1.529-.41 1.529-1.16 0-.5-.31-.809-.77-.939v.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/logo-github.svg b/htdocs/theme/common/octicons/build/svg/logo-github.svg
    index 253c13ecbaa..0da3476f6e3 100644
    --- a/htdocs/theme/common/octicons/build/svg/logo-github.svg
    +++ b/htdocs/theme/common/octicons/build/svg/logo-github.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="45" height="16" viewBox="0 0 45 16"><path fill-rule="evenodd" d="M18.53 12.03h-.02c.009 0 .015.01.024.011h.006l-.01-.01zm.004.011c-.093.001-.327.05-.574.05-.78 0-1.05-.36-1.05-.83V8.13h1.59c.09 0 .16-.08.16-.19v-1.7c0-.09-.08-.17-.16-.17h-1.59V3.96c0-.08-.05-.13-.14-.13h-2.16c-.09 0-.14.05-.14.13v2.17s-1.09.27-1.16.28c-.08.02-.13.09-.13.17v1.36c0 .11.08.19.17.19h1.11v3.28c0 2.44 1.7 2.69 2.86 2.69.53 0 1.17-.17 1.27-.22.06-.02.09-.09.09-.16v-1.5a.177.177 0 0 0-.146-.18zm23.696-2.2c0-1.81-.73-2.05-1.5-1.97-.6.04-1.08.34-1.08.34v3.52s.49.34 1.22.36c1.03.03 1.36-.34 1.36-2.25zm2.43-.16c0 3.43-1.11 4.41-3.05 4.41-1.64 0-2.52-.83-2.52-.83s-.04.46-.09.52c-.03.06-.08.08-.14.08h-1.48c-.1 0-.19-.08-.19-.17l.02-11.11c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v3.77s.82-.53 2.02-.53l-.01-.02c1.2 0 2.97.45 2.97 3.88zm-8.72-3.61H33.84c-.11 0-.17.08-.17.19v5.44s-.55.39-1.3.39-.97-.34-.97-1.09V6.25c0-.09-.08-.17-.17-.17h-2.14c-.09 0-.17.08-.17.17v5.11c0 2.2 1.23 2.75 2.92 2.75 1.39 0 2.52-.77 2.52-.77s.05.39.08.45c.02.05.09.09.16.09h1.34c.11 0 .17-.08.17-.17l.02-7.47c0-.09-.08-.17-.19-.17zm-23.7-.01h-2.13c-.09 0-.17.09-.17.2v7.34c0 .2.13.27.3.27h1.92c.2 0 .25-.09.25-.27V6.23c0-.09-.08-.17-.17-.17zm-1.05-3.38c-.77 0-1.38.61-1.38 1.38 0 .77.61 1.38 1.38 1.38.75 0 1.36-.61 1.36-1.38 0-.77-.61-1.38-1.36-1.38zm16.49-.25h-2.11c-.09 0-.17.08-.17.17v4.09h-3.31V2.6c0-.09-.08-.17-.17-.17h-2.13c-.09 0-.17.08-.17.17v11.11c0 .09.09.17.17.17h2.13c.09 0 .17-.08.17-.17V8.96h3.31l-.02 4.75c0 .09.08.17.17.17h2.13c.09 0 .17-.08.17-.17V2.6c0-.09-.08-.17-.17-.17zM8.81 7.35v5.74c0 .04-.01.11-.06.13 0 0-1.25.89-3.31.89-2.49 0-5.44-.78-5.44-5.92S2.58 1.99 5.1 2c2.18 0 3.06.49 3.2.58.04.05.06.09.06.14L7.94 4.5c0 .09-.09.2-.2.17-.36-.11-.9-.33-2.17-.33-1.47 0-3.05.42-3.05 3.73s1.5 3.7 2.58 3.7c.92 0 1.25-.11 1.25-.11v-2.3H4.88c-.11 0-.19-.08-.19-.17V7.35c0-.09.08-.17.19-.17h3.74c.11 0 .19.08.19.17z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="45" height="16" viewBox="0 0 45 16"><path fill-rule="evenodd" d="M18.53 12.03h-.02c.009 0 .015.01.024.011h.006l-.01-.01zm.004.011c-.093.001-.327.05-.574.05-.78 0-1.05-.36-1.05-.83V8.13h1.59c.09 0 .16-.08.16-.19v-1.7c0-.09-.08-.17-.16-.17h-1.59V3.96c0-.08-.05-.13-.14-.13h-2.16c-.09 0-.14.05-.14.13v2.17s-1.09.27-1.16.28c-.08.02-.13.09-.13.17v1.36c0 .11.08.19.17.19h1.11v3.28c0 2.44 1.7 2.69 2.86 2.69.53 0 1.17-.17 1.27-.22.06-.02.09-.09.09-.16v-1.5a.177.177 0 0 0-.146-.18zm23.696-2.2c0-1.81-.73-2.05-1.5-1.97-.6.04-1.08.34-1.08.34v3.52s.49.34 1.22.36c1.03.03 1.36-.34 1.36-2.25zm2.43-.16c0 3.43-1.11 4.41-3.05 4.41-1.64 0-2.52-.83-2.52-.83s-.04.46-.09.52c-.03.06-.08.08-.14.08h-1.48c-.1 0-.19-.08-.19-.17l.02-11.11c0-.09.08-.17.17-.17h2.13c.09 0 .17.08.17.17v3.77s.82-.53 2.02-.53l-.01-.02c1.2 0 2.97.45 2.97 3.88zm-8.72-3.61h-2.1c-.11 0-.17.08-.17.19v5.44s-.55.39-1.3.39-.97-.34-.97-1.09V6.25c0-.09-.08-.17-.17-.17h-2.14c-.09 0-.17.08-.17.17v5.11c0 2.2 1.23 2.75 2.92 2.75 1.39 0 2.52-.77 2.52-.77s.05.39.08.45c.02.05.09.09.16.09h1.34c.11 0 .17-.08.17-.17l.02-7.47c0-.09-.08-.17-.19-.17zm-23.7-.01h-2.13c-.09 0-.17.09-.17.2v7.34c0 .2.13.27.3.27h1.92c.2 0 .25-.09.25-.27V6.23c0-.09-.08-.17-.17-.17zm-1.05-3.38c-.77 0-1.38.61-1.38 1.38 0 .77.61 1.38 1.38 1.38.75 0 1.36-.61 1.36-1.38 0-.77-.61-1.38-1.36-1.38zm16.49-.25h-2.11c-.09 0-.17.08-.17.17v4.09h-3.31V2.6c0-.09-.08-.17-.17-.17h-2.13c-.09 0-.17.08-.17.17v11.11c0 .09.09.17.17.17h2.13c.09 0 .17-.08.17-.17V8.96h3.31l-.02 4.75c0 .09.08.17.17.17h2.13c.09 0 .17-.08.17-.17V2.6c0-.09-.08-.17-.17-.17zM8.81 7.35v5.74c0 .04-.01.11-.06.13 0 0-1.25.89-3.31.89-2.49 0-5.44-.78-5.44-5.92S2.58 1.99 5.1 2c2.18 0 3.06.49 3.2.58.04.05.06.09.06.14L7.94 4.5c0 .09-.09.2-.2.17-.36-.11-.9-.33-2.17-.33-1.47 0-3.05.42-3.05 3.73s1.5 3.7 2.58 3.7c.92 0 1.25-.11 1.25-.11v-2.3H4.88c-.11 0-.19-.08-.19-.17V7.35c0-.09.08-.17.19-.17h3.74c.11 0 .19.08.19.17z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/mortar-board.svg b/htdocs/theme/common/octicons/build/svg/mortar-board.svg
    index 302415b1736..869f9ae8e7c 100644
    --- a/htdocs/theme/common/octicons/build/svg/mortar-board.svg
    +++ b/htdocs/theme/common/octicons/build/svg/mortar-board.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M7.808 9.405l-3.83-1.19c-4-8 0 1.5 0 2.5s1.8 1.5 4 1.5 4-.5 4-1.5v-2.5l-3.83 1.19a.73.73 0 0 1-.36 0h.02zm.28-6.39a.34.34 0 0 0-.2 0l-7.64 2.38a.35.35 0 0 0 0 .67l1.73.55v1.77c-.3.17-.5.5-.5.86 0 .19.05.36.14.5-.08.14-.14.31-.14.5v2.58c0 .55 2 .55 2 0v-2.58c0-.19-.05-.36-.14-.5.08-.14.14-.31.14-.5 0-.38-.2-.69-.5-.86v-1.45l4.89 1.53c.06.02.14.02.2 0l7.64-2.38a.35.35 0 0 0 0-.67l-7.63-2.39.01-.01zm-.09 3.2c-.55 0-1-.22-1-.5s.45-.5 1-.5 1 .22 1 .5-.45.5-1 .5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M7.83 9.19L4 8c-4-8 0 1.5 0 2.5S5.8 12 8 12s4-.5 4-1.5V8L8.17 9.19a.73.73 0 0 1-.36 0h.02zm.28-6.39a.34.34 0 0 0-.2 0L.27 5.18a.35.35 0 0 0 0 .67L2 6.4v1.77c-.3.17-.5.5-.5.86 0 .19.05.36.14.5-.08.14-.14.31-.14.5v2.58c0 .55 2 .55 2 0v-2.58c0-.19-.05-.36-.14-.5.08-.14.14-.31.14-.5 0-.38-.2-.69-.5-.86V6.72l4.89 1.53c.06.02.14.02.2 0l7.64-2.38a.35.35 0 0 0 0-.67L8.1 2.81l.01-.01zM8.02 6c-.55 0-1-.22-1-.5s.45-.5 1-.5 1 .22 1 .5-.45.5-1 .5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/mute.svg b/htdocs/theme/common/octicons/build/svg/mute.svg
    index 4d894a1cadd..e448808fbe5 100644
    --- a/htdocs/theme/common/octicons/build/svg/mute.svg
    +++ b/htdocs/theme/common/octicons/build/svg/mute.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 2.75v10.38c0 .67-.81 1-1.28.53L3 9.94H1c-.55 0-1-.45-1-1v-2c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.75 8 2.08 8 2.75zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06 1.97 1.97-1.97 1.97 1.06 1.06L12.5 9l1.97 1.97 1.06-1.06-1.97-1.97 1.97-1.97z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 2.81v10.38c0 .67-.81 1-1.28.53L3 10H1c-.55 0-1-.45-1-1V7c0-.55.45-1 1-1h2l3.72-3.72C7.19 1.81 8 2.14 8 2.81zm7.53 3.22l-1.06-1.06-1.97 1.97-1.97-1.97-1.06 1.06L11.44 8 9.47 9.97l1.06 1.06 1.97-1.97 1.97 1.97 1.06-1.06L13.56 8l1.97-1.97z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/organization.svg b/htdocs/theme/common/octicons/build/svg/organization.svg
    index af333e418dd..6bf4ae94b40 100644
    --- a/htdocs/theme/common/octicons/build/svg/organization.svg
    +++ b/htdocs/theme/common/octicons/build/svg/organization.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088A6.78 6.78 0 0 1 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/package.svg b/htdocs/theme/common/octicons/build/svg/package.svg
    index 720e30026a5..2db03518db2 100644
    --- a/htdocs/theme/common/octicons/build/svg/package.svg
    +++ b/htdocs/theme/common/octicons/build/svg/package.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 4.732v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97v-7.47c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0l-6.5 1.74c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59v-6.77l6 1.61v6.75zm-6-9.36l2.5-.67 6.5 1.73-2.5.67L2 4.463zm13 7.77l-6 1.59v-6.75l2-.55v2.44l2-.53v-2.44l2-.53v6.77zm-2-7.24l-6.5-1.73 2-.53 6.5 1.73-2 .53z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 4.27v7.47c0 .45.3.84.75.97l6.5 1.73c.16.05.34.05.5 0l6.5-1.73c.45-.13.75-.52.75-.97V4.27c0-.45-.3-.84-.75-.97l-6.5-1.74a1.4 1.4 0 0 0-.5 0L1.75 3.3c-.45.13-.75.52-.75.97zm7 9.09l-6-1.59V5l6 1.61v6.75zM2 4l2.5-.67L11 5.06l-2.5.67L2 4zm13 7.77l-6 1.59V6.61l2-.55V8.5l2-.53V5.53L15 5v6.77zm-2-7.24L6.5 2.8l2-.53L15 4l-2 .53z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/pencil.svg b/htdocs/theme/common/octicons/build/svg/pencil.svg
    index 41c6e7ec6f8..8702f4dcecd 100644
    --- a/htdocs/theme/common/octicons/build/svg/pencil.svg
    +++ b/htdocs/theme/common/octicons/build/svg/pencil.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M0 11.592v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3l-1.3 1.3-3-3 1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/pin.svg b/htdocs/theme/common/octicons/build/svg/pin.svg
    index 861ae05afdc..95405c537c0 100644
    --- a/htdocs/theme/common/octicons/build/svg/pin.svg
    +++ b/htdocs/theme/common/octicons/build/svg/pin.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M10 1.494v.8l.5 1-4.5 3H2.2c-.44 0-.67.53-.34.86L5 10.294l-4 5 5-4 3.14 3.14a.5.5 0 0 0 .86-.34v-3.8l3-4.5 1 .5h.8c.44 0 .67-.53.34-.86l-4.28-4.28a.5.5 0 0 0-.86.34z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M10 1.2V2l.5 1L6 6H2.2c-.44 0-.67.53-.34.86L5 10l-4 5 5-4 3.14 3.14a.5.5 0 0 0 .86-.34V10l3-4.5 1 .5h.8c.44 0 .67-.53.34-.86L10.86.86a.5.5 0 0 0-.86.34z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/pulse.svg b/htdocs/theme/common/octicons/build/svg/pulse.svg
    index d87d04ea419..4ec57bacaae 100644
    --- a/htdocs/theme/common/octicons/build/svg/pulse.svg
    +++ b/htdocs/theme/common/octicons/build/svg/pulse.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M11.5 8.4L8.8 5.8 6.6 8.9 5.5 2 2.38 8.4H0v2h3.6l.9-1.8.9 5.4L9 8.9l1.6 1.5H14v-2h-2.5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8h-2.5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/quote.svg b/htdocs/theme/common/octicons/build/svg/quote.svg
    index 7b5f4a7f191..da5c2b22cef 100644
    --- a/htdocs/theme/common/octicons/build/svg/quote.svg
    +++ b/htdocs/theme/common/octicons/build/svg/quote.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.16 3.84C3.73 5.4 2.55 7.01 2.55 9.7c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.9 0-2.99-1.52-2.99-4.25C0 6.62 1.75 3.89 5.02 2l1.14 1.84zm7 0C10.73 5.4 9.55 7.01 9.55 9.7c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.89 0-2.98-1.52-2.98-4.25 0-3.8 1.75-6.53 5.02-8.42l1.14 1.84h-.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.16 3.5C3.73 5.06 2.55 6.67 2.55 9.36c.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.9 0-2.99-1.52-2.99-4.25 0-3.8 1.75-6.53 5.02-8.42L6.16 3.5zm7 0c-2.43 1.56-3.61 3.17-3.61 5.86.16-.05.3-.05.44-.05 1.27 0 2.5.86 2.5 2.41 0 1.61-1.03 2.61-2.5 2.61-1.89 0-2.98-1.52-2.98-4.25 0-3.8 1.75-6.53 5.02-8.42l1.14 1.84h-.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/radio-tower.svg b/htdocs/theme/common/octicons/build/svg/radio-tower.svg
    index a438661ce55..f89a7052a7a 100644
    --- a/htdocs/theme/common/octicons/build/svg/radio-tower.svg
    +++ b/htdocs/theme/common/octicons/build/svg/radio-tower.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.78 5.78c.25-.25.25-.67 0-.92-.32-.33-.48-.76-.48-1.19 0-.43.16-.86.48-1.19.25-.26.25-.67 0-.92a.613.613 0 0 0-.45-.19c-.16 0-.33.06-.45.19-.57.58-.85 1.35-.85 2.11 0 .76.29 1.53.85 2.11.25.25.66.25.9 0zM2.32.19a.651.651 0 0 0-.92 0C.47 1.15 0 2.41 0 3.66c0 1.26.47 2.52 1.4 3.48.25.26.66.26.91 0s.25-.68 0-.94c-.68-.7-1.02-1.62-1.02-2.54 0-.92.34-1.84 1.02-2.54a.66.66 0 0 0 .01-.93zm5.69 5.1a1.62 1.62 0 1 0-1.62-1.62c-.01.89.72 1.62 1.62 1.62zM14.58.2a.628.628 0 0 0-.91 0c-.25.26-.25.68 0 .94.68.7 1.02 1.62 1.02 2.54 0 .92-.34 1.83-1.02 2.54-.25.26-.25.68 0 .94a.651.651 0 0 0 .92 0c.93-.96 1.4-2.22 1.4-3.48A5.048 5.048 0 0 0 14.58.2zM8.01 6.59c-.41 0-.83-.1-1.2-.3l-3.15 8.37h1.49l.86-1h4l.84 1h1.49L9.2 6.29c-.38.2-.78.3-1.19.3zM8 7.07l1.01 3.6h-2L8 7.07zm-1.99 5.59l1-1h2l1 1h-4zm5.19-11.1c-.25.25-.25.67 0 .92.32.33.48.76.48 1.19 0 .43-.16.86-.48 1.19-.25.26-.25.67 0 .92a.63.63 0 0 0 .9 0c.57-.58.85-1.35.85-2.11 0-.76-.28-1.53-.85-2.11a.634.634 0 0 0-.9 0z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4.79 6.11c.25-.25.25-.67 0-.92-.32-.33-.48-.76-.48-1.19 0-.43.16-.86.48-1.19.25-.26.25-.67 0-.92a.613.613 0 0 0-.45-.19c-.16 0-.33.06-.45.19-.57.58-.85 1.35-.85 2.11 0 .76.29 1.53.85 2.11.25.25.66.25.9 0zM2.33.52a.651.651 0 0 0-.92 0C.48 1.48.01 2.74.01 3.99c0 1.26.47 2.52 1.4 3.48.25.26.66.26.91 0s.25-.68 0-.94c-.68-.7-1.02-1.62-1.02-2.54 0-.92.34-1.84 1.02-2.54a.66.66 0 0 0 .01-.93zm5.69 5.1A1.62 1.62 0 1 0 6.4 4c-.01.89.72 1.62 1.62 1.62zM14.59.53a.628.628 0 0 0-.91 0c-.25.26-.25.68 0 .94.68.7 1.02 1.62 1.02 2.54 0 .92-.34 1.83-1.02 2.54-.25.26-.25.68 0 .94a.651.651 0 0 0 .92 0c.93-.96 1.4-2.22 1.4-3.48A5.048 5.048 0 0 0 14.59.53zM8.02 6.92c-.41 0-.83-.1-1.2-.3l-3.15 8.37h1.49l.86-1h4l.84 1h1.49L9.21 6.62c-.38.2-.78.3-1.19.3zm-.01.48L9.02 11h-2l.99-3.6zm-1.99 5.59l1-1h2l1 1h-4zm5.19-11.1c-.25.25-.25.67 0 .92.32.33.48.76.48 1.19 0 .43-.16.86-.48 1.19-.25.26-.25.67 0 .92a.63.63 0 0 0 .9 0c.57-.58.85-1.35.85-2.11 0-.76-.28-1.53-.85-2.11a.634.634 0 0 0-.9 0z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/reply.svg b/htdocs/theme/common/octicons/build/svg/reply.svg
    index 5f89aad3010..12717db93da 100644
    --- a/htdocs/theme/common/octicons/build/svg/reply.svg
    +++ b/htdocs/theme/common/octicons/build/svg/reply.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.5 3.5c3.92.44 8 3.125 8 10-2.312-5.062-4.75-6-8-6V11L1 5.5 6.5 0v3.5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6 3.5c3.92.44 8 3.125 8 10-2.312-5.062-4.75-6-8-6V11L.5 5.5 6 0v3.5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/sign-out.svg b/htdocs/theme/common/octicons/build/svg/sign-out.svg
    index e0893cbce43..ccfc4959ae3 100644
    --- a/htdocs/theme/common/octicons/build/svg/sign-out.svg
    +++ b/htdocs/theme/common/octicons/build/svg/sign-out.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M12 9V7H8V5h4V3l4 3-4 3zm-2 3H6V3L2 1h8v3h1V1c0-.55-.45-1-1-1H1C.45 0 0 .45 0 1v11.38c0 .39.22.73.55.91L6 16.01V13h4c.55 0 1-.45 1-1V8h-1v4z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.992 8.994V6.996H7.995v-2h3.997V2.999l3.998 2.998-3.998 2.998zm-1.998 2.998H5.996V2.998L2 1h7.995v2.998h1V1c0-.55-.45-.999-1-.999H.999A1.001 1.001 0 0 0 0 1v11.372c0 .39.22.73.55.91L5.996 16v-3.008h3.998c.55 0 1-.45 1-1V7.995h-1v3.997z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/squirrel.svg b/htdocs/theme/common/octicons/build/svg/squirrel.svg
    index 7c974be5979..3e5b51beea4 100644
    --- a/htdocs/theme/common/octicons/build/svg/squirrel.svg
    +++ b/htdocs/theme/common/octicons/build/svg/squirrel.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M11.75 1c-2.21 0-4 1.31-4 2.92 0 1.94.5 3.03 0 6.08 0-4.5-2.77-6.34-4-6.34.05-.5-.48-.66-.48-.66s-.22.11-.3.34c-.27-.31-.56-.27-.56-.27l-.13.58S.45 4.29.43 6.87c.2.33 1.53.6 2.47.43.89.05.67.79.47.99C2.53 9.13 1.75 8 .75 8s-1 1 0 1 1 1 3 1c-3.09 1.2 0 4 0 4h-1c-1 0-1 1-1 1h6c3 0 5-1 5-3.47 0-.85-.43-1.79-1-2.53-1.11-1.46.23-2.68 1-2 .77.68 3 1 3-2 0-2.21-1.79-4-4-4zm-9.5 5c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M12 1C9.79 1 8 2.31 8 3.92c0 1.94.5 3.03 0 6.08 0-4.5-2.77-6.34-4-6.34.05-.5-.48-.66-.48-.66s-.22.11-.3.34c-.27-.31-.56-.27-.56-.27l-.13.58S.7 4.29.68 6.87c.2.33 1.53.6 2.47.43.89.05.67.79.47.99C2.78 9.13 2 8 1 8S0 9 1 9s1 1 3 1c-3.09 1.2 0 4 0 4H3c-1 0-1 1-1 1h6c3 0 5-1 5-3.47 0-.85-.43-1.79-1-2.53-1.11-1.46.23-2.68 1-2 .77.68 3 1 3-2 0-2.21-1.79-4-4-4zM2.5 6c-.28 0-.5-.22-.5-.5s.22-.5.5-.5.5.22.5.5-.22.5-.5.5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/sync.svg b/htdocs/theme/common/octicons/build/svg/sync.svg
    index 61bef53cbd0..692349a1f93 100644
    --- a/htdocs/theme/common/octicons/build/svg/sync.svg
    +++ b/htdocs/theme/common/octicons/build/svg/sync.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M10.236 7.4a4.15 4.15 0 0 1-1.2 3.6 4.346 4.346 0 0 1-5.41.54l1.17-1.14-4.3-.6.6 4.2 1.31-1.26c2.36 1.74 5.7 1.57 7.84-.54a5.876 5.876 0 0 0 1.74-4.46l-1.75-.34zM2.956 5a4.346 4.346 0 0 1 5.41-.54L7.196 5.6l4.3.6-.6-4.2-1.31 1.26c-2.36-1.74-5.7-1.57-7.85.54-1.24 1.23-1.8 2.85-1.73 4.46l1.75.35A4.17 4.17 0 0 1 2.956 5z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M10.24 7.4a4.15 4.15 0 0 1-1.2 3.6 4.346 4.346 0 0 1-5.41.54L4.8 10.4.5 9.8l.6 4.2 1.31-1.26c2.36 1.74 5.7 1.57 7.84-.54a5.876 5.876 0 0 0 1.74-4.46l-1.75-.34zM2.96 5a4.346 4.346 0 0 1 5.41-.54L7.2 5.6l4.3.6-.6-4.2-1.31 1.26c-2.36-1.74-5.7-1.57-7.85.54C.5 5.03-.06 6.65.01 8.26l1.75.35A4.17 4.17 0 0 1 2.96 5z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/tag.svg b/htdocs/theme/common/octicons/build/svg/tag.svg
    index 6c8a9c43c1e..aee833d91b9 100644
    --- a/htdocs/theme/common/octicons/build/svg/tag.svg
    +++ b/htdocs/theme/common/octicons/build/svg/tag.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7.73 1.73C7.26 1.26 6.62 1 5.96 1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39 1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38 7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16 1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7.685 1.72a2.49 2.49 0 0 0-1.76-.726H3.48A2.5 2.5 0 0 0 .994 3.48v2.456c0 .656.269 1.292.726 1.76l6.024 6.024a.99.99 0 0 0 1.402 0l4.563-4.563a.99.99 0 0 0 0-1.402L7.685 1.72zM2.366 7.048a1.54 1.54 0 0 1-.467-1.123V3.48c0-.874.716-1.58 1.58-1.58h2.456c.418 0 .825.159 1.123.467l6.104 6.094-4.702 4.702-6.094-6.114zm.626-4.066h1.989v1.989H2.982V2.982h.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/telescope.svg b/htdocs/theme/common/octicons/build/svg/telescope.svg
    index ce4bfaaa184..95047dc191d 100644
    --- a/htdocs/theme/common/octicons/build/svg/telescope.svg
    +++ b/htdocs/theme/common/octicons/build/svg/telescope.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7.59 9l3 6h-1l-2-4v5h-1v-6l-2 5h-1l2-5 2-1zm-1-9h-1v1h1V0zm-2 3h-1v1h1V3zm-3-2h-1v1h1V1zM.22 9a.52.52 0 0 0-.16.67l.55.92c.13.23.41.31.64.2l1.39-.66-1.16-2-1.27.86.01.01zm7.89-5.39l-5.8 3.95L3.54 9.7l6.33-3.03L8.1 3.61h.01zm4.22 1.28l-1.47-2.52a.51.51 0 0 0-.72-.17l-1.2.83 1.84 3.2 1.33-.64c.27-.13.36-.44.22-.7z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="16" viewBox="0 0 14 16"><path fill-rule="evenodd" d="M8 9l3 6h-1l-2-4v5H7v-6l-2 5H4l2-5 2-1zM7 0H6v1h1V0zM5 3H4v1h1V3zM2 1H1v1h1V1zM.63 9a.52.52 0 0 0-.16.67l.55.92c.13.23.41.31.64.2l1.39-.66-1.16-2-1.27.86.01.01zm7.89-5.39l-5.8 3.95L3.95 9.7l6.33-3.03-1.77-3.06h.01zm4.22 1.28l-1.47-2.52a.51.51 0 0 0-.72-.17l-1.2.83 1.84 3.2 1.33-.64c.27-.13.36-.44.22-.7z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/thumbsdown.svg b/htdocs/theme/common/octicons/build/svg/thumbsdown.svg
    index ac4c7c6996b..aa319a29879 100644
    --- a/htdocs/theme/common/octicons/build/svg/thumbsdown.svg
    +++ b/htdocs/theme/common/octicons/build/svg/thumbsdown.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.98 7.83l-.97-5.95C14.84.5 13.13 0 12 0H5.69c-.2 0-.38.05-.53.14L3.72 1H2C.94 1 0 1.94 0 3v4c0 1.06.94 2.02 2 2h2c.91 0 1.39.45 2.39 1.55.91 1 .88 1.8.63 3.27-.08.5.06 1 .42 1.42.39.47.98.77 1.56.77 1.83 0 3-3.72 3-5.02l-.02-.98h2.04c1.16 0 1.95-.8 1.98-1.97 0-.06.02-.13-.02-.2v-.01zm-1.97 1.19h-1.99c-.7 0-1.03.28-1.03.97l.03 1.03c0 1.27-1.17 4-2 4-.5 0-1.08-.5-1-1 .25-1.58.34-2.78-.89-4.14C6.11 8.75 5.36 8 4 8V2l1.67-1H12c.73 0 1.95.31 2 1l.02.02 1 6c-.03.64-.38 1-1 1h-.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.97 7.825L15 1.88C14.83.499 13.123 0 11.993 0H5.686c-.2 0-.38.05-.53.14L3.719 1h-1.72C.94 1 0 1.938 0 2.997v3.998c0 1.059.94 2.018 1.999 1.998h1.998c.91 0 1.39.45 2.389 1.55.91.999.88 1.798.63 3.267-.08.5.06 1 .42 1.42.39.47.979.769 1.558.769 1.83 0 2.998-3.718 2.998-5.017l-.02-.98h2.04c1.159 0 1.948-.799 1.978-1.968 0-.06.02-.13-.02-.2v-.01zm-1.969 1.19h-1.989c-.7 0-1.029.28-1.029.969l.03 1.03c0 1.268-1.17 3.997-1.999 3.997-.5 0-1.079-.5-.999-1 .25-1.579.34-2.778-.89-4.137-1.019-1.13-1.768-1.879-3.127-1.879V1.999l1.668-1h6.326c.73 0 1.95.31 2 1l.02.02.999 5.996c-.03.64-.38 1-1 1h-.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/thumbsup.svg b/htdocs/theme/common/octicons/build/svg/thumbsup.svg
    index e77f1e30e57..5b197266c1a 100644
    --- a/htdocs/theme/common/octicons/build/svg/thumbsup.svg
    +++ b/htdocs/theme/common/octicons/build/svg/thumbsup.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14 14c-.05.69-1.27 1-2 1H5.67L4 14V8c1.36 0 2.11-.75 3.13-1.88 1.23-1.36 1.14-2.56.88-4.13-.08-.5.5-1 1-1 .83 0 2 2.73 2 4l-.02 1.03c0 .69.33.97 1.02.97h2c.63 0 .98.36 1 1l-1 6L14 14zm0-8h-2.02l.02-.98C12 3.72 10.83 0 9 0c-.58 0-1.17.3-1.56.77-.36.41-.5.91-.42 1.41.25 1.48.28 2.28-.63 3.28-1 1.09-1.48 1.55-2.39 1.55H2C.94 7 0 7.94 0 9v4c0 1.06.94 2 2 2h1.72l1.44.86c.16.09.33.14.52.14h6.33c1.13 0 2.84-.5 3-1.88l.98-5.95c.02-.08.02-.14.02-.2-.03-1.17-.84-1.97-2-1.97H14z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M13.991 13.991c-.05.69-1.269 1-1.998 1H5.665l-1.669-1V7.995c1.36 0 2.11-.75 3.129-1.879 1.229-1.359 1.139-2.558.879-4.127-.08-.5.5-1 1-1 .829 0 1.998 2.729 1.998 3.998l-.02 1.03c0 .689.33.969 1.02.969H14c.63 0 .98.36 1 .999l-1 5.996-.01.01zm0-7.995h-2.018l.02-.98C11.992 3.719 10.822 0 8.993 0c-.58 0-1.169.3-1.559.77-.36.41-.5.909-.42 1.409.25 1.479.28 2.278-.629 3.278-1 1.089-1.48 1.549-2.389 1.549H2c-1.061-.01-2 .929-2 1.988v3.998c0 1.06.94 1.999 1.999 1.999h1.719l1.439.86c.16.089.33.139.52.139h6.325c1.13 0 2.839-.5 2.999-1.879l.979-5.946c.02-.08.02-.14.02-.2-.03-1.17-.84-1.969-1.999-1.969h-.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/unmute.svg b/htdocs/theme/common/octicons/build/svg/unmute.svg
    index 531aafc8b46..19b375fb08c 100644
    --- a/htdocs/theme/common/octicons/build/svg/unmute.svg
    +++ b/htdocs/theme/common/octicons/build/svg/unmute.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M12 7.96c0 1.09-.45 2.09-1.17 2.83l-.67-.67c.55-.56.89-1.31.89-2.16 0-.85-.34-1.61-.89-2.16l.67-.67A3.99 3.99 0 0 1 12 7.96zM7.72 2.22L4 5.94H2c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h2l3.72 3.72c.47.47 1.28.14 1.28-.53V2.75c0-.67-.81-1-1.28-.53zm5.94.08l-.67.67a6.996 6.996 0 0 1 2.06 4.98c0 1.94-.78 3.7-2.06 4.98l.67.67A7.973 7.973 0 0 0 16 7.94c0-2.22-.89-4.22-2.34-5.66v.02zm-1.41 1.41l-.69.67a5.05 5.05 0 0 1 1.48 3.58c0 1.39-.56 2.66-1.48 3.56l.69.67A5.97 5.97 0 0 0 14 7.96c0-1.65-.67-3.16-1.75-4.25z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M12 8.02c0 1.09-.45 2.09-1.17 2.83l-.67-.67c.55-.56.89-1.31.89-2.16 0-.85-.34-1.61-.89-2.16l.67-.67A3.99 3.99 0 0 1 12 8.02zM7.72 2.28L4 6H2c-.55 0-1 .45-1 1v2c0 .55.45 1 1 1h2l3.72 3.72c.47.47 1.28.14 1.28-.53V2.81c0-.67-.81-1-1.28-.53zm5.94.08l-.67.67a6.996 6.996 0 0 1 2.06 4.98c0 1.94-.78 3.7-2.06 4.98l.67.67A7.973 7.973 0 0 0 16 8c0-2.22-.89-4.22-2.34-5.66v.02zm-1.41 1.41l-.69.67a5.05 5.05 0 0 1 1.48 3.58c0 1.39-.56 2.66-1.48 3.56l.69.67A5.971 5.971 0 0 0 14 8.02c0-1.65-.67-3.16-1.75-4.25z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/unverified.svg b/htdocs/theme/common/octicons/build/svg/unverified.svg
    index becff6dfc8f..cf04ce3f81e 100644
    --- a/htdocs/theme/common/octicons/build/svg/unverified.svg
    +++ b/htdocs/theme/common/octicons/build/svg/unverified.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.68 7.07L14.6 5.73c-.17-.22-.28-.48-.31-.77l-.19-1.7a1.51 1.51 0 0 0-1.33-1.33l-1.7-.19c-.3-.03-.56-.16-.78-.33L8.95.33c-.55-.44-1.33-.44-1.88 0L5.73 1.41c-.22.17-.48.28-.77.31l-1.7.19c-.7.08-1.25.63-1.33 1.33l-.19 1.7c-.03.3-.16.56-.33.78L.33 7.06c-.44.55-.44 1.33 0 1.88l1.08 1.34c.17.22.28.48.31.77l.19 1.7c.08.7.63 1.25 1.33 1.33l1.7.19c.3.03.56.16.78.33l1.34 1.08c.55.44 1.33.44 1.88 0l1.34-1.08c.22-.17.48-.28.77-.31l1.7-.19c.7-.08 1.25-.63 1.33-1.33l.19-1.7c.03-.3.16-.56.33-.78l1.08-1.34c.44-.55.44-1.33 0-1.88zm-6.67 4.44c0 .28-.22.5-.5.5h-1c-.27 0-.5-.22-.5-.5v-1c0-.28.23-.5.5-.5h1c.28 0 .5.22.5.5v1zm1.56-4.89c-.06.17-.17.33-.3.47-.13.16-.14.19-.33.38-.16.17-.31.3-.52.45-.11.09-.2.19-.28.27-.08.08-.14.17-.19.27-.05.1-.08.19-.11.3-.03.11-.03.13-.03.25H7.14c0-.22 0-.31.03-.48.03-.19.08-.36.14-.52.06-.14.14-.28.25-.42.11-.13.23-.25.41-.38.27-.19.36-.3.48-.52.12-.22.2-.38.2-.59 0-.27-.06-.45-.2-.58-.13-.13-.31-.19-.58-.19-.09 0-.19.02-.3.05-.11.03-.17.09-.25.16-.08.07-.14.11-.2.2a.41.41 0 0 0-.09.28h-2c0-.38.13-.56.27-.83.16-.27.36-.5.61-.67.25-.17.55-.3.88-.38.33-.08.7-.13 1.09-.13.44 0 .83.05 1.17.13.34.09.63.22.88.39.23.17.41.38.55.63.13.25.19.55.19.88 0 .22 0 .42-.08.59l-.02-.01z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.67 7.066l-1.08-1.34a1.5 1.5 0 0 1-.309-.77l-.19-1.698a1.51 1.51 0 0 0-1.329-1.33l-1.699-.19c-.3-.03-.56-.159-.78-.329L8.945.33a1.504 1.504 0 0 0-1.878 0l-1.34 1.08a1.5 1.5 0 0 1-.77.31l-1.698.19c-.7.08-1.25.63-1.33 1.329l-.19 1.699c-.03.3-.159.56-.329.78L.33 7.055a1.504 1.504 0 0 0 0 1.878l1.08 1.34c.17.22.28.48.31.77l.19 1.698c.08.7.63 1.25 1.329 1.33l1.699.19c.3.03.56.159.78.329l1.339 1.08c.55.439 1.329.439 1.878 0l1.34-1.08c.22-.17.48-.28.77-.31l1.698-.19c.7-.08 1.25-.63 1.33-1.329l.19-1.699c.03-.3.159-.56.329-.78l1.08-1.339a1.504 1.504 0 0 0 0-1.878zm-6.666 4.437c0 .28-.22.5-.5.5h-.999c-.27 0-.5-.22-.5-.5v-1c0-.28.23-.5.5-.5h1c.28 0 .5.22.5.5v1zm1.56-4.887c-.06.17-.17.33-.3.47-.13.16-.14.19-.33.38-.16.17-.31.3-.52.449-.11.09-.2.19-.28.27-.08.08-.14.17-.19.27-.05.1-.08.19-.11.3-.03.11-.03.13-.03.25H7.136c0-.22 0-.31.03-.48.03-.19.08-.36.14-.52.06-.14.14-.28.25-.42.11-.13.23-.25.409-.38.27-.19.36-.3.48-.52.12-.219.2-.379.2-.589 0-.27-.06-.45-.2-.58-.13-.13-.31-.19-.58-.19-.09 0-.19.02-.3.05-.11.03-.17.09-.25.16-.08.07-.14.11-.2.2a.41.41 0 0 0-.09.28H5.028c0-.38.13-.56.27-.83.16-.27.36-.499.61-.669.25-.17.549-.3.879-.38.33-.08.7-.13 1.09-.13.439 0 .829.05 1.168.13.34.09.63.22.88.39.23.17.41.38.55.63.13.25.19.55.19.88 0 .22 0 .419-.08.589l-.02-.01z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/verified.svg b/htdocs/theme/common/octicons/build/svg/verified.svg
    index 8420d2ac554..e1c6c71f72b 100644
    --- a/htdocs/theme/common/octicons/build/svg/verified.svg
    +++ b/htdocs/theme/common/octicons/build/svg/verified.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.68 7.07L14.6 5.73c-.17-.22-.28-.48-.31-.77l-.19-1.7a1.51 1.51 0 0 0-1.33-1.33l-1.7-.19c-.3-.03-.56-.16-.78-.33L8.95.33c-.55-.44-1.33-.44-1.88 0L5.73 1.41c-.22.17-.48.28-.77.31l-1.7.19c-.7.08-1.25.63-1.33 1.33l-.19 1.7c-.03.3-.16.56-.33.78L.33 7.06c-.44.55-.44 1.33 0 1.88l1.08 1.34c.17.22.28.48.31.77l.19 1.7c.08.7.63 1.25 1.33 1.33l1.7.19c.3.03.56.16.78.33l1.34 1.08c.55.44 1.33.44 1.88 0l1.34-1.08c.22-.17.48-.28.77-.31l1.7-.19c.7-.08 1.25-.63 1.33-1.33l.19-1.7c.03-.3.16-.56.33-.78l1.08-1.34c.44-.55.44-1.33 0-1.88zm-9.17 4.94l-3.5-3.5 1.5-1.5 2 2 5-5 1.5 1.55-6.5 6.45z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M15.67 7.066l-1.08-1.34a1.5 1.5 0 0 1-.309-.77l-.19-1.698a1.51 1.51 0 0 0-1.329-1.33l-1.699-.19c-.3-.03-.56-.159-.78-.329L8.945.33a1.504 1.504 0 0 0-1.878 0l-1.34 1.08a1.5 1.5 0 0 1-.77.31l-1.698.19c-.7.08-1.25.63-1.33 1.329l-.19 1.699c-.03.3-.159.56-.329.78L.33 7.055a1.504 1.504 0 0 0 0 1.878l1.08 1.34c.17.22.28.48.31.77l.19 1.698c.08.7.63 1.25 1.329 1.33l1.699.19c.3.03.56.159.78.329l1.339 1.08c.55.439 1.329.439 1.878 0l1.34-1.08c.22-.17.48-.28.77-.31l1.698-.19c.7-.08 1.25-.63 1.33-1.329l.19-1.699c.03-.3.159-.56.329-.78l1.08-1.339a1.504 1.504 0 0 0 0-1.878zm-9.164 4.936L3.008 8.505l1.5-1.5 1.998 2 4.997-4.998 1.499 1.55-6.496 6.445z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/build/svg/x.svg b/htdocs/theme/common/octicons/build/svg/x.svg
    index 3725777be40..e3773142bb9 100644
    --- a/htdocs/theme/common/octicons/build/svg/x.svg
    +++ b/htdocs/theme/common/octicons/build/svg/x.svg
    @@ -1 +1 @@
    -<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M7.71 8.23l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75L1 11.98l3.75-3.75L1 4.48 2.48 3l3.75 3.75L9.98 3l1.48 1.48-3.75 3.75z"/></svg>
    \ No newline at end of file
    +<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 12 16"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z"/></svg>
    \ No newline at end of file
    diff --git a/htdocs/theme/common/octicons/package.json b/htdocs/theme/common/octicons/package.json
    index 77188450670..4d8ea495b08 100644
    --- a/htdocs/theme/common/octicons/package.json
    +++ b/htdocs/theme/common/octicons/package.json
    @@ -1,6 +1,6 @@
     {
    -  "version": "7.2.0",
       "name": "octicons",
    +  "version": "8.1.0",
       "description": "A scalable set of icons handcrafted with <3 by GitHub.",
       "homepage": "https://octicons.github.com",
       "author": "GitHub Inc.",
    diff --git a/htdocs/theme/eldy/ckeditor/config.js b/htdocs/theme/eldy/ckeditor/config.js
    index bc560d38f8f..50ff0cc6eed 100644
    --- a/htdocs/theme/eldy/ckeditor/config.js
    +++ b/htdocs/theme/eldy/ckeditor/config.js
    @@ -18,7 +18,7 @@ CKEDITOR.editorConfig = function( config )
     	//config.extraPlugins = 'docprops,scayt,showprotected';
     	config.removeDialogTabs = 'flash:advanced';	// config.removeDialogTabs = 'flash:advanced;image:Link';
     	config.protectedSource.push( /<\?[\s\S]*?\?>/g );   // Prevent PHP Code to be formatted
    -	//config.menu_groups = 'clipboard,table,anchor,link,image';	// for context menu 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea' 
    +	//config.menu_groups = 'clipboard,table,anchor,link,image';	// for context menu 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea'
     	//config.language = 'de';
     	//config.defaultLanguage = 'en';
     	//config.contentsLanguage = 'fr';
    @@ -29,7 +29,7 @@ CKEDITOR.editorConfig = function( config )
     	//config.autoParagraph = false;
     	//config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd';		// See also rules on this.dataProcessor.writer.setRules
     	//config.forcePasteAsPlainText = true;
    -	
    +
     	config.toolbar_Full =
     	[
     	    ['Templates','NewPage'],
    @@ -51,7 +51,7 @@ CKEDITOR.editorConfig = function( config )
     	];
     
     	// Used for mailing fields
    -	config.toolbar_dolibarr_mailings = 
    +	config.toolbar_dolibarr_mailings =
     	[
     	 	['Maximize','Preview'],
     	 	['SpellChecker', 'Scayt'],
    @@ -64,7 +64,7 @@ CKEDITOR.editorConfig = function( config )
     	 	['Link','Unlink','Anchor','Image','Table','HorizontalRule','SpecialChar'],
     	 	['Source']
     	 ];
    -	
    +
     	// Used for notes fields
     	config.toolbar_dolibarr_notes =
     	[
    @@ -78,7 +78,7 @@ CKEDITOR.editorConfig = function( config )
     	    ['Link','Unlink','Image','Table','HorizontalRule','SpecialChar'],
     	 	['Source']
     	];
    -	
    +
     	// Used for details lines
     	config.toolbar_dolibarr_details =
     	[
    @@ -91,12 +91,12 @@ CKEDITOR.editorConfig = function( config )
     	    ['Link','Unlink','SpecialChar'],
     	 	['Source']
     	];
    -	
    +
     	// Used for mailing fields
     	config.toolbar_dolibarr_readonly =
     	[
     	 	['Maximize'],
     	 	['Find'],
     	 	['Source']
    -	];	
    +	];
     };
    diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
    index cc1da092523..9eba59317bc 100644
    --- a/htdocs/theme/eldy/style.css.php
    +++ b/htdocs/theme/eldy/style.css.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2007-2017	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2011		Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2012		Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
      *
      * 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
    @@ -53,7 +54,7 @@ $colortexttitlenotab='100,60,20';
     $colortexttitle='0,0,0';
     $colortext='0,0,0';
     $colortextlink='0,0,100';
    -$fontsize='0.85em';
    +$fontsize='0.86em';
     $fontsizesmaller='0.75em';
     
     if (defined('THEME_ONLY_CONSTANT')) return;
    @@ -107,6 +108,7 @@ if (! isset($conf->global->THEME_ELDY_TOPMENU_BACK1)) $conf->global->THEME_ELDY_
     if (! isset($conf->global->THEME_ELDY_VERMENU_BACK1)) $conf->global->THEME_ELDY_VERMENU_BACK1=$colorbackvmenu1;
     if (! isset($conf->global->THEME_ELDY_BACKTITLE1)) $conf->global->THEME_ELDY_BACKTITLE1=$colorbacktitle1;
     if (! isset($conf->global->THEME_ELDY_USE_HOVER)) $conf->global->THEME_ELDY_USE_HOVER=$colorbacklinepairhover;
    +if (! isset($conf->global->THEME_ELDY_USE_CHECKED)) $conf->global->THEME_ELDY_USE_CHECKED=$colorbacklinepairchecked;
     if (! isset($conf->global->THEME_ELDY_LINEBREAK)) $conf->global->THEME_ELDY_LINEBREAK=$colorbacklinebreak;
     if (! isset($conf->global->THEME_ELDY_TEXTTITLENOTAB)) $conf->global->THEME_ELDY_TEXTTITLENOTAB=$colortexttitlenotab;
     if (! isset($conf->global->THEME_ELDY_TEXTLINK)) $conf->global->THEME_ELDY_TEXTLINK=$colortextlink;
    @@ -143,9 +145,11 @@ $fontsizesmaller     =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty(
     
     // Hover color
     $colorbacklinepairhover=((! isset($conf->global->THEME_ELDY_USE_HOVER) || (string) $conf->global->THEME_ELDY_USE_HOVER === '0')?'':($conf->global->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$conf->global->THEME_ELDY_USE_HOVER));
    +$colorbacklinepairchecked=((! isset($conf->global->THEME_ELDY_USE_CHECKED) || (string) $conf->global->THEME_ELDY_USE_CHECKED === '0')?'':($conf->global->THEME_ELDY_USE_CHECKED === '1'?'edf4fb':$conf->global->THEME_ELDY_USE_CHECKED));
     if (! empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED))
     {
     	$colorbacklinepairhover=((! isset($user->conf->THEME_ELDY_USE_HOVER) || $user->conf->THEME_ELDY_USE_HOVER === '0')?'':($user->conf->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$user->conf->THEME_ELDY_USE_HOVER));
    +	$colorbacklinepairchecked=((! isset($user->conf->THEME_ELDY_USE_CHECKED) || $user->conf->THEME_ELDY_USE_CHECKED === '0')?'':($user->conf->THEME_ELDY_USE_CHECKED === '1'?'edf4fb':$user->conf->THEME_ELDY_USE_CHECKED));
     }
     
     //$colortopbordertitle1=$colorbackhmenu1;
    @@ -177,7 +181,7 @@ $colorbacktabcard1=join(',',colorStringToArray($colorbacktabcard1));    // Norma
     $tmppart=explode(',',$colorbacktabcard1);
     $tmpval=(! empty($tmppart[0]) ? $tmppart[0] : 0)+(! empty($tmppart[1]) ? $tmppart[1] : 0)+(! empty($tmppart[2]) ? $tmppart[2] : 0);
     if ($tmpval <= 460) { $colortextbacktab='FFFFFF'; }
    -else { $colortextbacktab='111111'; }
    +else { $colortextbacktab='000000'; }
     
     
     // Format color value to match expected format (may be 'FFFFFF' or '255,255,255')
    @@ -191,6 +195,7 @@ $colorbacklineimpair2=join(',',colorStringToArray($colorbacklineimpair2));
     $colorbacklinepair1=join(',',colorStringToArray($colorbacklinepair1));
     $colorbacklinepair2=join(',',colorStringToArray($colorbacklinepair2));
     if ($colorbacklinepairhover != '') $colorbacklinepairhover=join(',',colorStringToArray($colorbacklinepairhover));
    +if ($colorbacklinepairchecked != '') $colorbacklinepairchecked=join(',',colorStringToArray($colorbacklinepairchecked));
     $colorbackbody=join(',',colorStringToArray($colorbackbody));
     $colortexttitlenotab=join(',',colorStringToArray($colortexttitlenotab));
     $colortexttitle=join(',',colorStringToArray($colortexttitle));
    @@ -218,6 +223,7 @@ print 'colorbacklineimpair2='.$colorbacklineimpair2."\n";
     print 'colorbacklinepair1='.$colorbacklinepair1."\n";
     print 'colorbacklinepair2='.$colorbacklinepair2."\n";
     print 'colorbacklinepairhover='.$colorbacklinepairhover."\n";
    +print 'colorbacklinepairchecked='.$colorbacklinepairchecked."\n";
     print '$colortexttitlenotab='.$colortexttitlenotab."\n";
     print '$colortexttitle='.$colortexttitle."\n";
     print '$colortext='.$colortext."\n";
    @@ -258,7 +264,7 @@ body {
         <?php print 'direction: '.$langs->trans("DIRECTION").";\n"; ?>
     }
     
    -.thumbstat, a.tab { font-weight: bold !important; }
    +.thumbstat { font-weight: bold !important; }
     th a { font-weight: <?php echo ($useboldtitle?'bold':'normal'); ?> !important; }
     a.tab { font-weight: bold !important; }
     
    @@ -491,6 +497,7 @@ input#onlinepaymenturl, input#directdownloadlink {
     }
     
     hr { border: 0; border-top: 1px solid #ccc; }
    +.tabBar hr { margin-top: 20px; margin-bottom: 17px; }
     
     .button, .buttonDelete, input[name="sbmtConnexion"] {
     	margin-bottom: 0;
    @@ -546,7 +553,7 @@ form {
         margin:0px;
     }
     form#addproduct {
    -    padding-top: 6px;
    +    padding-top: 10px;
     }
     div.float
     {
    @@ -689,6 +696,9 @@ textarea.centpercent {
     	height: 28px;
     	vertical-align: middle;
     }
    +.divsocialnetwork:not(:first-child) {
    +    padding-left: 20px;
    +}
     div.divsearchfield {
     	float: <?php print $left; ?>;
     	margin-<?php print $right; ?>: 12px;
    @@ -748,6 +758,9 @@ select.flat.selectlimit {
     .marginleftonly {
     	margin-left: 10px !important;
     }
    +.marginleftonlyshort {
    +	margin-left: 4px !important;
    +}
     .nomarginleft {
     	margin-left: 0px !important;
     }
    @@ -1159,8 +1172,8 @@ td.showDragHandle {
     	table-layout: fixed;
     }
     #id-right, #id-left {
    -	padding-top: 16px;
    -	padding-bottom: 16px;
    +	padding-top: 20px;
    +	padding-bottom: 20px;
     
     	display: table-cell;			/* DOL_XXX Empeche fonctionnement correct du scroll horizontal sur tableau, avec datatable ou CSS */
     	float: none;
    @@ -1265,8 +1278,8 @@ div.fiche {
     
     
     div.fiche {
    -	margin-<?php print $left; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?6:(empty($conf->dol_optimize_smallscreen)?'25':'6')); ?>px;
    -	margin-<?php print $right; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?6:(empty($conf->dol_optimize_smallscreen)?'24':'6')); ?>px;
    +	margin-<?php print $left; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?6:(empty($conf->dol_optimize_smallscreen)?'30':'6')); ?>px;
    +	margin-<?php print $right; ?>: <?php print (GETPOST('optioncss','aZ09') == 'print'?6:(empty($conf->dol_optimize_smallscreen)?'29':'6')); ?>px;
     	<?php if (! empty($dol_hide_leftmenu)) print 'margin-bottom: 12px;'."\n"; ?>
     	<?php if (! empty($dol_hide_leftmenu)) print 'margin-top: 12px;'."\n"; ?>
     }
    @@ -1664,6 +1677,9 @@ div.mainmenu.menu {
     #mainmenutd_menu a.tmenuimage {
         display: unset;
     }
    +a.tmenuimage {
    +    display: block;
    +}
     
     /* Do not load menu img for other if hidden to save bandwidth */
     
    @@ -1694,6 +1710,10 @@ div.mainmenu.cashdesk {
     	background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/pointofsale_over.png',1) ?>);
     }
     
    +div.mainmenu.takepos {
    +	background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/pointofsale_over.png',1) ?>);
    +}
    +
     div.mainmenu.companies {
     	background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/company_over.png',1) ?>);
     }
    @@ -1763,7 +1783,7 @@ $mainmenuusedarray=array_unique(explode(',',$mainmenuused));
     
     $generic=1;
     // Put here list of menu entries when the div.mainmenu.menuentry was previously defined
    -$divalreadydefined=array('home','companies','products','commercial','externalsite','accountancy','project','tools','members','agenda','ftp','holiday','hrm','bookmark','cashdesk','ecm','geoipmaxmind','gravatar','clicktodial','paypal','stripe','webservices','website');
    +$divalreadydefined=array('home','companies','products','commercial','externalsite','accountancy','project','tools','members','agenda','ftp','holiday','hrm','bookmark','cashdesk','takepos','ecm','geoipmaxmind','gravatar','clicktodial','paypal','stripe','webservices','website');
     // Put here list of menu entries we are sure we don't want
     $divnotrequired=array('multicurrency','salaries','ticket','margin','opensurvey','paybox','expensereport','incoterm','prelevement','propal','workflow','notification','supplier_proposal','cron','product','productbatch','expedition');
     foreach($mainmenuusedarray as $val)
    @@ -1824,6 +1844,7 @@ foreach($mainmenuusedarray as $val)
         position: absolute;
         height: 100%;
         width: 100%;
    +    font-size: 1em;
     }
     .login_center {
     	display: table-cell;
    @@ -1835,13 +1856,14 @@ foreach($mainmenuusedarray as $val)
     }
     form#login {
     	padding-bottom: 30px;
    -	font-size: 13px;
    +	font-size: 14px;
     	vertical-align: middle;
     }
     .login_table_title {
     	max-width: 530px;
    -	color: #aaa !important;
    +	color: #eee !important;
     	padding-bottom: 20px;
    +	text-shadow: 1px 1px #444;
     }
     .login_table label {
     	text-shadow: 1px 1px 1px #FFF;
    @@ -1876,12 +1898,30 @@ if (! empty($conf->global->MAIN_LOGIN_BACKGROUND)) {
     	padding: 5px;
     	margin-left: 5px;
     	margin-top: 5px;
    +	margin-bottom: 5px;
     }
     .login_table input#username:focus, .login_table input#password:focus, .login_table input#securitycode:focus {
     	outline: none !important;
    -	/* box-shadow: none;
    -	-webkit-box-shadow: 0 0 0 50px #FFF inset;
    -	box-shadow: 0 0 0 50px #FFF inset;*/
    +}
    +.login_table .trinputlogin {
    +	font-size: 1.2em;
    +	margin: 8px;
    +}
    +.login_table .tdinputlogin {
    +    background-color: transparent;
    +    /* border: 2px solid #ccc; */
    +    min-width: 220px;
    +    border-radius: 2px;
    +}
    +.login_table .tdinputlogin .fa {
    +	padding-left: 10px;
    +	width: 14px;
    +}
    +.login_table .tdinputlogin input#username, .login_table .tdinputlogin input#password {
    +	font-size: 1em;
    +}
    +.login_table .tdinputlogin input#securitycode {
    +	font-size: 1em;
     }
     .login_main_message {
     	text-align: center;
    @@ -2302,6 +2342,7 @@ div.tabBar table.tableforservicepart2:last-child {
     }
     .tableforservicepart1 .tdhrthin {
     	height: unset;
    +    padding-top: 0 !important;
     }
     
     div.popuptabset {
    @@ -2316,7 +2357,7 @@ div.popuptab {
     	padding-right: 5px;
     }
     div.tabsAction {
    -    margin: 20px 0em 20px 0em;
    +    margin: 20px 0em 30px 0em;
         padding: 0em 0em;
         text-align: right;
     }
    @@ -2343,7 +2384,7 @@ a.tabunactive {
     }
     a.tab:link, a.tab:visited, a.tab:hover, a.tab#active {
     	font-family: <?php print $fontlist ?>;
    -	padding: 12px 9px 13px;
    +	padding: 12px 14px 13px;
         margin: 0em 0.2em;
         text-decoration: none;
         white-space: nowrap;
    @@ -2457,21 +2498,24 @@ span.butAction, span.butActionDelete {
         cursor: pointer;
         /*color: #fff !important;
         background: rgb(<?php echo $colorbackhmenu1 ?>);
    -    border: 1px solid rgb(<?php echo $colorbackhmenu1 ?>);*/
    +    border: 1px solid rgb(<?php echo $colorbackhmenu1 ?>);
         border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
    -
         border-top-right-radius: 0 !important;
         border-bottom-right-radius: 0 !important;
         border-top-left-radius: 0 !important;
    -    border-bottom-left-radius: 0 !important;
    +    border-bottom-left-radius: 0 !important;*/
     }
     a.butActionNew>span.fa-plus-circle, a.butActionNew>span.fa-plus-circle:hover { padding-left: 6px; font-size: 1.5em; border: none; box-shadow: none; webkit-box-shadow: none; }
     a.butActionNewRefused>span.fa-plus-circle, a.butActionNewRefused>span.fa-plus-circle:hover { padding-left: 6px; font-size: 1.5em; border: none; box-shadow: none; webkit-box-shadow: none; }
     
    -.butAction:hover, .butActionNew:hover   {
    +.butAction:hover   {
       -webkit-box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1);
       box-shadow: 0px 0px 6px 1px rgba(50, 50, 50, 0.4), 0px 0px 0px rgba(60,60,60,0.1);
     }
    +.butActionNew:hover   {
    +  text-decoration: underline;
    +  box-shadow: unset !important;
    +}
     
     .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active, .buttonDelete {
         background: rgb(239, 232, 230);
    @@ -2692,7 +2736,9 @@ table.paddingtopbottomonly tr td {
     	background: rgb(<?php echo $colorbacktitle1; ?>) !important;
     }
     tr.liste_titre_filter td.liste_titre {
    -/*    border-bottom: 1px solid #ddd; */
    +	/* border-bottom: 1px solid #ddd; */
    +	padding-top: 1px;
    +	padding-bottom: 0px;
     }
     .liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd
     {
    @@ -2928,9 +2974,20 @@ div.pagination li.paginationafterarrows {
     	background: rgb(<?php echo $colorbacklinepairhover; ?>) !important;		/* Must be background to be stronger than background of odd or even */
     <?php } ?>
     }
    +<?php if ($colorbacklinepairchecked) { ?>
    +.highlight {
    +	background: rgb(<?php echo $colorbacklinepairchecked; ?>) !important; /* Must be background to be stronger than background of odd or even */
    +}
    +<?php } ?>
    +
     .nohover:hover {
     	background: unset;
     }
    +.nohoverborder:hover {
    +	border: unset;
    +	box-shadow: unset;
    +	-webkit-box-shadow: unset;
    +}
     .oddeven, .evenodd, .impair, .nohover .impair:hover, tr.impair td.nohover
     {
     	font-family: <?php print $fontlist ?>;
    @@ -3200,8 +3257,9 @@ ul.noborder li:nth-child(even):not(.liste_titre) {
         margin-bottom: 5px;
         text-align: center;
     
    -    background: #f8f8f8;
    +    background: #fcfcfc;
         border: 1px solid #eee;
    +    /* border-left: 6px solid #ddd; */
         box-shadow: 1px 1px 8px #ddd;
         border-radius: 0px;
     }
    @@ -3213,7 +3271,7 @@ ul.noborder li:nth-child(even):not(.liste_titre) {
     .boxstats130 {
         width: 158px;
         height: 48px;
    -    padding: 3px
    +    padding: 3px;
     }
     .boxstats {
         padding: 3px;
    @@ -3249,9 +3307,11 @@ ul.noborder li:nth-child(even):not(.liste_titre) {
         }
     	.thumbstat {
     		flex: 1 1 110px;
    +		margin-bottom: 8px;
     	}
     	.thumbstat150 {
     		flex: 1 1 110px;
    +		margin-bottom: 8px;
     	}
         .dashboardlineindicator {
             float: left;
    @@ -3445,7 +3505,7 @@ div.warning {
         background: #fcf8e3;
     }
     div.warning a, div.info a, div.error a {
    -	color: rgb(<?php echo $colortext; ?>);
    +	color: rgb(<?php echo $colortextlink; ?>);
     }
     
     /* Error message */
    @@ -3867,6 +3927,13 @@ span.websitebuttonsitepreviewdisabled img, a.websitebuttonsitepreviewdisabled im
         float: right;
         padding-top: 8px;
     }
    +.websiteselectionsection {
    +	border-left: 1px solid #bbb;
    +	border-right: 1px solid #bbb;
    +	margin-left: 0px;
    +	padding-left: 8px;
    +	margin-right: 5px;
    +}
     
     
     /* ============================================================================== */
    @@ -4372,7 +4439,7 @@ td.gminorheading {
     .ecmfiletree {
     	width: 99%;
     	height: 99%;
    -	background: #FFF;
    +	/* background: #FFF; */
     	padding-left: 2px;
     	font-weight: normal;
     }
    @@ -4869,7 +4936,81 @@ span.noborderoncategories {
     
     
     /* ============================================================================== */
    -/*  Multiselect with checkbox                                                     */
    +/*  External lib multiselect with checkbox                                        */
    +/* ============================================================================== */
    +
    +.multi-select-container {
    +  display: inline-block;
    +  position: relative;
    +}
    +
    +.multi-select-menu {
    +  position: absolute;
    +  left: 0;
    +  top: 0.8em;
    +  float: left;
    +  min-width: 100%;
    +  background: #fff;
    +  margin: 1em 0;
    +  padding: 0.4em 0;
    +  border: 1px solid #aaa;
    +  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    +  display: none;
    +}
    +
    +.multi-select-menu input {
    +  margin-right: 0.3em;
    +  vertical-align: 0.1em;
    +}
    +
    +.multi-select-button {
    +  display: inline-block;
    +  max-width: 20em;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-overflow: ellipsis;
    +  vertical-align: middle;
    +  background-color: #fff;
    +  cursor: default;
    +
    +  border: none;
    +  border-bottom: solid 1px rgba(0,0,0,.2);
    +  padding: 5px;
    +  padding-left: 2px;
    +  height: 17px;
    +}
    +.multi-select-button:focus {
    +  outline: none;
    +  border-bottom: 1px solid #666;
    +}
    +
    +.multi-select-button:after {
    +  content: "";
    +  display: inline-block;
    +  width: 0;
    +  height: 0;
    +  border-style: solid;
    +  border-width: 0.5em 0.23em 0em 0.23em;
    +  border-color: #444 transparent transparent transparent;
    +  margin-left: 0.4em;
    +}
    +
    +.multi-select-container--open .multi-select-menu { display: block; }
    +
    +.multi-select-container--open .multi-select-button:after {
    +  border-width: 0 0.4em 0.4em 0.4em;
    +  border-color: transparent transparent #999 transparent;
    +}
    +
    +.multi-select-menuitem {
    +    clear: both;
    +    float: left;
    +    padding-left: 5px
    +}
    +
    +
    +/* ============================================================================== */
    +/*  Native multiselect with checkbox                                              */
     /* ============================================================================== */
     
     ul.ulselectedfields {
    @@ -4909,10 +5050,10 @@ dl.dropdown {
     }
     .dropdown dd ul {
         background-color: #FFF;
    -    border: 1px solid #888;
    +    box-shadow: 1px 1px 10px #aaa;
         display:none;
         <?php echo $right; ?>:0px;						/* pop is align on right */
    -    padding: 2px 15px 2px 5px;
    +    padding: 0 0 0 0;
         position:absolute;
         top:2px;
         list-style:none;
    @@ -4922,10 +5063,13 @@ dl.dropdown {
     .dropdown dd ul li {
     	white-space: nowrap;
     	font-weight: normal;
    -	padding: 2px;
    +	padding: 7px 8px 7px 8px;
     	/* color: rgb(<?php print $colortext; ?>); */
     	color: #000;
     }
    +.dropdown dd ul li:hover {
    +	background: #eee;
    +}
     .dropdown dd ul li input[type="checkbox"] {
         margin-<?php echo $right; ?>: 3px;
     }
    @@ -4937,7 +5081,7 @@ dl.dropdown {
     	color: #888;
     }
     .dropdown dd ul li a:hover {
    -    background-color:#fff;
    +    background-color:#eee;
     }
     
     
    diff --git a/htdocs/theme/md/ckeditor/config.js b/htdocs/theme/md/ckeditor/config.js
    index bc560d38f8f..50ff0cc6eed 100644
    --- a/htdocs/theme/md/ckeditor/config.js
    +++ b/htdocs/theme/md/ckeditor/config.js
    @@ -18,7 +18,7 @@ CKEDITOR.editorConfig = function( config )
     	//config.extraPlugins = 'docprops,scayt,showprotected';
     	config.removeDialogTabs = 'flash:advanced';	// config.removeDialogTabs = 'flash:advanced;image:Link';
     	config.protectedSource.push( /<\?[\s\S]*?\?>/g );   // Prevent PHP Code to be formatted
    -	//config.menu_groups = 'clipboard,table,anchor,link,image';	// for context menu 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea' 
    +	//config.menu_groups = 'clipboard,table,anchor,link,image';	// for context menu 'clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea'
     	//config.language = 'de';
     	//config.defaultLanguage = 'en';
     	//config.contentsLanguage = 'fr';
    @@ -29,7 +29,7 @@ CKEDITOR.editorConfig = function( config )
     	//config.autoParagraph = false;
     	//config.removeFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd';		// See also rules on this.dataProcessor.writer.setRules
     	//config.forcePasteAsPlainText = true;
    -	
    +
     	config.toolbar_Full =
     	[
     	    ['Templates','NewPage'],
    @@ -51,7 +51,7 @@ CKEDITOR.editorConfig = function( config )
     	];
     
     	// Used for mailing fields
    -	config.toolbar_dolibarr_mailings = 
    +	config.toolbar_dolibarr_mailings =
     	[
     	 	['Maximize','Preview'],
     	 	['SpellChecker', 'Scayt'],
    @@ -64,7 +64,7 @@ CKEDITOR.editorConfig = function( config )
     	 	['Link','Unlink','Anchor','Image','Table','HorizontalRule','SpecialChar'],
     	 	['Source']
     	 ];
    -	
    +
     	// Used for notes fields
     	config.toolbar_dolibarr_notes =
     	[
    @@ -78,7 +78,7 @@ CKEDITOR.editorConfig = function( config )
     	    ['Link','Unlink','Image','Table','HorizontalRule','SpecialChar'],
     	 	['Source']
     	];
    -	
    +
     	// Used for details lines
     	config.toolbar_dolibarr_details =
     	[
    @@ -91,12 +91,12 @@ CKEDITOR.editorConfig = function( config )
     	    ['Link','Unlink','SpecialChar'],
     	 	['Source']
     	];
    -	
    +
     	// Used for mailing fields
     	config.toolbar_dolibarr_readonly =
     	[
     	 	['Maximize'],
     	 	['Find'],
     	 	['Source']
    -	];	
    +	];
     };
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index 87b41358fa5..80a79b0245a 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -5,6 +5,7 @@
      * Copyright (C) 2011		Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2012		Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2015		Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
      *
      * 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
    @@ -54,7 +55,7 @@ $colortexttitlenotab='90,90,90';
     $colortexttitle='20,20,20';
     $colortext='0,0,0';
     $colortextlink='0,0,120';
    -$fontsize='13';
    +$fontsize='14';
     $fontsizesmaller='11';
     
     if (defined('THEME_ONLY_CONSTANT')) return;
    @@ -99,7 +100,7 @@ $dol_no_mouse_hover=$conf->dol_no_mouse_hover;
     //$user->conf->THEME_ELDY_ENABLE_PERSONALIZED=0;
     //var_dump($user->conf->THEME_ELDY_RGB);
     
    -$useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:1);
    +$useboldtitle=(isset($conf->global->THEME_ELDY_USEBOLDTITLE)?$conf->global->THEME_ELDY_USEBOLDTITLE:0);
     $borderwidth=2;
     
     // Case of option always editable
    @@ -108,6 +109,7 @@ if (! isset($conf->global->THEME_ELDY_TOPMENU_BACK1)) $conf->global->THEME_ELDY_
     if (! isset($conf->global->THEME_ELDY_VERMENU_BACK1)) $conf->global->THEME_ELDY_VERMENU_BACK1=$colorbackvmenu1;
     if (! isset($conf->global->THEME_ELDY_BACKTITLE1)) $conf->global->THEME_ELDY_BACKTITLE1=$colorbacktitle1;
     if (! isset($conf->global->THEME_ELDY_USE_HOVER)) $conf->global->THEME_ELDY_USE_HOVER==$colorbacklinepairhover;
    +if (! isset($conf->global->THEME_ELDY_USE_CHECKED)) $conf->global->THEME_ELDY_USE_CHECKED=$colorbacklinepairchecked;
     if (! isset($conf->global->THEME_ELDY_LINEBREAK)) $conf->global->THEME_ELDY_LINEBREAK=$colorbacklinebreak;
     if (! isset($conf->global->THEME_ELDY_TEXTTITLENOTAB)) $conf->global->THEME_ELDY_TEXTTITLENOTAB=$colortexttitlenotab;
     if (! isset($conf->global->THEME_ELDY_TEXTLINK)) $conf->global->THEME_ELDY_TEXTLINK=$colortextlink;
    @@ -119,7 +121,7 @@ if (empty($conf->global->THEME_ELDY_ENABLE_PERSONALIZED))
         $conf->global->THEME_ELDY_BACKTABCARD1='255,255,255';     // card
         $conf->global->THEME_ELDY_BACKTABACTIVE='234,234,234';
         $conf->global->THEME_ELDY_TEXT='0,0,0';
    -    $conf->global->THEME_ELDY_FONT_SIZE1='13';
    +    $conf->global->THEME_ELDY_FONT_SIZE1='14';
         $conf->global->THEME_ELDY_FONT_SIZE2='11';
     }
     
    @@ -145,9 +147,11 @@ $fontsizesmaller     =empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED)?(empty(
     
     // Hover color
     $colorbacklinepairhover=((! isset($conf->global->THEME_ELDY_USE_HOVER) || (string) $conf->global->THEME_ELDY_USE_HOVER === '0')?'':($conf->global->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$conf->global->THEME_ELDY_USE_HOVER));
    +$colorbacklinepairchecked=((! isset($conf->global->THEME_ELDY_USE_CHECKED) || (string) $conf->global->THEME_ELDY_USE_CHECKED === '0')?'':($conf->global->THEME_ELDY_USE_CHECKED === '1'?'edf4fb':$conf->global->THEME_ELDY_USE_CHECKED));
     if (! empty($user->conf->THEME_ELDY_ENABLE_PERSONALIZED))
     {
         $colorbacklinepairhover=((! isset($user->conf->THEME_ELDY_USE_HOVER) || $user->conf->THEME_ELDY_USE_HOVER === '0')?'':($user->conf->THEME_ELDY_USE_HOVER === '1'?'edf4fb':$user->conf->THEME_ELDY_USE_HOVER));
    +    $colorbacklinepairchecked=((! isset($user->conf->THEME_ELDY_USE_CHECKED) || $user->conf->THEME_ELDY_USE_CHECKED === '0')?'':($user->conf->THEME_ELDY_USE_CHECKED === '1'?'edf4fb':$user->conf->THEME_ELDY_USE_CHECKED));
     }
     
     if (empty($colortopbordertitle1)) $colortopbordertitle1=$colorbackhmenu1;
    @@ -193,6 +197,7 @@ $colorbacklineimpair2=join(',',colorStringToArray($colorbacklineimpair2));
     $colorbacklinepair1=join(',',colorStringToArray($colorbacklinepair1));
     $colorbacklinepair2=join(',',colorStringToArray($colorbacklinepair2));
     if ($colorbacklinepairhover != '') $colorbacklinepairhover=join(',',colorStringToArray($colorbacklinepairhover));
    +if ($colorbacklinepairchecked != '') $colorbacklinepairchecked=join(',',colorStringToArray($colorbacklinepairchecked));
     $colorbackbody=join(',',colorStringToArray($colorbackbody));
     $colortexttitlenotab=join(',',colorStringToArray($colortexttitlenotab));
     $colortexttitle=join(',',colorStringToArray($colortexttitle));
    @@ -211,6 +216,7 @@ print 'colorbacklineimpair2='.$colorbacklineimpair2."\n";
     print 'colorbacklinepair1='.$colorbacklinepair1."\n";
     print 'colorbacklinepair2='.$colorbacklinepair2."\n";
     print 'colorbacklinepairhover='.$colorbacklinepairhover."\n";
    +print 'colorbacklinepairchecked='.$colorbacklinepairchecked."\n";
     print '$colortexttitlenotab='.$colortexttitlenotab."\n";
     print '$colortexttitle='.$colortexttitle."\n";
     print '$colortext='.$colortext."\n";
    @@ -251,7 +257,8 @@ body {
         <?php print 'direction: '.$langs->trans("DIRECTION").";\n"; ?>
     }
     
    -th a, .thumbstat, a.tab { font-weight: bold !important; }
    +.thumbstat { font-weight: bold !important; }
    +th a { font-weight: <?php echo ($useboldtitle?'bold':'normal'); ?> !important; }
     a.tab { font-weight: bold !important; }
     
     a:link, a:visited, a:hover, a:active { font-family: <?php print $fontlist ?>; font-weight: normal; color: rgb(<?php print $colortextlink; ?>); text-decoration: none;  }
    @@ -682,6 +689,9 @@ textarea.centpercent {
     	height: 28px;
     	vertical-align: middle;
     }
    +.divsocialnetwork:not(:first-child) {
    +    padding-left: 20px;
    +}
     div.divsearchfield {
     	float: <?php print $left; ?>;
     	margin-<?php print $right; ?>: 12px;
    @@ -735,6 +745,9 @@ select.flat.selectlimit {
     .marginleftonly {
     	margin-left: 10px !important;
     }
    +.marginleftonlyshort {
    +	margin-left: 4px !important;
    +}
     .nomarginleft {
     	margin-left: 0px !important;
     }
    @@ -1192,6 +1205,13 @@ td.showDragHandle {
     .side-nav-vert {
     	margin-left: 228px;
     }
    +<?php if (empty($conf->global->THEME_DISABLE_STICKY_TOPMENU)) {  ?>
    +.side-nav-vert {
    +	position: sticky;
    +	top: 0px;
    +	z-index: 210;
    +}
    +<?php } ?>
     
     /* For smartphone (testmenuhider is on) */
     <?php if (in_array($conf->browser->layout, array('phone','tablet')) && ((GETPOST('testmenuhider') || ! empty($conf->global->MAIN_TESTMENUHIDER)) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))) { ?>
    @@ -1223,6 +1243,11 @@ div.backgroundsemitransparent {
     	padding-left: 10px;
     	padding-right: 10px;
     }
    +
    +
    +
    +/* Login */
    +
     div.login_block {
     	/* position: initial !important;*/
     	display: none;
    @@ -1237,6 +1262,10 @@ div.login_block {
     	color: #333 !important;
     	font-weight: normal !important;
     }
    +
    +
    +
    +
     #id-right {
     	padding-left: 0 ! important;
     }
    @@ -1687,6 +1716,10 @@ div.mainmenu.cashdesk {
     	background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/pointofsale.png',1) ?>);
     }
     
    +div.mainmenu.takepos {
    +	background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/pointofsale.png',1) ?>);
    +}
    +
     div.mainmenu.companies {
     	background-image: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/menus/company.png',1) ?>);
     }
    @@ -1760,7 +1793,7 @@ $mainmenuusedarray=array_unique(explode(',',$mainmenuused));
     
     $generic=1;
     // Put here list of menu entries when the div.mainmenu.menuentry was previously defined
    -$divalreadydefined=array('home','companies','products','commercial','externalsite','accountancy','project','tools','members','agenda','ftp','holiday','hrm','bookmark','cashdesk','ecm','geoipmaxmind','gravatar','clicktodial','paypal','stripe','webservices','website');
    +$divalreadydefined=array('home','companies','products','commercial','externalsite','accountancy','project','tools','members','agenda','ftp','holiday','hrm','bookmark','cashdesk','takepos','ecm','geoipmaxmind','gravatar','clicktodial','paypal','stripe','webservices','website');
     // Put here list of menu entries we are sure we don't want
     $divnotrequired=array('multicurrency','salaries','ticket','margin','opensurvey','paybox','expensereport','incoterm','prelevement','propal','workflow','notification','supplier_proposal','cron','product','productbatch','expedition');
     foreach($mainmenuusedarray as $val)
    @@ -1809,7 +1842,9 @@ foreach($mainmenuusedarray as $val)
         	display: none;
         <?php } ?>
     }
    -
    +a.tmenuimage {
    +    display: block;
    +}
     
     
     /* Login */
    @@ -1832,7 +1867,7 @@ foreach($mainmenuusedarray as $val)
     }
     form#login {
     	padding-bottom: 30px;
    -	font-size: 13px;
    +	font-size: 14px;
     	vertical-align: middle;
     }
     .login_table_title {
    @@ -1864,17 +1899,29 @@ form#login {
     }
     .login_table input#username, .login_table input#password, .login_table input#securitycode{
     	border: none;
    -	border-bottom: solid 1px rgba(180,180,180,.4);
    +	/* border-bottom: solid 1px rgba(180,180,180,.4); */
     	padding: 5px;
     	margin-left: 18px;
     	margin-top: 5px;
    +	margin-bottom: 5px;
     }
     .login_table input#username:focus, .login_table input#password:focus, .login_table input#securitycode:focus {
     	outline: none !important;
    -	/* box-shadow: none;
    -	-webkit-box-shadow: 0 0 0 50px #FFF inset;
    -	box-shadow: 0 0 0 50px #FFF inset;*/
     }
    +.login_table .trinputlogin {
    +	margin: 8px;
    +}
    +.login_table .tdinputlogin {
    +    background-color: #fff;
    +    border: 2px solid #ccc;
    +    min-width: 220px;
    +    border-radius: 2px;
    +}
    +.login_table .tdinputlogin .fa {
    +	padding-left: 10px;
    +	width: 14px;
    +}
    +
     .login_main_message {
     	text-align: center;
     	max-width: 570px;
    @@ -2300,7 +2347,7 @@ a.tabTitle {
     
     a.tab:link, a.tab:visited, a.tab:hover, a.tab#active {
     	font-family: <?php print $fontlist ?>;
    -	padding: 12px 9px 12px;
    +	padding: 12px 13px 12px;
         margin: 0em 0.2em;
         text-decoration: none;
         white-space: nowrap;
    @@ -2662,6 +2709,8 @@ table.paddingtopbottomonly tr td {
     }
     tr.liste_titre_filter td.liste_titre {
         border-bottom: 1px solid #FDFFFF;
    +	padding-top: 4px;
    +	padding-bottom: 3px;
     }
     .liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd
     {
    @@ -2693,7 +2742,7 @@ table.liste td, table.noborder td, div.noborder form div {
     	padding: 8px 6px 8px 6px;			/* t r b l */
     }
     div.liste_titre_bydiv .divsearchfield {
    -	padding: 2px 1px 2px 0px;			/* t r b l */
    +	padding: 2px 1px 2px 6px;			/* t r b l */
     }
     
     table.nobordernopadding {
    @@ -2892,6 +2941,12 @@ ul.noborder li:nth-child(odd):not(.liste_titre) {
     
     
     /* Set the color for hover lines */
    +
    +.nohoverborder:hover {
    +	border: unset;
    +	box-shadow: unset;
    +	-webkit-box-shadow: unset;
    +}
     .oddeven:hover, .evenodd:hover, .impair:hover, .pair:hover
     {
     <?php if ($colorbacklinepairhover) { ?>
    @@ -2899,6 +2954,12 @@ ul.noborder li:nth-child(odd):not(.liste_titre) {
     <?php } ?>
     }
     
    +<?php if ($colorbacklinepairchecked) { ?>
    +.highlight {
    +	background: rgb(<?php echo $colorbacklinepairchecked; ?>) !important; /* Must be background to be stronger than background of odd or even */
    +}
    +<?php } ?>
    +
     .oddeven, .evenodd, .impair, .nohover .impair:hover, tr.impair td.nohover
     {
     	font-family: <?php print $fontlist ?>;
    @@ -3362,7 +3423,7 @@ div.warning {
         background: #fcf8e3;
     }
     div.warning a, div.info a, div.error a {
    -	color: rgb(<?php echo $colortext; ?>);
    +	color: rgb(<?php echo $colortextlink; ?>);
     }
     
     /* Error message */
    @@ -4737,7 +4798,81 @@ span.noborderoncategories {
     
     
     /* ============================================================================== */
    -/*  Multiselect with checkbox                                                     */
    +/*  External lib multiselect with checkbox                                        */
    +/* ============================================================================== */
    +
    +.multi-select-container {
    +  display: inline-block;
    +  position: relative;
    +}
    +
    +.multi-select-menu {
    +  position: absolute;
    +  left: 0;
    +  top: 0.8em;
    +  float: left;
    +  min-width: 100%;
    +  background: #fff;
    +  margin: 1em 0;
    +  padding: 0.4em 0;
    +  border: 1px solid #aaa;
    +  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    +  display: none;
    +}
    +
    +.multi-select-menu input {
    +  margin-right: 0.3em;
    +  vertical-align: 0.1em;
    +}
    +
    +.multi-select-button {
    +  display: inline-block;
    +  max-width: 20em;
    +  white-space: nowrap;
    +  overflow: hidden;
    +  text-overflow: ellipsis;
    +  vertical-align: middle;
    +  background-color: #fff;
    +  cursor: default;
    +
    +  border: none;
    +  border-bottom: solid 1px rgba(0,0,0,.2);
    +  padding: 5px;
    +  padding-left: 2px;
    +  height: 17px;
    +}
    +.multi-select-button:focus {
    +  outline: none;
    +  border-bottom: 1px solid #666;
    +}
    +
    +.multi-select-button:after {
    +  content: "";
    +  display: inline-block;
    +  width: 0;
    +  height: 0;
    +  border-style: solid;
    +  border-width: 0.5em 0.23em 0em 0.23em;
    +  border-color: #444 transparent transparent transparent;
    +  margin-left: 0.4em;
    +}
    +
    +.multi-select-container--open .multi-select-menu { display: block; }
    +
    +.multi-select-container--open .multi-select-button:after {
    +  border-width: 0 0.4em 0.4em 0.4em;
    +  border-color: transparent transparent #999 transparent;
    +}
    +
    +.multi-select-menuitem {
    +    clear: both;
    +    float: left;
    +    padding-left: 5px
    +}
    +
    +
    +/* ============================================================================== */
    +/*  Native multiselect with checkbox                                              */
     /* ============================================================================== */
     
     ul.ulselectedfields {
    @@ -4748,7 +4883,7 @@ dl.dropdown {
         padding:0px;
     	margin-left: 2px;
         margin-right: 2px;
    -    vertical-align: text-bottom;
    +    vertical-align: middle;
         display: inline-block;
     }
     .dropdown dd, .dropdown dt {
    @@ -4777,10 +4912,10 @@ dl.dropdown {
     }
     .dropdown dd ul {
         background-color: #FFF;
    -    border: 1px solid #888;
    +    box-shadow: 1px 1px 10px #aaa;
         display:none;
         right:0px;						/* pop is align on right */
    -    padding: 2px 15px 2px 5px;
    +    padding: 0 0 0 0;
         position:absolute;
         top:2px;
         list-style:none;
    @@ -4790,9 +4925,12 @@ dl.dropdown {
     .dropdown dd ul li {
     	white-space: nowrap;
     	font-weight: normal;
    -	padding: 2px;
    +	padding: 7px 8px 7px 8px;
     	color: #000;
     }
    +.dropdown dd ul li:hover {
    +	background: #eee;
    +}
     .dropdown dd ul li input[type="checkbox"] {
         margin-right: 3px;
     }
    @@ -4804,7 +4942,7 @@ dl.dropdown {
     	color: #888;
     }
     .dropdown dd ul li a:hover {
    -    background-color:#fff;
    +    background-color: #eee;
     }
     
     
    diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php
    index b736b49646f..c4718c395b3 100644
    --- a/htdocs/ticket/card.php
    +++ b/htdocs/ticket/card.php
    @@ -55,26 +55,43 @@ $action    = GETPOST('action', 'alpha', 3);
     $hookmanager->initHooks(array('ticketcard','globalcard'));
     
     $object = new Ticket($db);
    -
     $extrafields = new ExtraFields($db);
    +// Fetch optionals attributes and labels
     $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
    +$search_array_options=$extrafields->getOptionalsFromPost($extralabels,'','search_');
     
    -if (!$action) {
    -    $action = 'view';
    +// Initialize array of search criterias
    +$search_all=trim(GETPOST("search_all",'alpha'));
    +$search=array();
    +foreach($object->fields as $key => $val)
    +{
    +	if (GETPOST('search_'.$key,'alpha')) $search[$key]=GETPOST('search_'.$key,'alpha');
     }
    +
    +if (empty($action) && empty($id) && empty($ref)) $action='view';
    +
     //Select mail models is same action as add_message
     if (GETPOST('modelselected','alpha')) {
         $action = 'add_message';
     }
     
    +// Load object
    +//include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php';  // Must be include, not include_once  // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
    +if ($id || $track_id || $ref) {
    +	$res = $object->fetch($id, $ref, $track_id);
    +	if ($res >= 0)
    +	{
    +		$id = $object->id;
    +		$track_id = $object->track_id;
    +	}
    +}
    +
     // Store current page url
     $url_page_current = DOL_URL_ROOT.'/ticket/card.php';
     
    -if ($id || $track_id || $ref) {
    -	$res = $object->fetch($id, $ref, $track_id);
    -}
    -
    -// Security check
    +// Security check - Protection if external user
    +//if ($user->societe_id > 0) access_forbidden();
    +//if ($user->societe_id > 0) $socid = $user->societe_id;
     $result = restrictedArea($user, 'ticket', $object->id);
     
     $triggermodname = 'TICKETSUP_MODIFY';
    @@ -89,7 +106,9 @@ $now = dol_now();
      * Actions
      */
     
    -// TODO Replace actions with common includes actions_addupdatedelete.inc.php
    +$parameters=array();
    +$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 ($cancel)
     {
    @@ -98,7 +117,7 @@ if ($cancel)
     		header("Location: ".$backtopage);
     		exit;
     	}
    -	$action='';
    +	$action='view';
     }
     
     // Do action
    @@ -157,26 +176,25 @@ include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';        // Must be inc
     $userstat = new User($db);
     $form = new Form($db);
     $formticket = new FormTicket($db);
    +if (! empty($conf->projet->enabled)) $formproject = new FormProjets($db);
     
    -if (! empty($conf->projet->enabled)) {
    -	$formproject = new FormProjets($db);
    -}
    +$help_url = 'FR:DocumentationModuleTicket';
    +$page_title = $actionobject->getTitle($action);
     
    -if ($action == 'view' || $action == 'add_message' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen'
    +llxHeader('', $page_title, $help_url);
    +
    +
    +if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'add_message' || $action == 'close' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'reopen'
     	|| $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink')
     {
     
    -    if ($res > 0) {
    +    if ($res > 0)
    +    {
             // or for unauthorized internals users
             if (!$user->societe_id && ($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY && $object->fk_user_assign != $user->id) && !$user->rights->ticket->manage) {
                 accessforbidden('', 0);
             }
     
    -        $help_url = 'FR:DocumentationModuleTicket';
    -        $page_title = $actionobject->getTitle($action);
    -
    -        llxHeader('', $page_title, $help_url);
    -
             // Confirmation close
             if ($action == 'close') {
                 print $form->formconfirm($url_page_current . "?track_id=" . $object->track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_close", '', '', 1);
    @@ -287,7 +305,7 @@ if ($action == 'view' || $action == 'add_message' || $action == 'close' || $acti
             $morehtmlref.= $object->subject;
             // Author
             if ($object->fk_user_create > 0) {
    -        	$morehtmlref .= '<br>' . $langs->trans("CreatedBy") . '  ';
    +        	$morehtmlref .= '<br>' . $langs->trans("CreatedBy") . ' : ';
     
                 $langs->load("users");
                 $fuser = new User($db);
    @@ -295,10 +313,24 @@ if ($action == 'view' || $action == 'add_message' || $action == 'close' || $acti
                 $morehtmlref .= $fuser->getNomUrl(0);
             }
             if (!empty($object->origin_email)) {
    -        	$morehtmlref .= '<br>' . $langs->trans("CreatedBy") . ' ';
    +        	$morehtmlref .= '<br>' . $langs->trans("CreatedBy") . ' : ';
             	$morehtmlref .= $object->origin_email . ' <small>(' . $langs->trans("TicketEmailOriginIssuer") . ')</small>';
             }
     
    +        // Thirdparty
    +        if (! empty($conf->societe->enabled))
    +        {
    +	        $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' ';
    +	        if ($action != 'editcustomer' && $object->fk_statut < 8 && !$user->societe_id && $user->rights->ticket->write) {
    +	        	$morehtmlref.='<a href="' . $url_page_current . '?action=editcustomer&amp;track_id=' . $object->track_id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . '</a> : ';
    +	        }
    +	        if ($action == 'editcustomer') {
    +	        	$morehtmlref.=$form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->socid, 'editcustomer', '', 1, 0, 0, array(), 1);
    +	        } else {
    +	        	$morehtmlref.=$form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->socid, 'none', '', 1, 0, 0, array(), 1);
    +	        }
    +        }
    +
             // Project
             if (! empty($conf->projet->enabled))
             {
    @@ -323,9 +355,7 @@ if ($action == 'view' || $action == 'add_message' || $action == 'close' || $acti
             		if (! empty($object->fk_project)) {
             			$proj = new Project($db);
             			$proj->fetch($object->fk_project);
    -        			$morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
    -        			$morehtmlref.=$proj->ref;
    -        			$morehtmlref.='</a>';
    +        			$morehtmlref.=$proj->getNomUrl(1);
             		} else {
             			$morehtmlref.='';
             		}
    @@ -385,24 +415,6 @@ if ($action == 'view' || $action == 'add_message' || $action == 'close' || $acti
             }
             print '</td></tr>';
     
    -        // Thirdparty
    -        print '<tr><td>';
    -        print '<table class="nobordernopadding" width="100%"><tr><td>';
    -        print $langs->trans('ThirdParty');
    -        print '</td>';
    -        if ($action != 'editcustomer' && $object->fk_statut < 8 && !$user->societe_id && $user->rights->ticket->write) {
    -            print '<td align="right"><a href="' . $url_page_current . '?action=editcustomer&amp;track_id=' . $object->track_id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . '</a></td>';
    -        }
    -        print '</tr></table>';
    -        print '</td><td colspan="3">';
    -
    -        if ($action == 'editcustomer') {
    -            $form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->fk_soc, 'editcustomer', ($object->fk_soc ? 's.rowid <> ' . $object->fk_soc : ''), 1);
    -        } else {
    -            $form->form_thirdparty($url_page_current . '?track_id=' . $object->track_id, $object->fk_soc, 'none', 's.rowid <> ' . $object->fk_soc, 1);
    -        }
    -        print '</td></tr>';
    -
             // User assigned
             print '<tr><td>' . $langs->trans("AssignedTo") . '</td><td>';
             if ($object->fk_user_assign > 0) {
    @@ -692,151 +704,146 @@ if ($action == 'view' || $action == 'add_message' || $action == 'close' || $acti
     			print '</div>';
             }
     
    -        // Contract
    -        if ($action == 'sel_contract') {
    -            if (!empty($conf->contrat->enabled)) {
    -                $langs->load('contrats');
    -                print load_fiche_titre($langs->trans('LinkToAContract'), '', 'title_commercial.png');
    -
    -                $form_contract = new FormContract($db);
    -                $form_contract->formSelectContract(
    -                    $url_page_current.'?track_id='.$object->track_id,
    -                    $object->fk_soc,
    -                    GETPOST('contractid'),
    -                    'contractid'
    -                );
    -            }
    -        }
    -
             print '</div></div></div>';
             print '<div style="clear:both"></div>';
     
    -        print dol_fiche_end();
    +		dol_fiche_end();
     
     
    -        /* ActionBar */
    -        print '<div class="tabsAction">';
    +		// Buttons for actions
    +		if ($action != 'presend' && $action != 'editline') {
    +			print '<div class="tabsAction">'."\n";
    +			$parameters=array();
    +			$reshook=$hookmanager->executeHooks('addMoreActionsButtons',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
    +			if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
     
    -        // Show link to add a message (if read and not closed)
    -        if ($object->fk_statut < 8 && $action != "add_message") {
    -            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=add_message">' . $langs->trans('TicketAddMessage') . '</a></div>';
    -        }
    +			if (empty($reshook))
    +			{
    +				// Show link to add a message (if read and not closed)
    +		        if ($object->fk_statut < 8 && $action != "add_message") {
    +		            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=add_message">' . $langs->trans('TicketAddMessage') . '</a></div>';
    +		        }
     
    -        // Link to create an intervention
    -        // socid is needed otherwise fichinter ask it and forgot origin after form submit :\
    -        if (!$object->fk_soc && $user->rights->ficheinter->creer) {
    -            print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="' . $langs->trans('UnableToCreateInterIfNoSocid') . '">' . $langs->trans('TicketAddIntervention') . '</a></div>';
    -        }
    -        if ($object->fk_soc > 0 && $object->fk_statut < 8 && $user->rights->ficheinter->creer) {
    -            print '<div class="inline-block divButAction"><a class="butAction" href="' . dol_buildpath('/fichinter/card.php', 1) . '?action=create&socid=' . $object->fk_soc . '&origin=ticket_ticket&originid=' . $object->id . '">' . $langs->trans('TicketAddIntervention') . '</a></div>';
    -        }
    +		        // Link to create an intervention
    +		        // socid is needed otherwise fichinter ask it and forgot origin after form submit :\
    +		        if (!$object->fk_soc && $user->rights->ficheinter->creer) {
    +		            print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="' . $langs->trans('UnableToCreateInterIfNoSocid') . '">' . $langs->trans('TicketAddIntervention') . '</a></div>';
    +		        }
    +		        if ($object->fk_soc > 0 && $object->fk_statut < 8 && $user->rights->ficheinter->creer) {
    +		            print '<div class="inline-block divButAction"><a class="butAction" href="' . dol_buildpath('/fichinter/card.php', 1) . '?action=create&socid=' . $object->fk_soc . '&origin=ticket_ticket&originid=' . $object->id . '">' . $langs->trans('TicketAddIntervention') . '</a></div>';
    +		        }
     
    -        //    Button to link to a contract
    -        if ($user->rights->ticket->write && $object->fk_statut < 5 && $user->rights->contrat->creer) {
    -            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=sel_contract">' . $langs->trans('LinkToAContract') . '</a></div>';
    -        }
    +		        // Close ticket if statut is read
    +		        if ($object->fk_statut > 0 && $object->fk_statut < 8 && $user->rights->ticket->write) {
    +		            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=close">' . $langs->trans('CloseTicket') . '</a></div>';
    +		        }
     
    -        // Close ticket if statut is read
    -        if ($object->fk_statut > 0 && $object->fk_statut < 8 && $user->rights->ticket->write) {
    -            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=close">' . $langs->trans('CloseTicket') . '</a></div>';
    -        }
    +		        // Re-open ticket
    +		        if (!$user->socid && $object->fk_statut == 8 && !$user->societe_id) {
    +		            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=reopen">' . $langs->trans('ReOpen') . '</a></div>';
    +		        }
     
    -        // Re-open ticket
    -        if (!$user->socid && $object->fk_statut == 8 && !$user->societe_id) {
    -            print '<div class="inline-block divButAction"><a class="butAction" href="card.php?track_id=' . $object->track_id . '&action=reopen">' . $langs->trans('ReOpen') . '</a></div>';
    -        }
    -
    -        // Delete ticket
    -        if ($user->rights->ticket->delete && !$user->societe_id) {
    -            print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?track_id=' . $object->track_id . '&action=delete">' . $langs->trans('Delete') . '</a></div>';
    -        }
    -        print '</div>';
    -
    -        if ($action == 'view' || $action == 'edit_message_init') {
    -            print '<div class="fichecenter"><div class="">';
    -
    -            //print '<div style="float: left; width:49%; margin-right: 1%;">';
    -            // Message list
    -            print load_fiche_titre($langs->trans('TicketMessagesList'), '', 'messages@ticket');
    -            $show_private_message = ($user->societe_id ? 0 : 1);
    -            $actionobject->viewTicketTimelineMessages($show_private_message, true, $object);
    -
    -            print '</div><!-- fichehalfleft --> ';
    -            print '</div><!-- fichecenter -->';
    -            print '<br style="clear: both">';
    -        } elseif ($action == 'add_message') {
    -            $action='new_message';
    -            $modelmail='ticket_send';
    -
    -            print '<div>';
    -            print load_fiche_titre($langs->trans('TicketAddMessage'), '', 'messages@ticket');
    -
    -            // Define output language
    -            $outputlangs = $langs;
    -            $newlang = '';
    -            if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) {
    -                $newlang = $_REQUEST['lang_id'];
    -            }
    -            if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
    -                $newlang = $object->default_lang;
    -            }
    -
    -            $formticket = new FormTicket($db);
    -
    -            $formticket->action = $action;
    -            $formticket->track_id = $object->track_id;
    -            $formticket->id = $object->id;
    -
    -            $formticket->withfile = 2;
    -            $formticket->param = array('fk_user_create' => $user->id);
    -            $formticket->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang);
    -
    -            // Tableau des parametres complementaires du post
    -            $formticket->param['models']=$modelmail;
    -            $formticket->param['models_id']=GETPOST('modelmailselected', 'int');
    -            //$formticket->param['socid']=$object->fk_soc;
    -            $formticket->param['returnurl']=$_SERVER["PHP_SELF"].'?track_id='.$object->track_id;
    +		        // Delete ticket
    +		        if ($user->rights->ticket->delete && !$user->societe_id) {
    +		            print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?track_id=' . $object->track_id . '&action=delete">' . $langs->trans('Delete') . '</a></div>';
    +		        }
    +			}
    +	        print '</div>'."\n";
    +		}
     
     
    -            $formticket->withsubstit = 1;
    +		// Select mail models is same action as presend
    +		if (GETPOST('modelselected')) {
    +			$action = 'presend';
    +		}
     
    -            if ($object->fk_soc > 0) {
    -                $object->fetch_thirdparty();
    -                $formticket->substit['__THIRDPARTY_NAME__'] = $object->thirdparty->name;
    -            }
    -            $formticket->substit['__SIGNATURE__'] = $user->signature;
    -            $formticket->substit['__TICKETSUP_TRACKID__'] = $object->track_id;
    -            $formticket->substit['__TICKETSUP_REF__'] = $object->ref;
    -            $formticket->substit['__TICKETSUP_SUBJECT__'] = $object->subject;
    -            $formticket->substit['__TICKETSUP_TYPE__'] = $object->type_code;
    -            $formticket->substit['__TICKETSUP_CATEGORY__'] = $object->category_code;
    -            $formticket->substit['__TICKETSUP_SEVERITY__'] = $object->severity_code;
    -            $formticket->substit['__TICKETSUP_MESSAGE__'] = $object->message;
    -            $formticket->substit['__TICKETSUP_PROGRESSION__'] = $object->progress;
    -            if ($object->fk_user_assign > 0) {
    -                $userstat->fetch($object->fk_user_assign);
    -                $formticket->substit['__TICKETSUP_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname);
    -            }
    +		if (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'edit_message_init')
    +		{
    +			print '<div class="fichecenter"><div class="fichehalfleft">';
    +			print '<a name="builddoc"></a>'; // ancre
     
    -            if ($object->fk_user_create > 0) {
    -                $userstat->fetch($object->fk_user_create);
    -                $formticket->substit['__TICKETSUP_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname);
    -            }
    +			// Show links to link elements
    +			$linktoelem = $form->showLinkToObjectBlock($object, null, array('ticket'));
    +			$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
    +
    +			print '</div><div class="fichehalfright"><div class="ficheaddleft">';
    +
    +			// Message list
    +			print load_fiche_titre($langs->trans('TicketMessagesList'), '', 'messages@ticket');
    +			$show_private_message = ($user->societe_id ? 0 : 1);
    +			$actionobject->viewTicketTimelineMessages($show_private_message, true, $object);
    +
    +			print '</div></div>';
    +			print '</div><!-- fichecenter -->';
    +			print '<br style="clear: both">';
    +		}
    +		elseif ($action == 'add_message')
    +		{
    +			$action='new_message';
    +			$modelmail='ticket_send';
    +
    +			print '<div>';
    +			print load_fiche_titre($langs->trans('TicketAddMessage'), '', 'messages@ticket');
    +
    +			// Define output language
    +			$outputlangs = $langs;
    +			$newlang = '';
    +			if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) {
    +				$newlang = $_REQUEST['lang_id'];
    +			}
    +			if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
    +				$newlang = $object->default_lang;
    +			}
    +
    +			$formticket = new FormTicket($db);
    +
    +			$formticket->action = $action;
    +			$formticket->track_id = $object->track_id;
    +			$formticket->id = $object->id;
    +
    +			$formticket->withfile = 2;
    +			$formticket->param = array('fk_user_create' => $user->id);
    +			$formticket->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang);
    +
    +			// Tableau des parametres complementaires du post
    +			$formticket->param['models']=$modelmail;
    +			$formticket->param['models_id']=GETPOST('modelmailselected', 'int');
    +			//$formticket->param['socid']=$object->fk_soc;
    +			$formticket->param['returnurl']=$_SERVER["PHP_SELF"].'?track_id='.$object->track_id;
     
     
    -            $formticket->showMessageForm('100%');
    -            print '</div>';
    -        }
    -    }
    -} // End action view
    +			$formticket->withsubstit = 1;
     
    -/***************************************************
    - * LINKED OBJECT BLOCK
    - *
    - * Put here code to view linked object
    - ****************************************************/
    -$somethingshown = $form->showLinkedObjectBlock($object);
    +			if ($object->fk_soc > 0) {
    +				$object->fetch_thirdparty();
    +				$formticket->substit['__THIRDPARTY_NAME__'] = $object->thirdparty->name;
    +			}
    +			$formticket->substit['__SIGNATURE__'] = $user->signature;
    +			$formticket->substit['__TICKETSUP_TRACKID__'] = $object->track_id;
    +			$formticket->substit['__TICKETSUP_REF__'] = $object->ref;
    +			$formticket->substit['__TICKETSUP_SUBJECT__'] = $object->subject;
    +			$formticket->substit['__TICKETSUP_TYPE__'] = $object->type_code;
    +			$formticket->substit['__TICKETSUP_CATEGORY__'] = $object->category_code;
    +			$formticket->substit['__TICKETSUP_SEVERITY__'] = $object->severity_code;
    +			$formticket->substit['__TICKETSUP_MESSAGE__'] = $object->message;
    +			$formticket->substit['__TICKETSUP_PROGRESSION__'] = $object->progress;
    +			if ($object->fk_user_assign > 0) {
    +				$userstat->fetch($object->fk_user_assign);
    +				$formticket->substit['__TICKETSUP_USER_ASSIGN__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname);
    +			}
    +
    +			if ($object->fk_user_create > 0) {
    +				$userstat->fetch($object->fk_user_create);
    +				$formticket->substit['__TICKETSUP_USER_CREATE__'] = dolGetFirstLastname($userstat->firstname, $userstat->lastname);
    +			}
    +
    +
    +			$formticket->showMessageForm('100%');
    +			print '</div>';
    +	    }
    +	}
    +}
     
     // End of page
    -llxFooter('');
    +llxFooter();
     $db->close();
    diff --git a/htdocs/ticket/class/actions_ticket.class.php b/htdocs/ticket/class/actions_ticket.class.php
    index 6dc946ebad3..7e8ae39564a 100644
    --- a/htdocs/ticket/class/actions_ticket.class.php
    +++ b/htdocs/ticket/class/actions_ticket.class.php
    @@ -35,22 +35,49 @@ require_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php';
      */
     class ActionsTicket
     {
    +    /**
    +     * @var DoliDB Database handler.
    +     */
         public $db;
    +
         public $dao;
     
         public $mesg;
    -    public $error;
    -    public $errors = array();
    +
    +    /**
    +	 * @var string Error code (or message)
    +	 */
    +	public $error;
    +
    +    /**
    +	 * @var string[] Error codes (or messages)
    +	 */
    +	public $errors = array();
    +
         //! Numero de l'erreur
         public $errno = 0;
     
         public $template_dir;
         public $template;
     
    +    /**
    +     * @var string ticket action label
    +     */
         public $label;
    -    public $description;
     
    +    /**
    +	 * @var string description
    +	 */
    +	public $description;
    +
    +	/**
    +     * @var int ID
    +     */
         public $fk_statut;
    +
    +    /**
    +	 * @var int Thirdparty ID
    +	 */
         public $fk_soc;
     
         /**
    @@ -579,6 +606,7 @@ class ActionsTicket
          *
          * @param User $user        User for action
          * @param string $action    Action string
    +     * @return int
          */
         private function newMessage($user, &$action)
         {
    @@ -792,6 +820,7 @@ class ActionsTicket
          *
          * @param User $user        User for action
          * @param string $action    Action string
    +     * @return void
          */
         private function newMessagePublic($user, &$action)
         {
    @@ -949,7 +978,7 @@ class ActionsTicket
          * Print statut
          *
          * @param		int		$mode		Display mode
    -     * @return 		void
    +     * @return 		string				Label of status
          */
         public function getLibStatut($mode = 0)
         {
    @@ -962,6 +991,7 @@ class ActionsTicket
          * Get ticket info
          *
          * @param  int $id    Object id
    +     * @return void
          */
         public function getInfo($id)
         {
    @@ -975,7 +1005,8 @@ class ActionsTicket
         /**
          * Get action title
          *
    -     * @param string $action    Type of action
    +     * @param string 	$action    	Type of action
    +     * @return string			Title of action
          */
         public function getTitle($action = '')
         {
    @@ -998,10 +1029,11 @@ class ActionsTicket
          * View html list of logs
          *
          * @param boolean $show_user Show user who make action
    +     * @return void
          */
         public function viewTicketLogs($show_user = true)
         {
    -        global $conf, $langs, $bc;
    +        global $conf, $langs;
     
             // Load logs in cache
             $ret = $this->dao->loadCacheLogsTicket();
    @@ -1021,11 +1053,8 @@ class ActionsTicket
                     print '</th>';
                 }
     
    -            $var = true;
    -
                 foreach ($this->dao->cache_logs_ticket as $id => $arraylogs) {
    -                $var = !$var;
    -                print "<tr " . $bc[$var] . ">";
    +                print '<tr class="oddeven">';
                     print '<td><strong>';
                     print dol_print_date($arraylogs['datec'], 'dayhour');
                     print '</strong></td>';
    @@ -1042,7 +1071,7 @@ class ActionsTicket
                         print '</td>';
                     }
                     print '</tr>';
    -                print "<tr " . $bc[$var] . ">";
    +                print '<tr class="oddeven">';
                     print '<td colspan="2">';
                     print dol_nl2br($arraylogs['message']);
     
    @@ -1061,10 +1090,11 @@ class ActionsTicket
          *
          * @param 	boolean 	$show_user 	Show user who make action
          * @param	Ticket	$object		Object
    +     * @return void
          */
         public function viewTimelineTicketLogs($show_user = true, $object = true)
         {
    -    	global $conf, $langs, $bc;
    +    	global $conf, $langs;
     
         	// Load logs in cache
         	$ret = $object->loadCacheLogsTicket();
    @@ -1168,10 +1198,11 @@ class ActionsTicket
          *
          * @param boolean $show_private Show private messages
          * @param boolean $show_user    Show user who make action
    +     * @return void
          */
         public function viewTicketMessages($show_private, $show_user = true)
         {
    -        global $conf, $langs, $user, $bc;
    +        global $conf, $langs, $user;
     		global $object;
     
             // Load logs in cache
    @@ -1202,8 +1233,7 @@ class ActionsTicket
                         || ($arraymsgs['private'] == "1" && $show_private)
                     ) {
                         //print '<tr>';
    -                    $var = !$var;
    -                    print "<tr " . $bc[$var] . ">";
    +                    print '<tr class="oddeven">';
                         print '<td><strong>';
                         print dol_print_date($arraymsgs['datec'], 'dayhour');
                         print '<strong></td>';
    @@ -1221,7 +1251,7 @@ class ActionsTicket
                             print '</td>';
                         }
                         print '</td>';
    -                    print "<tr " . $bc[$var] . ">";
    +                    print '<tr class="oddeven">';
                         print '<td colspan="2">';
                         print $arraymsgs['message'];
                         print '</td>';
    @@ -1241,10 +1271,11 @@ class ActionsTicket
          * @param 	boolean 	$show_private Show private messages
          * @param 	boolean 	$show_user    Show user who make action
          * @param	Ticket	$object		 Object ticket
    +     * @return void
          */
         public function viewTicketTimelineMessages($show_private, $show_user, Ticket $object)
         {
    -    	global $conf, $langs, $user, $bc;
    +    	global $conf, $langs, $user;
     
         	// Load logs in cache
         	$ret = $object->loadCacheMsgsTicket();
    @@ -1292,6 +1323,7 @@ class ActionsTicket
         	}
         }
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          * load_previous_next_ref
          *
    @@ -1301,6 +1333,7 @@ class ActionsTicket
          */
         function load_previous_next_ref($filter, $fieldid)
         {
    +        // phpcs:enable
             $this->getInstanceDao();
             return $object->load_previous_next_ref($filter, $fieldid);
         }
    @@ -1312,6 +1345,7 @@ class ActionsTicket
          * @param string $message          Email message
          * @param int    $send_internal_cc Receive a copy on internal email ($conf->global->TICKET_NOTIFICATION_EMAIL_FROM)
          * @param array  $array_receiver   Array of receiver. exemple array('name' => 'John Doe', 'email' => 'john@doe.com', etc...)
    +     * @return void
          */
         public function sendTicketMessageByEmail($subject, $message, $send_internal_cc = 0, $array_receiver = array())
         {
    diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php
    index c75ab7e2450..110c27a5cce 100644
    --- a/htdocs/ticket/class/api_tickets.class.php
    +++ b/htdocs/ticket/class/api_tickets.class.php
    @@ -473,190 +473,6 @@ class Tickets extends DolibarrApi
             );
         }
     
    -
    -    /**
    -     * Get the list of tickets categories.
    -     *
    -     * @param string    $sortfield  Sort field
    -     * @param string    $sortorder  Sort order
    -     * @param int       $limit      Number of items per page
    -     * @param int       $page       Page number (starting from zero)
    -     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of events types
    -     *
    -     * @url     GET setup/dictionary/categories
    -     *
    -     * @throws RestException
    -     */
    -    function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    -    {
    -    	$list = array();
    -
    -    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    -    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
    -    	$sql.= " WHERE t.active = 1";
    -    	// Add sql filters
    -    	if ($sqlfilters)
    -    	{
    -    		if (! DolibarrApi::_checkFilters($sqlfilters))
    -    		{
    -    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    -    		}
    -    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    -    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    -    	}
    -
    -
    -    	$sql.= $this->db->order($sortfield, $sortorder);
    -
    -    	if ($limit) {
    -    		if ($page < 0) {
    -    			$page = 0;
    -    		}
    -    		$offset = $limit * $page;
    -
    -    		$sql .= $this->db->plimit($limit, $offset);
    -    	}
    -
    -    	$result = $this->db->query($sql);
    -
    -    	if ($result) {
    -    		$num = $this->db->num_rows($result);
    -    		$min = min($num, ($limit <= 0 ? $num : $limit));
    -    		for ($i = 0; $i < $min; $i++) {
    -    			$list[] = $this->db->fetch_object($result);
    -    		}
    -    	} else {
    -    		throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
    -    	}
    -
    -    	return $list;
    -    }
    -
    -    /**
    -     * Get the list of tickets severity.
    -     *
    -     * @param string    $sortfield  Sort field
    -     * @param string    $sortorder  Sort order
    -     * @param int       $limit      Number of items per page
    -     * @param int       $page       Page number (starting from zero)
    -     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of events types
    -     *
    -     * @url     GET setup/dictionary/severities
    -     *
    -     * @throws RestException
    -     */
    -    function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    -    {
    -    	$list = array();
    -
    -    	$sql = "SELECT rowid, code, pos,  label, use_default, color, description";
    -    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
    -    	$sql.= " WHERE t.active = 1";
    -    	// Add sql filters
    -    	if ($sqlfilters)
    -    	{
    -    		if (! DolibarrApi::_checkFilters($sqlfilters))
    -    		{
    -    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    -    		}
    -    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    -    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    -    	}
    -
    -
    -    	$sql.= $this->db->order($sortfield, $sortorder);
    -
    -    	if ($limit) {
    -    		if ($page < 0) {
    -    			$page = 0;
    -    		}
    -    		$offset = $limit * $page;
    -
    -    		$sql .= $this->db->plimit($limit, $offset);
    -    	}
    -
    -    	$result = $this->db->query($sql);
    -
    -    	if ($result) {
    -    		$num = $this->db->num_rows($result);
    -    		$min = min($num, ($limit <= 0 ? $num : $limit));
    -    		for ($i = 0; $i < $min; $i++) {
    -    			$list[] = $this->db->fetch_object($result);
    -    		}
    -    	} else {
    -    		throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
    -    	}
    -
    -    	return $list;
    -    }
    -
    -    /**
    -     * Get the list of tickets types.
    -     *
    -     * @param string    $sortfield  Sort field
    -     * @param string    $sortorder  Sort order
    -     * @param int       $limit      Number of items per page
    -     * @param int       $page       Page number (starting from zero)
    -     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of events types
    -     *
    -     * @url     GET setup/dictionary/types
    -     *
    -     * @throws RestException
    -     */
    -    function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    -    {
    -    	$list = array();
    -
    -    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    -    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
    -    	$sql.= " WHERE t.active = 1";
    -    	if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'";
    -    	if ($module)    $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
    -    	// Add sql filters
    -    	if ($sqlfilters)
    -    	{
    -    		if (! DolibarrApi::_checkFilters($sqlfilters))
    -    		{
    -    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    -    		}
    -    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    -    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    -    	}
    -
    -
    -    	$sql.= $this->db->order($sortfield, $sortorder);
    -
    -    	if ($limit) {
    -    		if ($page < 0) {
    -    			$page = 0;
    -    		}
    -    		$offset = $limit * $page;
    -
    -    		$sql .= $this->db->plimit($limit, $offset);
    -    	}
    -
    -    	$result = $this->db->query($sql);
    -
    -    	if ($result) {
    -    		$num = $this->db->num_rows($result);
    -    		$min = min($num, ($limit <= 0 ? $num : $limit));
    -    		for ($i = 0; $i < $min; $i++) {
    -    			$list[] = $this->db->fetch_object($result);
    -    		}
    -    	} else {
    -    		throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
    -    	}
    -
    -    	return $list;
    -    }
    -
    -
    -
    -
    -
         /**
          * Validate fields before create or update object
          *
    diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php
    index 76c9eb8856e..03aec1eb818 100644
    --- a/htdocs/ticket/class/ticket.class.php
    +++ b/htdocs/ticket/class/ticket.class.php
    @@ -25,8 +25,8 @@
     // Put here all includes required by your class file
     require_once DOL_DOCUMENT_ROOT . "/core/class/commonobject.class.php";
     require_once DOL_DOCUMENT_ROOT . '/fichinter/class/fichinter.class.php';
    -//require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    -//require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    +//require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
    +//require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
     
     
     /**
    @@ -38,22 +38,27 @@ class Ticket extends CommonObject
          * @var string ID to identify managed object
          */
         public $element = 'ticket';
    +
         /**
          * @var string Name of table without prefix where object is stored
          */
         public $table_element = 'ticket';
    +
         /**
          * @var string Name of field for link to tickets
          */
         public $fk_element='fk_ticket';
    +
         /**
          * @var int  Does ticketcore support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
          */
         public $ismultientitymanaged = 1;
    +
         /**
          * @var int  Does ticketcore support extrafields ? 0=No, 1=Yes
          */
         public $isextrafieldmanaged = 1;
    +
         /**
          * @var string String with name of icon for ticketcore. Must be the part after the 'object_' into object_ticketcore.png
          */
    @@ -211,8 +216,6 @@ class Ticket extends CommonObject
         const STATUS_CANCELED = 9;
     
     
    -
    -
         /**
          *  Constructor
          *
    @@ -555,7 +558,7 @@ class Ticket extends CommonObject
          * @param  int    $offset    Offset for query
          * @param  int    $arch      archive or not (not used)
          * @param  array  $filter    Filter for query
    -     *            output
    +     *                           output
          * @return int <0 if KO, >0 if OK
          */
         public function fetchAll($user, $sortorder = 'ASC', $sortfield = 't.datec', $limit = '', $offset = 0, $arch = '', $filter = '')
    @@ -1020,7 +1023,12 @@ class Ticket extends CommonObject
             $this->tms = '';
         }
     
    -
    +    /**
    +     * print selected status
    +     *
    +     * @param string    $selected   selected status
    +     * @return void
    +     */
         public function printSelectStatus($selected = "")
         {
             print Form::selectarray('search_fk_statut', $this->statuts_short, $selected, $show_empty = 1, $key_in_label = 0, $value_as_key = 0, $option = '', $translate = 1, $maxlen = 0, $disabled = 0, $sort = '', $morecss = '');
    @@ -1159,6 +1167,7 @@ class Ticket extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
          *    Return status label of object
          *
    @@ -1168,143 +1177,144 @@ class Ticket extends CommonObject
          */
         function LibStatut($statut, $mode = 0)
         {
    +        // phpcs:enable
             global $langs;
     
             if ($mode == 0) {
                 return $langs->trans($this->statuts[$statut]);
             }
    -        if ($mode == 1) {
    +        elseif ($mode == 1) {
                 return $langs->trans($this->statuts_short[$statut]);
             }
    -        if ($mode == 2) {
    +        elseif ($mode == 2) {
                 if ($statut == 0) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 1) {
    +            elseif ($statut == 1) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 3) {
    +            elseif ($statut == 3) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 4) {
    +            elseif ($statut == 4) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 5) {
    +            elseif ($statut == 5) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 6) {
    +            elseif ($statut == 6) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 8) {
    +            elseif ($statut == 8) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 9) {
    +            elseif ($statut == 9) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
             }
    -        if ($mode == 3) {
    +        elseif ($mode == 3) {
                 if ($statut == 0) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket');
                 }
     
    -            if ($statut == 1) {
    +            elseif ($statut == 1) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket');
                 }
     
    -            if ($statut == 3) {
    +            elseif ($statut == 3) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket');
                 }
     
    -            if ($statut == 4) {
    +            elseif ($statut == 4) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket');
                 }
     
    -            if ($statut == 5) {
    +            elseif ($statut == 5) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket');
                 }
     
    -            if ($statut == 6) {
    +            elseif ($statut == 6) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket');
                 }
     
    -            if ($statut == 8) {
    +            elseif ($statut == 8) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket');
                 }
     
    -            if ($statut == 9) {
    +            elseif ($statut == 9) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket');
                 }
             }
    -        if ($mode == 4) {
    +        elseif ($mode == 4) {
                 if ($statut == 0) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 1) {
    +            elseif ($statut == 1) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 3) {
    +            elseif ($statut == 3) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 4) {
    +            elseif ($statut == 4) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 5) {
    +            elseif ($statut == 5) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 6) {
    +            elseif ($statut == 6) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 8) {
    +            elseif ($statut == 8) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
     
    -            if ($statut == 9) {
    +            elseif ($statut == 9) {
                     return img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket') . ' ' . $langs->trans($this->statuts_short[$statut]);
                 }
             }
    -        if ($mode == 5) {
    +        elseif ($mode == 5) {
                 if ($statut == 0) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut0.png@ticket');
                 }
     
    -            if ($statut == 1) {
    +            elseif ($statut == 1) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut1.png@ticket');
                 }
     
    -            if ($statut == 3) {
    +            elseif ($statut == 3) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut3.png@ticket');
                 }
     
    -            if ($statut == 4) {
    +            elseif ($statut == 4) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut4.png@ticket');
                 }
     
    -            if ($statut == 5) {
    +            elseif ($statut == 5) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut5.png@ticket');
                 }
     
    -            if ($statut == 6) {
    +            elseif ($statut == 6) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut6.png@ticket');
                 }
     
    -            if ($statut == 8) {
    +            elseif ($statut == 8) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut8.png@ticket');
                 }
     
    -            if ($statut == 9) {
    +            elseif ($statut == 9) {
                     return $langs->trans($this->statuts_short[$statut]) . ' ' . img_picto($langs->trans($this->statuts_short[$statut]), 'statut9.png@ticket');
                 }
             }
    @@ -1478,8 +1488,6 @@ class Ticket extends CommonObject
     			dol_syslog(get_class($this) . "::assignUser " . $this->error, LOG_ERR);
     			return - 1;
     		}
    -
    -		return 0;
     	}
     
         /**
    @@ -1614,8 +1622,8 @@ class Ticket extends CommonObject
                     }
                     include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php';
                     $mailfile = new CMailFile($subject, $info_sendto['email'], $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, 0);
    -                if ($mailfile->error) {
    -                    setEventMessage($mailfile->error, 'errors');
    +                if ($mailfile->error || $mailfile->errors) {
    +                    setEventMessages($mailfile->error, $mailfile->errors, 'errors');
                     } else {
                         $result = $mailfile->sendfile();
                         if ($result > 0) {
    @@ -1627,7 +1635,7 @@ class Ticket extends CommonObject
                     }
                 }
     
    -            setEventMessage($langs->trans('TicketNotificationNumberEmailSent', $nb_sent));
    +            setEventMessages($langs->trans('TicketNotificationNumberEmailSent', $nb_sent), null, 'mesgs');
             }
     
             return $nb_sent;
    @@ -2436,6 +2444,7 @@ class Ticket extends CommonObject
         }
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
     	 *  Return if at least one photo is available
     	 *
    @@ -2444,6 +2453,7 @@ class Ticket extends CommonObject
     	 */
         function is_photo_available($sdir)
         {
    +        // phpcs:enable
             include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
     
             global $conf;
    @@ -2468,7 +2478,6 @@ class Ticket extends CommonObject
             }
             return false;
         }
    -
     }
     
     
    @@ -2477,7 +2486,10 @@ class Ticket extends CommonObject
      */
     class TicketsLine
     {
    -    public $id;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
         /**
          * @var string  $ref    Ticket reference
    @@ -2490,8 +2502,8 @@ class TicketsLine
         public $track_id;
     
         /**
    -	 * Thirdparty ID
    -	*/
    +	 * @var int Thirdparty ID
    +	 */
         public $fk_soc;
     
         /**
    @@ -2588,5 +2600,4 @@ class TicketsLine
      	 * Close ticket date
     	 */
         public $date_close = '';
    -
     }
    diff --git a/htdocs/ticket/class/ticketlogs.class.php b/htdocs/ticket/class/ticketlogs.class.php
    index ffa6a193415..66cecd6eb5e 100644
    --- a/htdocs/ticket/class/ticketlogs.class.php
    +++ b/htdocs/ticket/class/ticketlogs.class.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) - 2013-2016    Jean-François FERRY    <hello@librethic.io>
    +/* Copyright (C) 2013-2016  Jean-François FERRY     <hello@librethic.io>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -23,8 +24,8 @@
     
     // Put here all includes required by your class file
     require_once DOL_DOCUMENT_ROOT . "/core/class/commonobject.class.php";
    -//require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    -//require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    +//require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
    +//require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
     
     
     /**
    @@ -32,16 +33,46 @@ require_once DOL_DOCUMENT_ROOT . "/core/class/commonobject.class.php";
      */
     class Ticketlogs// extends CommonObject
     {
    -    public $db; //!< To store db handler
    -    public $error; //!< To return error code (or message)
    -    public $errors = array(); //!< To return several error codes (or messages)
    -    public $element = 'ticketlogs'; //!< Id that identify managed objects
    +    /**
    +     * @var DoliDB Database handler.
    +     */
    +    public $db;
    +
    +    /**
    +     * @var string Error code (or message)
    +     */
    +    public $error;
    +
    +    /**
    +     * @var string[] Error codes (or messages)
    +     */
    +    public $errors = array();
    +
    +    /**
    +     * @var string ID to identify managed object
    +     */
    +    public $element = 'ticketlogs';
    +
    +    /**
    +     * @var string Name of table without prefix where object is stored
    +     */
         public $table_element = 'ticketlogs'; //!< Name of table without prefix where object is stored
     
    -    public $id;
    +    /**
    +	 * @var int ID
    +	 */
    +	public $id;
     
    +	/**
    +     * @var string trackid
    +     */
         public $fk_track_id;
    +
    +    /**
    +     * @var int user create ID
    +     */
         public $fk_user_create;
    +
         public $datec = '';
         public $message;
     
    @@ -53,7 +84,6 @@ class Ticketlogs// extends CommonObject
         public function __construct($db)
         {
             $this->db = $db;
    -        return 1;
         }
     
         /**
    @@ -75,7 +105,7 @@ class Ticketlogs// extends CommonObject
             }
     
             if (isset($this->fk_user_create)) {
    -            $this->fk_user_create = trim($this->fk_user_create);
    +            $this->fk_user_create = (int) $this->fk_user_create;
             }
     
             if (isset($this->message)) {
    @@ -114,7 +144,7 @@ class Ticketlogs// extends CommonObject
             if (!$error) {
                 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "ticket_logs");
     
    -            if (!$notrigger) {
    +            //if (!$notrigger) {
                     // Uncomment this and change MYOBJECT to your own tag if you
                     // want this action calls a trigger.
     
    @@ -124,7 +154,7 @@ class Ticketlogs// extends CommonObject
                     //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
                     //if ($result < 0) { $error++; $this->errors=$interface->errors; }
                     //// End call triggers
    -            }
    +            //}
             }
     
             // Commit or rollback
    @@ -203,7 +233,7 @@ class Ticketlogs// extends CommonObject
             }
     
             if (isset($this->fk_user_create)) {
    -            $this->fk_user_create = trim($this->fk_user_create);
    +            $this->fk_user_create = (int) $this->fk_user_create;
             }
     
             if (isset($this->message)) {
    @@ -232,8 +262,8 @@ class Ticketlogs// extends CommonObject
                 $this->errors[] = "Error " . $this->db->lasterror();
             }
     
    -        if (!$error) {
    -            if (!$notrigger) {
    +        //if (!$error) {
    +            //if (!$notrigger) {
                     // Uncomment this and change MYOBJECT to your own tag if you
                     // want this action calls a trigger.
     
    @@ -243,8 +273,8 @@ class Ticketlogs// extends CommonObject
                     //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
                     //if ($result < 0) { $error++; $this->errors=$interface->errors; }
                     //// End call triggers
    -            }
    -        }
    +            //}
    +        //}
     
             // Commit or rollback
             if ($error) {
    @@ -274,8 +304,8 @@ class Ticketlogs// extends CommonObject
     
             $this->db->begin();
     
    -        if (!$error) {
    -            if (!$notrigger) {
    +        //if (!$error) {
    +            //if (!$notrigger) {
                     // Uncomment this and change MYOBJECT to your own tag if you
                     // want this action calls a trigger.
     
    @@ -285,8 +315,8 @@ class Ticketlogs// extends CommonObject
                     //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
                     //if ($result < 0) { $error++; $this->errors=$interface->errors; }
                     //// End call triggers
    -            }
    -        }
    +            //}
    +        //}
     
             if (!$error) {
                 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "ticket_logs";
    @@ -322,10 +352,12 @@ class Ticketlogs// extends CommonObject
          */
         public function initAsSpecimen()
         {
    +	global $user;
    +	    
             $this->id = 0;
     
             $this->fk_track_id = '';
    -        $this->fk_user_create = '';
    +        $this->fk_user_create = $user->id;
             $this->datec = '';
             $this->message = '';
         }
    diff --git a/htdocs/ticket/class/ticketstats.class.php b/htdocs/ticket/class/ticketstats.class.php
    index 6b65f25016a..28a49a3bd8f 100644
    --- a/htdocs/ticket/class/ticketstats.class.php
    +++ b/htdocs/ticket/class/ticketstats.class.php
    @@ -29,7 +29,10 @@ require_once 'ticket.class.php';
      */
     class TicketStats extends Stats
     {
    -    public $table_element;
    +    /**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element;
     
         public $socid;
         public $userid;
    diff --git a/htdocs/ticket/document.php b/htdocs/ticket/document.php
    index e31cd98912d..d1d80387f6e 100644
    --- a/htdocs/ticket/document.php
    +++ b/htdocs/ticket/document.php
    @@ -138,7 +138,7 @@ if ($object->id)
     
         dol_fiche_end();
     
    -    // Construit liste des fichiers
    +    // Build file list
         $filearray = dol_dir_list($upload_dir, "files", 0, '', '\.meta$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1);
         $totalsize = 0;
         foreach ($filearray as $key => $file) {
    @@ -158,5 +158,6 @@ else
         accessforbidden('', 0, 0);
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php
    index 76edc111b14..1b43d0054b7 100644
    --- a/htdocs/ticket/list.php
    +++ b/htdocs/ticket/list.php
    @@ -409,7 +409,6 @@ if ($projectid > 0) {
             dol_fiche_end();
     
             $object = $savobject;
    -
         } else {
             print "ErrorRecordNotFound";
         }
    @@ -701,7 +700,7 @@ if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nb
     	$hidegeneratedfilelistifempty=1;
     	if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) $hidegeneratedfilelistifempty=0;
     
    -	require_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    +	require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
     	$formfile = new FormFile($db);
     
     	// Show list of available documents
    diff --git a/htdocs/user/admin/group_extrafields.php b/htdocs/user/admin/group_extrafields.php
    index 0dd5cf9ce7e..48e2b4091d6 100644
    --- a/htdocs/user/admin/group_extrafields.php
    +++ b/htdocs/user/admin/group_extrafields.php
    @@ -82,7 +82,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
     	print '<div class="tabsAction">';
    -	print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +	print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
     	print "</div>";
     }
     
    @@ -95,7 +95,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -	print "<br>";
    +	print '<br><div id="newattrib"></div>';
     	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -114,6 +114,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/admin/user_extrafields.php b/htdocs/user/admin/user_extrafields.php
    index bf704af2003..81dc7c290c1 100644
    --- a/htdocs/user/admin/user_extrafields.php
    +++ b/htdocs/user/admin/user_extrafields.php
    @@ -81,7 +81,7 @@ dol_fiche_end();
     if ($action != 'create' && $action != 'edit')
     {
     	print '<div class="tabsAction">';
    -	print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute")."</a>";
    +	print "<a class=\"butAction\" href=\"".$_SERVER["PHP_SELF"]."?action=create#newattrib\">".$langs->trans("NewAttribute")."</a>";
     	print "</div>";
     }
     
    @@ -94,7 +94,7 @@ if ($action != 'create' && $action != 'edit')
     
     if ($action == 'create')
     {
    -	print "<br>";
    +	print '<br><div id="newattrib"></div>';
     	print load_fiche_titre($langs->trans('NewAttribute'));
     
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php';
    @@ -113,6 +113,6 @@ if ($action == 'edit' && ! empty($attrname))
         require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php';
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/agenda_extsites.php b/htdocs/user/agenda_extsites.php
    index 2d94711aae8..2eb2ede000b 100644
    --- a/htdocs/user/agenda_extsites.php
    +++ b/htdocs/user/agenda_extsites.php
    @@ -162,12 +162,17 @@ if ($user->rights->user->user->lire || $user->admin) {
     
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
     
    -print $langs->trans("AgendaExtSitesDesc")."<br>\n";
    +
    +print '<div class="underbanner clearboth"></div>';
    +
    +print '<br>';
    +print '<span class="opacitymedium">'.$langs->trans("AgendaExtSitesDesc")."</span><br>\n";
     print "<br>\n";
     
     $selectedvalue=$conf->global->AGENDA_DISABLE_EXT;
     if ($selectedvalue==1) $selectedvalue=0; else $selectedvalue=1;
     
    +
     print '<div class="div-table-responsive">';
     print "<table class=\"noborder\" width=\"100%\">";
     
    @@ -210,15 +215,15 @@ while ($i <= $MAXAGENDA)
     print '</table>';
     print '</div>';
     
    -dol_fiche_end();
     
     print '<div class="center">';
     print "<input type=\"submit\" id=\"save\" name=\"save\" class=\"button hideifnotset\" value=\"".$langs->trans("Save")."\">";
     print "</div>";
     
    +dol_fiche_end();
    +
     print "</form>\n";
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php
    index 2f9fb787c72..13b555b6d5c 100644
    --- a/htdocs/user/bank.php
    +++ b/htdocs/user/bank.php
    @@ -558,6 +558,6 @@ if ($id && $action == 'edit' && $user->rights->user->user->creer) print '</form>
     
     if ($id && $action == 'create' && $user->rights->user->user->creer) print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/card.php b/htdocs/user/card.php
    index a7282783166..a87438eda95 100644
    --- a/htdocs/user/card.php
    +++ b/htdocs/user/card.php
    @@ -11,8 +11,9 @@
      * Copyright (C) 2013-2016 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
      * Copyright (C) 2015-2017 Jean-François Ferry  <jfefe@aternatik.fr>
      * Copyright (C) 2015      Ari Elbaz (elarifr)  <github@accedinfo.com>
    - * Copyright (C) 2015      Charlie Benke        <charlie@patas-monkey.com>
    + * Copyright (C) 2015-2018 Charlene Benke       <charlie@patas-monkey.com>
      * Copyright (C) 2016      Raphaël Doursenaud   <rdoursenaud@gpcsolutions.fr>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -200,6 +201,8 @@ if (empty($reshook)) {
     			$object->office_fax = GETPOST("office_fax", 'alpha');
     			$object->user_mobile = GETPOST("user_mobile");
     			$object->skype = GETPOST("skype", 'alpha');
    +			$object->twitter = GETPOST("twitter", 'alpha');
    +			$object->facebook = GETPOST("facebook", 'alpha');
     			$object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha'));
     			$object->job = GETPOST("job", 'alpha');
     			$object->signature = GETPOST("signature");
    @@ -219,6 +222,9 @@ if (empty($reshook)) {
     			$dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth'), GETPOST('dateemploymentday'), GETPOST('dateemploymentyear'));
     			$object->dateemployment = $dateemployment;
     
    +			$dateemploymentend = dol_mktime(0, 0, 0, GETPOST('dateemploymentendmonth'), GETPOST('dateemploymentendday'), GETPOST('dateemploymentendyear'));
    +			$object->dateemploymentend = $dateemploymentend;
    +
     			// Fill array 'array_options' with data from add form
     			$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
     			if ($ret < 0) {
    @@ -344,6 +350,8 @@ if (empty($reshook)) {
     				$object->office_fax = GETPOST("office_fax", 'alpha');
     				$object->user_mobile = GETPOST("user_mobile");
     				$object->skype = GETPOST("skype", 'alpha');
    +				$object->twitter = GETPOST("twitter", 'alpha');
    +				$object->facebook = GETPOST("facebook", 'alpha');
     				$object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha'));
     				$object->job = GETPOST("job", 'alpha');
     				$object->signature = GETPOST("signature",'none');
    @@ -361,6 +369,8 @@ if (empty($reshook)) {
     				$object->color = GETPOST("color",'alpha') != '' ? GETPOST("color",'alpha') : '';
     				$dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth','int'), GETPOST('dateemploymentday','int'), GETPOST('dateemploymentyear','int'));
     				$object->dateemployment = $dateemployment;
    +				$dateemploymentend = dol_mktime(0, 0, 0, GETPOST('dateemploymentendmonth','int'), GETPOST('dateemploymentendday','int'), GETPOST('dateemploymentendyear','int'));
    +				$object->dateemploymentend = $dateemploymentend;
     
     				if (! empty($conf->multicompany->enabled))
     				{
    @@ -582,6 +592,8 @@ if (empty($reshook)) {
     					$ldap_fax = $attribute[$conf->global->LDAP_FIELD_FAX];
     					$ldap_mobile = $attribute[$conf->global->LDAP_FIELD_MOBILE];
     					$ldap_skype = $attribute[$conf->global->LDAP_FIELD_SKYPE];
    +					$ldap_twitter = $attribute[$conf->global->LDAP_FIELD_TWITTER];
    +					$ldap_facebook = $attribute[$conf->global->LDAP_FIELD_FACEBOOK];
     					$ldap_mail = $attribute[$conf->global->LDAP_FIELD_MAIL];
     					$ldap_sid = $attribute[$conf->global->LDAP_FIELD_SID];
     				}
    @@ -684,7 +696,6 @@ if ($action == 'create' || $action == 'adduserldap')
     					}
     					$liste[$key] = $label;
     				}
    -
     			}
     			else
     			{
    @@ -994,7 +1005,7 @@ if ($action == 'create' || $action == 'adduserldap')
     	print '</td></tr>';
     
     	// Skype
    -	if (! empty($conf->skype->enabled))
    +	if (! empty($conf->socialnetworks->enabled))
     	{
     		print '<tr><td>'.$langs->trans("Skype").'</td>';
     		print '<td>';
    @@ -1005,7 +1016,41 @@ if ($action == 'create' || $action == 'adduserldap')
     		}
     		else
     		{
    -			print '<input class="maxwidth200" type="text" name="skype" value="'.GETPOST('skype').'">';
    +			print '<input class="maxwidth200" type="text" name="skype" value="'.GETPOST('skype','alpha').'">';
    +		}
    +		print '</td></tr>';
    +	}
    +
    +	// Twitter
    +	if (! empty($conf->socialnetworks->enabled))
    +	{
    +		print '<tr><td>'.$langs->trans("Twitter").'</td>';
    +		print '<td>';
    +		if (! empty($ldap_twitter))
    +		{
    +			print '<input type="hidden" name="twitter" value="'.$ldap_twitter.'">';
    +			print $ldap_twitter;
    +		}
    +		else
    +		{
    +			print '<input class="maxwidth200" type="text" name="twitter" value="'.GETPOST('twitter','alpha').'">';
    +		}
    +		print '</td></tr>';
    +	}
    +
    +	// Facebook
    +	if (! empty($conf->socialnetworks->enabled))
    +	{
    +		print '<tr><td>'.$langs->trans("Facebook").'</td>';
    +		print '<td>';
    +		if (! empty($ldap_facebook))
    +		{
    +			print '<input type="hidden" name="facebook" value="'.$ldap_facebook.'">';
    +			print $ldap_facebook;
    +		}
    +		else
    +		{
    +			print '<input class="maxwidth200" type="text" name="facebook" value="'.GETPOST('facebook','alpha').'">';
     		}
     		print '</td></tr>';
     	}
    @@ -1153,14 +1198,21 @@ if ($action == 'create' || $action == 'adduserldap')
     	// Date employment
     	print '<tr><td>'.$langs->trans("DateEmployment").'</td>';
     	print '<td>';
    -	echo $form->select_date(GETPOST('dateemployment'),'dateemployment',0,0,1,'form'.'dateemployment',1,0,1);
    +	print $form->selectDate(GETPOST('dateemployment'), 'dateemployment', 0, 0, 1, 'formdateemployment', 1, 0);
    +	print '</td>';
    +	print "</tr>\n";
    +
    +	// Date employment END
    +	print '<tr><td>'.$langs->trans("DateEmploymentEnd").'</td>';
    +	print '<td>';
    +	print $form->selectDate(GETPOST('dateemploymentend'), 'dateemploymentend', 0, 0, 1, 'formdateemploymentend', 1, 0);
     	print '</td>';
     	print "</tr>\n";
     
     	// Date birth
     	print '<tr><td>'.$langs->trans("DateToBirth").'</td>';
     	print '<td>';
    -	echo $form->select_date(GETPOST('birth'),'birth',0,0,1,'createuser',1,0,1);
    +	print $form->selectDate(GETPOST('birth'), 'birth', 0, 0, 1, 'createuser', 1, 0);
     	print '</td>';
     	print "</tr>\n";
     
    @@ -1191,8 +1243,11 @@ else
     		$res=$object->fetch_optionals();
     
     		// Check if user has rights
    -		$object->getrights();
    -		if (empty($object->nb_rights) && $object->statut != 0) setEventMessages($langs->trans('UserHasNoPermissions'), null, 'warnings');
    +		if (empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
    +		{
    +			$object->getrights();
    +			if (empty($object->nb_rights) && $object->statut != 0) setEventMessages($langs->trans('UserHasNoPermissions'), null, 'warnings');
    +		}
     
     		// Connexion ldap
     		// pour recuperer passDoNotExpire et userChangePassNextLogon
    @@ -1327,7 +1382,7 @@ else
     			// Password
     			print '<tr><td>'.$langs->trans("Password").'</td>';
     
    -			print '<td>';
    +			print '<td class="wordbreak">';
     			$valuetoshow='';
     			if (preg_match('/ldap/',$dolibarr_main_authentication))
     			{
    @@ -1503,6 +1558,13 @@ else
     			print '</td>';
     			print "</tr>\n";
     
    +			// Date employment
    +			print '<tr><td>'.$langs->trans("DateEmploymentEnd").'</td>';
    +			print '<td>';
    +			print dol_print_date($object->dateemploymentend);
    +			print '</td>';
    +			print "</tr>\n";
    +
     			// Date of birth
     			print '<tr><td>'.$langs->trans("DateToBirth").'</td>';
     			print '<td>';
    @@ -2172,7 +2234,7 @@ else
     			print '</td></tr>';
     
     			// Skype
    -			if (! empty($conf->skype->enabled))
    +			if (! empty($conf->socialnetworks->enabled))
     			{
     				print '<tr><td>'.$langs->trans("Skype").'</td>';
     				print '<td>';
    @@ -2188,6 +2250,40 @@ else
     				print '</td></tr>';
     			}
     
    +			// Twitter
    +			if (! empty($conf->socialnetworks->enabled))
    +			{
    +				print '<tr><td>'.$langs->trans("Twitter").'</td>';
    +				print '<td>';
    +				if ($caneditfield  && empty($object->ldap_sid))
    +				{
    +					print '<input size="40" type="text" name="twitter" class="flat" value="'.$object->twitter.'">';
    +				}
    +				else
    +				{
    +					print '<input type="hidden" name="twitter" value="'.$object->twitter.'">';
    +					print $object->twitter;
    +				}
    +				print '</td></tr>';
    +			}
    +
    +			// Skype
    +			if (! empty($conf->socialnetworks->enabled))
    +			{
    +				print '<tr><td>'.$langs->trans("Facebook").'</td>';
    +				print '<td>';
    +				if ($caneditfield  && empty($object->ldap_sid))
    +				{
    +					print '<input size="40" type="text" name="facebook" class="flat" value="'.$object->facebook.'">';
    +				}
    +				else
    +				{
    +					print '<input type="hidden" name="facebook" value="'.$object->facebook.'">';
    +					print $object->facebook;
    +				}
    +				print '</td></tr>';
    +			}
    +
     			// EMail
     			print "<tr>".'<td'.(! empty($conf->global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").'</td>';
     			print '<td>';
    @@ -2432,14 +2528,22 @@ else
     			// Date employment
     			print '<tr><td>'.$langs->trans("DateEmployment").'</td>';
     			print '<td>';
    -			echo $form->select_date(GETPOST('dateemployment')?GETPOST('dateemployment'):$object->dateemployment,'dateemployment',0,0,1,'form'.'dateemployment',1,0,1);
    +			print $form->selectDate(GETPOST('dateemployment')?GETPOST('dateemployment'):$object->dateemployment, 'dateemployment', 0, 0, 1, 'formdateemployment', 1, 0);
     			print '</td>';
     			print "</tr>\n";
     
    +			// Date employmentEnd
    +			print '<tr><td>'.$langs->trans("DateEmploymentEnd").'</td>';
    +			print '<td>';
    +			print $form->selectDate(GETPOST('dateemploymentend')?GETPOST('dateemploymentend'):$object->dateemploymentend, 'dateemploymentend', 0, 0, 1, 'formdateemploymentend', 1, 0);
    +			print '</td>';
    +			print "</tr>\n";
    +
    +
     			// Date birth
     			print '<tr><td>'.$langs->trans("DateToBirth").'</td>';
     			print '<td>';
    -			echo $form->select_date(GETPOST('birth')?GETPOST('birth'):$object->birth,'birth',0,0,1,'updateuser',1,0,1);
    +			print $form->selectDate(GETPOST('birth')?GETPOST('birth'):$object->birth, 'birth', 0, 0, 1, 'updateuser', 1, 0);
     			print '</td>';
     			print "</tr>\n";
     
    @@ -2488,7 +2592,6 @@ else
     
     		if (! empty($conf->ldap->enabled) && ! empty($object->ldap_sid)) $ldap->close();
     	}
    -
     }
     
     if (! empty($conf->api->enabled) && ! empty($conf->use_javascript_ajax))
    @@ -2508,5 +2611,6 @@ if (! empty($conf->api->enabled) && ! empty($conf->use_javascript_ajax))
     	print '</script>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php
    index dd4e60e4617..74e30ad3e88 100644
    --- a/htdocs/user/class/api_users.class.php
    +++ b/htdocs/user/class/api_users.class.php
    @@ -32,7 +32,7 @@ class Users extends DolibarrApi
     	 * @var array   $FIELDS     Mandatory fields, checked when create and update object
     	 */
     	static $FIELDS = array(
    -		'login'
    +		'login',
     	);
     
     	/**
    @@ -43,7 +43,8 @@ class Users extends DolibarrApi
     	/**
     	 * Constructor
     	 */
    -	function __construct() {
    +    function __construct()
    +    {
     		global $db, $conf;
     		$this->db = $db;
     		$this->useraccount = new User($this->db);
    @@ -63,7 +64,8 @@ class Users extends DolibarrApi
          * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
     	 * @return  array               Array of User objects
     	 */
    -	function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '') {
    +    function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '')
    +    {
     	    global $db, $conf;
     
     	    $obj_ret = array();
    @@ -136,7 +138,8 @@ class Users extends DolibarrApi
     	 *
     	 * @throws 	RestException
     	 */
    -	function get($id) {
    +    function get($id)
    +    {
     		//if (!DolibarrApiAccess::$user->rights->user->user->lire) {
     			//throw new RestException(401);
     		//}
    @@ -162,7 +165,8 @@ class Users extends DolibarrApi
     	 * @param array $request_data New user data
     	 * @return int
     	 */
    -	function post($request_data = null) {
    +    function post($request_data = null)
    +    {
     	    // check user authorization
     	    //if(! DolibarrApiAccess::$user->rights->user->creer) {
     	    //   throw new RestException(401, "User creation not allowed");
    @@ -194,7 +198,8 @@ class Users extends DolibarrApi
     	 * @param array $request_data   Datas
     	 * @return int
     	 */
    -	function put($id, $request_data = null) {
    +    function put($id, $request_data = null)
    +    {
     		//if (!DolibarrApiAccess::$user->rights->user->user->creer) {
     			//throw new RestException(401);
     		//}
    @@ -231,38 +236,49 @@ class Users extends DolibarrApi
     	 *
     	 * @param   int     $id        User ID
     	 * @param   int     $group     Group ID
    +	 * @param   int     $entity    Entity ID (valid only for superadmin in multicompany transverse mode)
     	 * @return  int                1 if success
          *
     	 * @url	GET {id}/setGroup/{group}
     	 */
    -	function setGroup($id, $group) {
    +    function setGroup($id, $group, $entity = 1)
    +    {
     
     		global $conf;
     
     		//if (!DolibarrApiAccess::$user->rights->user->user->supprimer) {
     			//throw new RestException(401);
     		//}
    -        $result = $this->useraccount->fetch($id);
    -        if (!$result)
    -        {
    -          throw new RestException(404, 'User not found');
    -        }
    +		$result = $this->useraccount->fetch($id);
    +		if (!$result)
    +		{
    +			throw new RestException(404, 'User not found');
    +		}
     
    -        if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user'))
    -        {
    -          throw new RestException(401, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
    -        }
    +		if (!DolibarrApi::_checkAccessToResource('user', $this->useraccount->id, 'user'))
    +		{
    +			throw new RestException(401, 'Access not allowed for login ' . DolibarrApiAccess::$user->login);
    +		}
     
    -        // When using API, action is done on entity of logged user because a user of entity X with permission to create user should not be able to
    -        // hack the security by giving himself permissions on another entity.
    -        $result = $this->useraccount->SetInGroup($group, DolibarrApiAccess::$user->entity > 0 ? DolibarrApiAccess::$user->entity : $conf->entity);
    -        if (! ($result > 0))
    -        {
    -            throw new RestException(500, $this->useraccount->error);
    -        }
    +		if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE) && ! empty(DolibarrApiAccess::$user->admin) && empty(DolibarrApiAccess::$user->entity))
    +		{
    +			$entity = (! empty($entity) ? $entity : $conf->entity);
    +		}
    +		else
    +		{
    +			// When using API, action is done on entity of logged user because a user of entity X with permission to create user should not be able to
    +			// hack the security by giving himself permissions on another entity.
    +			$entity = (DolibarrApiAccess::$user->entity > 0 ? DolibarrApiAccess::$user->entity : $conf->entity);
    +		}
     
    -        return 1;
    -    }
    +		$result = $this->useraccount->SetInGroup($group, $entity);
    +		if (! ($result > 0))
    +		{
    +			throw new RestException(500, $this->useraccount->error);
    +		}
    +
    +		return 1;
    +	}
     
     	/**
     	 * Delete account
    @@ -270,7 +286,8 @@ class Users extends DolibarrApi
     	 * @param   int     $id Account ID
     	 * @return  array
     	 */
    -	function delete($id) {
    +    function delete($id)
    +    {
     		//if (!DolibarrApiAccess::$user->rights->user->user->supprimer) {
     			//throw new RestException(401);
     		//}
    @@ -353,7 +370,8 @@ class Users extends DolibarrApi
     	 * @return  array
     	 * @throws RestException
     	 */
    -	function _validate($data) {
    +    function _validate($data)
    +    {
     		$account = array();
     		foreach (Users::$FIELDS as $field)
     		{
    diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
    index 161cea20e77..d1a8cae636b 100644
    --- a/htdocs/user/class/user.class.php
    +++ b/htdocs/user/class/user.class.php
    @@ -7,10 +7,11 @@
      * Copyright (C) 2005-2017 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2005      Lionel Cousteix      <etm_ltd@tiscali.co.uk>
      * Copyright (C) 2011      Herve Prot           <herve.prot@symeos.com>
    - * Copyright (C) 2013-2014 Philippe Grand       <philippe.grand@atoo-net.com>
    + * Copyright (C) 2013-2018 Philippe Grand       <philippe.grand@atoo-net.com>
      * Copyright (C) 2013-2015 Alexandre Spangaro   <aspangaro.dolibarr@gmail.com>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
    - * Copyright (C) 2018      Nicolas ZABOURI	<info@inovea-conseil.com>
    + * Copyright (C) 2018      charlene Benke       <charlie@patas-monkey.com>
    + * Copyright (C) 2018      Nicolas ZABOURI      <info@inovea-conseil.com>
      *
      * 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
    @@ -39,10 +40,26 @@ require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
      */
     class User extends CommonObject
     {
    +	/**
    +	 * @var string ID to identify managed object
    +	 */
     	public $element='user';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
     	public $table_element='user';
    +
    +	/**
    +	 * @var int Field with ID of parent key if this field has a parent
    +	 */
     	public $fk_element='fk_user';
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
     
     	public $id=0;
     	public $statut;
    @@ -52,10 +69,19 @@ class User extends CommonObject
     	public $gender;
     	public $birth;
     	public $email;
    +
     	public $skype;
    -	public $job;
    +	public $twitter;
    +	public $facebook;
    +
    +	public $job;			// job position
     	public $signature;
    +
    +	/**
    +	 * @var string Address
    +	 */
     	public $address;
    +
     	public $zip;
     	public $town;
     	public $state_id;		// The state/department
    @@ -67,6 +93,10 @@ class User extends CommonObject
     	public $admin;
     	public $login;
     	public $api_key;
    +
    +	/**
    +	 * @var int Entity
    +	 */
     	public $entity;
     
     	//! Clear password in memory
    @@ -93,7 +123,14 @@ class User extends CommonObject
     	public $socid;
     	public $contactid;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_member;
    +
    +	/**
    +	 * @var int User ID
    +	 */
     	public $fk_user;
     
     	public $clicktodial_url;
    @@ -132,18 +169,19 @@ class User extends CommonObject
     	public $color;						// Define background color for user in agenda
     
     	public $dateemployment;			// Define date of employment by company
    +	public $dateemploymentend;		// Define date of employment end by company
     
     	public $default_c_exp_tax_cat;
     	public $default_range;
     
    -	public $fields=array(
    -        	'rowid'=>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'index'=>1, 'position'=>1, 'comment'=>'Id'),
    -        	'lastname'=>array('type'=>'varchar(50)', 'label'=>'Name', 'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object'),
    -        	'firstname'=>array('type'=>'varchar(50)', 'label'=>'Name','enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    -    	);
    +	public $fields = array(
    +        'rowid'=>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'index'=>1, 'position'=>1, 'comment'=>'Id'),
    +        'lastname'=>array('type'=>'varchar(50)', 'label'=>'Name', 'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>20, 'searchall'=>1, 'comment'=>'Reference of object'),
    +        'firstname'=>array('type'=>'varchar(50)', 'label'=>'Name','enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
    +    );
     
     	/**
    -	 *    Constructor de la classe
    +	 *    Constructor of the class
     	 *
     	 *    @param   DoliDb  $db     Database handler
     	 */
    @@ -189,7 +227,8 @@ class User extends CommonObject
     		$login=trim($login);
     
     		// Get user
    -		$sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.signature, u.office_phone, u.office_fax, u.user_mobile,";
    +		$sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.twitter, u.facebook,";
    +		$sql.= " u.signature, u.office_phone, u.office_fax, u.user_mobile,";
     		$sql.= " u.address, u.zip, u.town, u.fk_state as state_id, u.fk_country as country_id,";
     		$sql.= " u.admin, u.login, u.note,";
     		$sql.= " u.pass, u.pass_crypted, u.pass_temp, u.api_key,";
    @@ -208,7 +247,7 @@ class User extends CommonObject
     		$sql.= " u.salaryextra,";
     		$sql.= " u.weeklyhours,";
     		$sql.= " u.color,";
    -		$sql.= " u.dateemployment,";
    +		$sql.= " u.dateemployment, u.dateemploymentend,";
     		$sql.= " u.ref_int, u.ref_ext,";
     		$sql.= " u.default_range, u.default_c_exp_tax_cat,";			// Expense report default mode
     		$sql.= " c.code as country_code, c.label as country,";
    @@ -294,6 +333,8 @@ class User extends CommonObject
     				$this->user_mobile  = $obj->user_mobile;
     				$this->email		= $obj->email;
     				$this->skype		= $obj->skype;
    +				$this->twitter		= $obj->twitter;
    +				$this->facebook		= $obj->facebook;
     				$this->job			= $obj->job;
     				$this->signature	= $obj->signature;
     				$this->admin		= $obj->admin;
    @@ -311,6 +352,7 @@ class User extends CommonObject
     				$this->weeklyhours	= $obj->weeklyhours;
     				$this->color		= $obj->color;
     				$this->dateemployment	= $this->db->jdate($obj->dateemployment);
    +				$this->dateemploymentend = $this->db->jdate($obj->dateemploymentend);
     
     				$this->datec				= $this->db->jdate($obj->datec);
     				$this->datem				= $this->db->jdate($obj->datem);
    @@ -431,7 +473,7 @@ class User extends CommonObject
     	/**
     	 *  Add a right to the user
     	 *
    -	 * 	@param	int		$rid			id of permission to add
    +	 * 	@param	int		$rid			Id of permission to add or 0 to add several permissions
     	 *  @param  string	$allmodule		Add all permissions of module $allmodule
     	 *  @param  string	$allperms		Add all permissions of module $allmodule, subperms $allperms only
     	 *  @param	int		$entity			Entity to use
    @@ -484,8 +526,15 @@ class User extends CommonObject
     			// Where pour la liste des droits a ajouter
     			if (! empty($allmodule))
     			{
    -				$whereforadd="module='".$this->db->escape($allmodule)."'";
    -				if (! empty($allperms)) $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
    +				if ($allmodule == 'allmodules')
    +				{
    +					$whereforadd='allmodules';
    +				}
    +				else
    +				{
    +					$whereforadd="module='".$this->db->escape($allmodule)."'";
    +					if (! empty($allperms))  $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
    +				}
     			}
     		}
     
    @@ -495,8 +544,10 @@ class User extends CommonObject
     			//print "$module-$perms-$subperms";
     			$sql = "SELECT id";
     			$sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
    -			$sql.= " WHERE ".$whereforadd;
    -			$sql.= " AND entity = ".$entity;
    +			$sql.= " WHERE entity = ".$entity;
    +			if (! empty($whereforadd) && $whereforadd != 'allmodules') {
    +				$sql.= " AND ".$whereforadd;
    +			}
     
     			$result=$this->db->query($sql);
     			if ($result)
    @@ -542,7 +593,6 @@ class User extends CommonObject
     			$this->db->commit();
     			return 1;
     		}
    -
     	}
     
     
    @@ -597,8 +647,18 @@ class User extends CommonObject
     		else {
     			// On a demande suppression d'un droit sur la base d'un nom de module ou perms
     			// Where pour la liste des droits a supprimer
    -			if (! empty($allmodule)) $wherefordel="module='".$this->db->escape($allmodule)."'";
    -			if (! empty($allperms))  $wherefordel=" AND perms='".$this->db->escape($allperms)."'";
    +			if (! empty($allmodule))
    +			{
    +				if ($allmodule == 'allmodules')
    +				{
    +					$wherefordel='allmodules';
    +				}
    +				else
    +				{
    +					$wherefordel="module='".$this->db->escape($allmodule)."'";
    +					if (! empty($allperms))  $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
    +				}
    +			}
     		}
     
     		// Suppression des droits selon critere defini dans wherefordel
    @@ -607,8 +667,10 @@ class User extends CommonObject
     			//print "$module-$perms-$subperms";
     			$sql = "SELECT id";
     			$sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
    -			$sql.= " WHERE $wherefordel";
    -			$sql.= " AND entity = ".$entity;
    +			$sql.= " WHERE entity = ".$entity;
    +			if (! empty($wherefordel) && $wherefordel != 'allmodules') {
    +				$sql.= " AND ".$wherefordel;
    +			}
     
     			$result=$this->db->query($sql);
     			if ($result)
    @@ -654,7 +716,6 @@ class User extends CommonObject
     			$this->db->commit();
     			return 1;
     		}
    -
     	}
     
     
    @@ -676,24 +737,28 @@ class User extends CommonObject
     	/**
     	 *	Load permissions granted to user into object user
     	 *
    -	 *	@param  string	$moduletag    Limit permission for a particular module ('' by default means load all permissions)
    +	 *	@param  string	$moduletag		Limit permission for a particular module ('' by default means load all permissions)
    +	 *  @param	int		$forcereload	Force reload of permissions even if they were already loaded (ignore cache)
     	 *	@return	void
     	 *  @see	clearrights, delrights, addrights
     	 */
    -	function getrights($moduletag='')
    +	function getrights($moduletag='', $forcereload=0)
     	{
     		global $conf;
     
    -		if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag])
    +		if (empty($forcereload))
     		{
    -			// Le fichier de ce module est deja charge
    -			return;
    -		}
    +			if ($moduletag && isset($this->_tab_loaded[$moduletag]) && $this->_tab_loaded[$moduletag])
    +			{
    +				// Rights for this module are already loaded, so we leave
    +				return;
    +			}
     
    -		if ($this->all_permissions_are_loaded)
    -		{
    -			// Si les permissions ont deja ete charge pour ce user, on quitte
    -			return;
    +			if ($this->all_permissions_are_loaded)
    +			{
    +				// We already loaded all rights for this user, so we leave
    +				return;
    +			}
     		}
     
     		// Recuperation des droits utilisateurs + recuperation des droits groupes
    @@ -805,7 +870,6 @@ class User extends CommonObject
     						// if we have already define a subperm like this $this->rights->$module->level1->level2 with llx_user_rights, we don't want override level1 because the level2 can be not define on user group
     						if (!is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = 1;
     					}
    -
     				}
     				$i++;
     			}
    @@ -882,6 +946,7 @@ class User extends CommonObject
     	 * Existing categories are left untouch.
     	 *
     	 * @param int[]|int $categories Category or categories IDs
    +     * @return void
     	 */
     	public function setCategories($categories)
     	{
    @@ -1141,6 +1206,7 @@ class User extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Create a user from a contact object. User will be internal but if contact is linked to a third party, user will be external
     	 *
    @@ -1151,6 +1217,7 @@ class User extends CommonObject
     	 */
     	function create_from_contact($contact,$login='',$password='')
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		$error=0;
    @@ -1162,6 +1229,8 @@ class User extends CommonObject
     		$this->gender		= $contact->gender;
     		$this->email		= $contact->email;
     		$this->skype 		= $contact->skype;
    +		$this->twitter 		= $contact->twitter;
    +		$this->facebook		= $contact->facebook;
     		$this->office_phone	= $contact->phone_pro;
     		$this->office_fax	= $contact->fax;
     		$this->user_mobile	= $contact->phone_mobile;
    @@ -1216,9 +1285,9 @@ class User extends CommonObject
     			$this->db->rollback();
     			return $result;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Create a user into database from a member object
     	 *
    @@ -1228,6 +1297,7 @@ class User extends CommonObject
     	 */
     	function create_from_member($member,$login='')
     	{
    +        // phpcs:enable
     		global $conf,$user,$langs;
     
     		// Positionne parametres
    @@ -1292,6 +1362,7 @@ class User extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Assign rights by default
     	 *
    @@ -1299,6 +1370,7 @@ class User extends CommonObject
     	 */
     	function set_default_rights()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$sql = "SELECT id FROM ".MAIN_DB_PREFIX."rights_def";
    @@ -1372,7 +1444,11 @@ class User extends CommonObject
     		$this->office_fax   = trim($this->office_fax);
     		$this->user_mobile  = trim($this->user_mobile);
     		$this->email        = trim($this->email);
    +
     		$this->skype        = trim($this->skype);
    +		$this->twitter      = trim($this->twitter);
    +		$this->facebook     = trim($this->facebook);
    +
     		$this->job    		= trim($this->job);
     		$this->signature    = trim($this->signature);
     		$this->note         = trim($this->note);
    @@ -1384,6 +1460,7 @@ class User extends CommonObject
     		$this->accountancy_code = trim($this->accountancy_code);
     		$this->color 		= empty($this->color)?'':$this->color;
     		$this->dateemployment 	= empty($this->dateemployment)?'':$this->dateemployment;
    +		$this->dateemploymentend = empty($this->dateemploymentend)?'':$this->dateemploymentend;
     
     		// Check parameters
     		if (! empty($conf->global->USER_MAIL_REQUIRED) && ! isValidEMail($this->email))
    @@ -1421,11 +1498,14 @@ class User extends CommonObject
     		$sql.= ", user_mobile = '".$this->db->escape($this->user_mobile)."'";
     		$sql.= ", email = '".$this->db->escape($this->email)."'";
     		$sql.= ", skype = '".$this->db->escape($this->skype)."'";
    +		$sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
    +		$sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
     		$sql.= ", job = '".$this->db->escape($this->job)."'";
     		$sql.= ", signature = '".$this->db->escape($this->signature)."'";
     		$sql.= ", accountancy_code = '".$this->db->escape($this->accountancy_code)."'";
     		$sql.= ", color = '".$this->db->escape($this->color)."'";
     		$sql.= ", dateemployment=".(strval($this->dateemployment)!='' ? "'".$this->db->idate($this->dateemployment)."'" : 'null');
    +		$sql.= ", dateemploymentend=".(strval($this->dateemploymentend)!='' ? "'".$this->db->idate($this->dateemploymentend)."'" : 'null');
     		$sql.= ", note = '".$this->db->escape($this->note)."'";
     		$sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null");
     		$sql.= ", openid = ".($this->openid?"'".$this->db->escape($this->openid)."'":"null");
    @@ -1502,9 +1582,13 @@ class User extends CommonObject
     						$adh->zip=$this->zip;
     						$adh->state_id=$this->state_id;
     						$adh->country_id=$this->country_id;
    -						
    +
     						$adh->email=$this->email;
    +
     						$adh->skype=$this->skype;
    +						$adh->twitter=$this->twitter;
    +						$adh->facebook=$this->facebook;
    +
     						$adh->phone=$this->office_phone;
     						$adh->phone_mobile=$this->user_mobile;
     
    @@ -1552,7 +1636,11 @@ class User extends CommonObject
     						//$tmpobj->societe=(empty($tmpobj->societe) && $this->societe_id ? $this->societe_id : $tmpobj->societe);
     
     						$tmpobj->email=$this->email;
    +
     						$tmpobj->skype=$this->skype;
    +						$tmpobj->twitter=$this->twitter;
    +						$tmpobj->facebook=$this->facebook;
    +
     						$tmpobj->phone_pro=$this->office_phone;
     						$tmpobj->phone_mobile=$this->user_mobile;
     						$tmpobj->fax=$this->office_fax;
    @@ -1622,9 +1710,9 @@ class User extends CommonObject
     			$this->db->rollback();
     			return -2;
     		}
    -
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Mise a jour en base de la date de derniere connexion d'un utilisateur
     	 *	  Fonction appelee lors d'une nouvelle connexion
    @@ -1633,6 +1721,7 @@ class User extends CommonObject
     	 */
     	function update_last_login_date()
     	{
    +        // phpcs:enable
     		$now=dol_now();
     
     		$sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
    @@ -1790,6 +1879,7 @@ class User extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Send new password by email
     	 *
    @@ -1800,7 +1890,8 @@ class User extends CommonObject
     	 */
     	function send_password($user, $password='', $changelater=0)
     	{
    -		global $conf,$langs;
    +        // phpcs:enable
    +		global $conf, $langs;
     		global $dolibarr_main_url_root;
     
     		require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
    @@ -1821,10 +1912,8 @@ class User extends CommonObject
     			$outputlangs=$langs;
     		}
     
    -		$outputlangs->load("main");
    -		$outputlangs->load("errors");
    -		$outputlangs->load("users");
    -		$outputlangs->load("other");
    +		// Load translation files required by the page
    +		$outputlangs->loadLangs(array("main", "errors", "users", "other"));
     
     		$appli=constant('DOL_APPLICATION_TITLE');
     		if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
    @@ -1904,6 +1993,7 @@ class User extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    	Read clicktodial information for user
     	 *
    @@ -1911,6 +2001,7 @@ class User extends CommonObject
     	 */
     	function fetch_clicktodial()
     	{
    +        // phpcs:enable
     		$sql = "SELECT url, login, pass, poste ";
     		$sql.= " FROM ".MAIN_DB_PREFIX."user_clicktodial as u";
     		$sql.= " WHERE u.fk_user = ".$this->id;
    @@ -1940,6 +2031,7 @@ class User extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update clicktodial info
     	 *
    @@ -1947,6 +2039,7 @@ class User extends CommonObject
     	 */
     	function update_clicktodial()
     	{
    +        // phpcs:enable
     		$this->db->begin();
     
     		$sql = "DELETE FROM ".MAIN_DB_PREFIX."user_clicktodial";
    @@ -1979,6 +2072,7 @@ class User extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Add user into a group
     	 *
    @@ -1989,6 +2083,7 @@ class User extends CommonObject
     	 */
     	function SetInGroup($group, $entity, $notrigger=0)
     	{
    +        // phpcs:enable
     		global $conf, $langs, $user;
     
     		$error=0;
    @@ -2039,6 +2134,7 @@ class User extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Remove a user from a group
     	 *
    @@ -2049,6 +2145,7 @@ class User extends CommonObject
     	 */
     	function RemoveFromGroup($group, $entity, $notrigger=0)
     	{
    +        // phpcs:enable
     		global $conf,$langs,$user;
     
     		$error=0;
    @@ -2108,9 +2205,7 @@ class User extends CommonObject
     	 */
     	function getPhotoUrl($width, $height, $cssclass='', $imagesize='')
     	{
    -		$result='';
    -
    -		$result.='<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
    +		$result ='<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
     		$result.=Form::showphoto('userphoto', $this, $width, $height, 0, $cssclass, $imagesize);
     		$result.='</a>';
     
    @@ -2134,10 +2229,12 @@ class User extends CommonObject
     	 */
     	function getNomUrl($withpictoimg=0, $option='', $infologin=0, $notooltip=0, $maxlen=24, $hidethirdpartylogo=0, $mode='',$morecss='', $save_lastsearch_value=-1)
     	{
    -		global $langs, $conf, $db, $hookmanager;
    +		global $langs, $conf, $db, $hookmanager, $user;
     		global $dolibarr_main_authentication, $dolibarr_main_demo;
     		global $menumanager;
     
    +        if(!$user->rights->user->user->lire && $user->id !=$this->id) $option='nolink';
    +
     		if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
     
     		$result=''; $label='';
    @@ -2186,7 +2283,7 @@ class User extends CommonObject
     			$label.= '<br><b>'.$langs->trans("Browser").':</b> '.$conf->browser->name.($conf->browser->version?' '.$conf->browser->version:'').' ('.$_SERVER['HTTP_USER_AGENT'].')';
     			$label.= '<br><b>'.$langs->trans("Layout").':</b> '.$conf->browser->layout;
     			$label.= '<br><b>'.$langs->trans("Screen").':</b> '.$_SESSION['dol_screenwidth'].' x '.$_SESSION['dol_screenheight'];
    -			if (! empty($conf->browser->phone)) $label.= '<br><b>'.$langs->trans("Phone").':</b> '.$conf->browser->phone;
    +			if ($conf->browser->layout == 'phone') $label.= '<br><b>'.$langs->trans("Phone").':</b> '.$langs->trans("Yes");;
     			if (! empty($_SESSION["disablemodules"])) $label.= '<br><b>'.$langs->trans("DisabledModules").':</b> <br>'.join(', ',explode(',',$_SESSION["disablemodules"]));
     		}
     		if ($infologin < 0) $label='';
    @@ -2269,19 +2366,28 @@ class User extends CommonObject
     	 */
     	function getLoginUrl($withpicto=0,$option='')
     	{
    -		global $langs;
    +		global $langs, $user;
     
     		$result='';
     
     		$linkstart = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
     		$linkend='</a>';
     
    +                //Check user's rights to see an other user
    +                if((!$user->rights->user->user->lire && $this->id !=$user->id)) $option='nolink';
    +
     		if ($option == 'xxx')
     		{
     			$linkstart = '<a href="'.DOL_URL_ROOT.'/user/card.php?id='.$this->id.'">';
     			$linkend='</a>';
     		}
     
    +        if ($option == 'nolink')
    +		{
    +			$linkstart = '';
    +			$linkend='';
    +		}
    +
     		$result.=$linkstart;
     		if ($withpicto) $result.=img_object($langs->trans("ShowUser"), 'user', 'class="paddingright"');
     		$result.=$this->login;
    @@ -2300,6 +2406,7 @@ class User extends CommonObject
     		return $this->LibStatut($this->statut,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -2309,43 +2416,44 @@ class User extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     		$langs->load('users');
     
     		if ($mode == 0)
     		{
    -			$prefix='';
     			if ($statut == 1) return $langs->trans('Enabled');
    -			if ($statut == 0) return $langs->trans('Disabled');
    +			elseif ($statut == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($statut == 1) return $langs->trans('Enabled');
    -			if ($statut == 0) return $langs->trans('Disabled');
    +			elseif ($statut == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
    -			if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
    +			elseif ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
    -			if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
    +			elseif ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($statut == 1) return img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"').' '.$langs->trans('Enabled');
    -			if ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
    +			elseif ($statut == 0) return img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($statut == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4','class="pictostatus"');
    -			if ($statut == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
    +			elseif ($statut == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5','class="pictostatus"');
     		}
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
     	 *
    @@ -2357,14 +2465,16 @@ class User extends CommonObject
     	 */
     	function _load_ldap_dn($info,$mode=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$dn='';
     		if ($mode==0) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS].",".$conf->global->LDAP_USER_DN;
    -		if ($mode==1) $dn=$conf->global->LDAP_USER_DN;
    -		if ($mode==2) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS];
    +		elseif ($mode==1) $dn=$conf->global->LDAP_USER_DN;
    +		elseif ($mode==2) $dn=$conf->global->LDAP_KEY_USERS."=".$info[$conf->global->LDAP_KEY_USERS];
     		return $dn;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Initialize the info array (array of LDAP values) that will be used to call LDAP functions
     	 *
    @@ -2372,6 +2482,7 @@ class User extends CommonObject
     	 */
     	function _load_ldap_info()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$info=array();
    @@ -2388,13 +2499,15 @@ class User extends CommonObject
     			'LDAP_FIELD_NAME'		=> 'lastname',
     			'LDAP_FIELD_FIRSTNAME'	=> 'firstname',
     			'LDAP_FIELD_LOGIN'		=> 'login',
    -			'LDAP_FIELD_LOGIN_SAMBA'	=> 'login',
    +			'LDAP_FIELD_LOGIN_SAMBA'=> 'login',
     			'LDAP_FIELD_PHONE'		=> 'office_phone',
     			'LDAP_FIELD_MOBILE'		=> 'user_mobile',
    -			'LDAP_FIELD_FAX'			=> 'office_fax',
    +			'LDAP_FIELD_FAX'		=> 'office_fax',
     			'LDAP_FIELD_MAIL'		=> 'email',
    -			'LDAP_FIELD_SID'			=> 'ldap_sid',
    -			'LDAP_FIELD_SKYPE'		=> 'skype'
    +			'LDAP_FIELD_SID'		=> 'ldap_sid',
    +			'LDAP_FIELD_SKYPE'		=> 'skype',
    +			'LDAP_FIELD_TWITTER'	=> 'twitter',
    +			'LDAP_FIELD_FACEBOOK'	=> 'facebook'
     		);
     
     		// Champs
    @@ -2433,7 +2546,7 @@ class User extends CommonObject
     			if (! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED))		$info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // Create OpenLDAP MD5 password (TODO add type of encryption)
     		}
     		// Set LDAP password if possible
    -		else if ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
    +		elseif ($conf->global->LDAP_SERVER_PROTOCOLVERSION !== '3') // If ldap key is modified and LDAPv3 we use ldap_rename function for avoid lose encrypt password
     		{
     			if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
     			{
    @@ -2446,7 +2559,7 @@ class User extends CommonObject
     				}
     			}
     			// Use $this->pass_indatabase value if exists
    -			else if (! empty($this->pass_indatabase))
    +			elseif (! empty($this->pass_indatabase))
     			{
     				if (! empty($conf->global->LDAP_FIELD_PASSWORD))				$info[$conf->global->LDAP_FIELD_PASSWORD] = $this->pass_indatabase;	// $this->pass_indatabase = mot de passe non crypte
     				if (! empty($conf->global->LDAP_FIELD_PASSWORD_CRYPTED))		$info[$conf->global->LDAP_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass_indatabase, 4); // md5 for OpenLdap TODO add type of encryption
    @@ -2505,7 +2618,9 @@ class User extends CommonObject
     		$this->gender='man';
     		$this->note='This is a note';
     		$this->email='email@specimen.com';
    -		$this->skype='tom.hanson';
    +		$this->skype='skypepseudo';
    +		$this->twitter='twitterpseudo';
    +		$this->facebook='facebookpseudo';
     		$this->office_phone='0999999999';
     		$this->office_fax='0999999998';
     		$this->user_mobile='0999999997';
    @@ -2555,7 +2670,6 @@ class User extends CommonObject
     			}
     
     			$this->db->free($result);
    -
     		}
     		else
     		{
    @@ -2634,6 +2748,7 @@ class User extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Update user using data from the LDAP
     	 *
    @@ -2643,6 +2758,7 @@ class User extends CommonObject
     	 */
     	function update_ldap2dolibarr(&$ldapuser)
     	{
    +        // phpcs:enable
     		// TODO: Voir pourquoi le update met à jour avec toutes les valeurs vide (global $user écrase ?)
     		global $user, $conf;
     
    @@ -2657,6 +2773,8 @@ class User extends CommonObject
     		$this->office_fax=$ldapuser->{$conf->global->LDAP_FIELD_FAX};
     		$this->email=$ldapuser->{$conf->global->LDAP_FIELD_MAIL};
     		$this->skype=$ldapuser->{$conf->global->LDAP_FIELD_SKYPE};
    +		$this->twitter=$ldapuser->{$conf->global->LDAP_FIELD_TWITTER};
    +		$this->facebook=$ldapuser->{$conf->global->LDAP_FIELD_FACEBOOK};
     		$this->ldap_sid=$ldapuser->{$conf->global->LDAP_FIELD_SID};
     
     		$this->job=$ldapuser->{$conf->global->LDAP_FIELD_TITLE};
    @@ -2670,6 +2788,7 @@ class User extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * Return and array with all instanciated first level children users of current user
     	 *
    @@ -2678,6 +2797,7 @@ class User extends CommonObject
     	 */
     	function get_children()
     	{
    +        // phpcs:enable
     		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."user";
     		$sql.= " WHERE fk_user = ".$this->id;
     
    @@ -2707,7 +2827,7 @@ class User extends CommonObject
     	 *
     	 *	@return		int		<0 if KO, >0 if OK
     	 */
    -	private function load_parentof()
    +	private function loadParentOf()
     	{
     		global $conf;
     
    @@ -2719,7 +2839,7 @@ class User extends CommonObject
     		$sql.= " WHERE fk_user <> 0";
     		$sql.= " AND entity IN (".getEntity('user').")";
     
    -		dol_syslog(get_class($this)."::load_parentof", LOG_DEBUG);
    +		dol_syslog(get_class($this)."::loadParentOf", LOG_DEBUG);
     		$resql = $this->db->query($sql);
     		if ($resql)
     		{
    @@ -2736,6 +2856,7 @@ class User extends CommonObject
     		}
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 * 	Reconstruit l'arborescence hierarchique des users sous la forme d'un tableau
     	 *	Set and return this->users that is an array sorted according to tree with arrays of:
    @@ -2751,6 +2872,7 @@ class User extends CommonObject
     	 */
     	function get_full_tree($deleteafterid=0, $filter='')
     	{
    +        // phpcs:enable
     		global $conf, $user;
     		global $hookmanager;
     
    @@ -2760,7 +2882,7 @@ class User extends CommonObject
     		$this->users = array();
     
     		// Init this->parentof that is array(id_son=>id_parent, ...)
    -		$this->load_parentof();
    +		$this->loadParentOf();
     
     		// Init $this->users array
     		$sql = "SELECT DISTINCT u.rowid, u.firstname, u.lastname, u.fk_user, u.fk_soc, u.login, u.email, u.gender, u.admin, u.statut, u.photo, u.entity";	// Distinct reduce pb with old tables with duplicates
    @@ -2879,6 +3001,7 @@ class User extends CommonObject
     		return $childids;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	For user id_user and its childs available in this->users, define property fullpath and fullname.
     	 *  Function called by get_full_tree().
    @@ -2889,6 +3012,7 @@ class User extends CommonObject
     	 */
     	function build_path_from_id_user($id_user,$protection=0)
     	{
    +        // phpcs:enable
     		dol_syslog(get_class($this)."::build_path_from_id_user id_user=".$id_user." protection=".$protection, LOG_DEBUG);
     
     		if (! empty($this->users[$id_user]['fullpath']))
    @@ -2934,13 +3058,14 @@ class User extends CommonObject
     	public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
     	{
     		$tables = array(
    -			'user'
    +			'user',
     		);
     
     		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *      Charge indicateurs this->nb pour le tableau de bord
     	 *
    @@ -2948,6 +3073,7 @@ class User extends CommonObject
     	 */
     	function load_state_board()
     	{
    +        // phpcs:enable
     		global $conf;
     
     		$this->nb=array();
    @@ -2989,7 +3115,7 @@ class User extends CommonObject
     	 */
     	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
     	{
    -		global $conf,$user,$langs;
    +		global $conf, $user, $langs;
     
     		$langs->load("user");
     
    @@ -3011,6 +3137,7 @@ class User extends CommonObject
     		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Return property of user from its id
     	 *
    @@ -3020,6 +3147,7 @@ class User extends CommonObject
     	 */
     	function user_get_property($rowid,$mode)
     	{
    +        // phpcs:enable
     		$user_property='';
     
     		if (empty($rowid)) return '';
    @@ -3108,8 +3236,5 @@ class User extends CommonObject
     			$this->errors[] = $this->db->lasterror();
     			return -1;
     		}
    -
     	}
    -
     }
    -
    diff --git a/htdocs/user/class/userbankaccount.class.php b/htdocs/user/class/userbankaccount.class.php
    index 77385f84179..b1769edea6f 100644
    --- a/htdocs/user/class/userbankaccount.class.php
    +++ b/htdocs/user/class/userbankaccount.class.php
    @@ -206,4 +206,3 @@ class UserBankAccount extends Account
     		return $rib;
     	}
     }
    -
    diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php
    index 2400c855a6d..6f3e333f6f5 100644
    --- a/htdocs/user/class/usergroup.class.php
    +++ b/htdocs/user/class/usergroup.class.php
    @@ -1,11 +1,11 @@
     <?php
    -/* Copyright (c) 2005		Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    - * Copyright (c) 2005-2018	Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (c) 2005-2018	Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2012		Florian Henry		<florian.henry@open-concept.pro>
    - * Copyright (C) 2014		Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2014		Alexis Algoud		<alexis@atm-consulting.fr>
    - * Copyright (C) 2018           Nicolas ZABOURI		<info@inovea-conseil.com>
    +/* Copyright (c) 2005		Rodolphe Quiedeville <rodolphe@quiedeville.org>
    + * Copyright (c) 2005-2018	Laurent Destailleur	 <eldy@users.sourceforge.net>
    + * Copyright (c) 2005-2018	Regis Houssin		 <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012		Florian Henry		 <florian.henry@open-concept.pro>
    + * Copyright (C) 2014		Juanjo Menent		 <jmenent@2byte.es>
    + * Copyright (C) 2014		Alexis Algoud		 <alexis@atm-consulting.fr>
    + * Copyright (C) 2018       Nicolas ZABOURI		 <info@inovea-conseil.com>
      *
      * 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
    @@ -27,7 +27,7 @@
      */
     
     require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
    -if (! empty($conf->ldap->enabled)) require_once (DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    +if (! empty($conf->ldap->enabled)) require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
     
     
     /**
    @@ -35,23 +35,49 @@ if (! empty($conf->ldap->enabled)) require_once (DOL_DOCUMENT_ROOT."/core/class/
      */
     class UserGroup extends CommonObject
     {
    -	public $element='usergroup';
    -	public $table_element='usergroup';
    -	public $ismultientitymanaged = 1;	// 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    -    public $picto='group';
    -	public $entity;		// Entity of group
    -
    -
    -	public $name;			// Name of group
     	/**
    +	 * @var string ID to identify managed object
    +	 */
    +	public $element='usergroup';
    +
    +	/**
    +	 * @var string Name of table without prefix where object is stored
    +	 */
    +	public $table_element='usergroup';
    +
    +	/**
    +	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
    +	 * @var int
    +	 */
    +	public $ismultientitymanaged = 1;
    +
    +    public $picto='group';
    +
    +	/**
    +	 * @var int Entity of group
    +	 */
    +	public $entity;
    +
    +	/**
    +	 * @var string
     	 * @deprecated
     	 * @see name
     	 */
    -	public $nom;			// Name of group
    +	public $nom;
    +
    +	/**
    +	 * @var string name
    +	 */
    +	public $name;			// Name of group
    +
     	public $globalgroup;	// Global group
    +
     	public $datec;			// Creation date of group
    +
     	public $datem;			// Modification date of group
    +
     	public $note;			// Description
    +
     	public $members=array();	// Array of users
     
     	public $nb_rights;					// Number of rights granted to the user
    @@ -308,8 +334,18 @@ class UserGroup extends CommonObject
     		}
     		else {
     			// Where pour la liste des droits a ajouter
    -			if (! empty($allmodule)) $whereforadd="module='".$this->db->escape($allmodule)."'";
    -			if (! empty($allperms))  $whereforadd=" AND perms='".$this->db->escape($allperms)."'";
    +			if (! empty($allmodule))
    +			{
    +				if ($allmodule == 'allmodules')
    +				{
    +					$whereforadd='allmodules';
    +				}
    +				else
    +				{
    +					$whereforadd="module='".$this->db->escape($allmodule)."'";
    +					if (! empty($allperms))  $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
    +				}
    +			}
     		}
     
     		// Ajout des droits de la liste whereforadd
    @@ -318,8 +354,10 @@ class UserGroup extends CommonObject
     			//print "$module-$perms-$subperms";
     			$sql = "SELECT id";
     			$sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
    -			$sql.= " WHERE $whereforadd";
    -			$sql.= " AND entity = ".$entity;
    +			$sql.= " WHERE entity = ".$entity;
    +			if (! empty($whereforadd) && $whereforadd != 'allmodules') {
    +				$sql.= " AND ".$whereforadd;
    +			}
     
     			$result=$this->db->query($sql);
     			if ($result)
    @@ -365,7 +403,6 @@ class UserGroup extends CommonObject
     			$this->db->commit();
     			return 1;
     		}
    -
     	}
     
     
    @@ -422,8 +459,18 @@ class UserGroup extends CommonObject
     		}
     		else {
     			// Where pour la liste des droits a supprimer
    -			if (! empty($allmodule)) $wherefordel="module='".$this->db->escape($allmodule)."'";
    -			if (! empty($allperms))  $wherefordel=" AND perms='".$this->db->escape($allperms)."'";
    +			if (! empty($allmodule))
    +			{
    +				if ($allmodule == 'allmodules')
    +				{
    +					$wherefordel='allmodules';
    +				}
    +				else
    +				{
    +					$wherefordel="module='".$this->db->escape($allmodule)."'";
    +					if (! empty($allperms))  $whereforadd.=" AND perms='".$this->db->escape($allperms)."'";
    +				}
    +			}
     		}
     
     		// Suppression des droits de la liste wherefordel
    @@ -432,8 +479,10 @@ class UserGroup extends CommonObject
     			//print "$module-$perms-$subperms";
     			$sql = "SELECT id";
     			$sql.= " FROM ".MAIN_DB_PREFIX."rights_def";
    -			$sql.= " WHERE $wherefordel";
    -			$sql.= " AND entity = ".$entity;
    +			$sql.= " WHERE entity = ".$entity;
    +			if (! empty($wherefordel) && $wherefordel != 'allmodules') {
    +				$sql.= " AND ".$wherefordel;
    +			}
     
     			$result=$this->db->query($sql);
     			if ($result)
    @@ -479,7 +528,6 @@ class UserGroup extends CommonObject
     			$this->db->commit();
     			return 1;
     		}
    -
     	}
     
     
    @@ -773,6 +821,7 @@ class UserGroup extends CommonObject
     	    return $this->LibStatut(0,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un statut donne
     	 *
    @@ -782,6 +831,7 @@ class UserGroup extends CommonObject
     	 */
     	function LibStatut($statut,$mode=0)
     	{
    +        // phpcs:enable
     	    global $langs;
     	    $langs->load('users');
     	    return '';
    @@ -864,6 +914,7 @@ class UserGroup extends CommonObject
     		return $result;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
     	 *
    @@ -875,6 +926,7 @@ class UserGroup extends CommonObject
     	 */
     	function _load_ldap_dn($info,$mode=0)
     	{
    +        // phpcs:enable
     		global $conf;
     		$dn='';
     		if ($mode==0) $dn=$conf->global->LDAP_KEY_GROUPS."=".$info[$conf->global->LDAP_KEY_GROUPS].",".$conf->global->LDAP_GROUP_DN;
    @@ -884,6 +936,7 @@ class UserGroup extends CommonObject
     	}
     
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *	Initialize the info array (array of LDAP values) that will be used to call LDAP functions
     	 *
    @@ -891,6 +944,7 @@ class UserGroup extends CommonObject
     	 */
     	function _load_ldap_info()
     	{
    +        // phpcs:enable
     		global $conf,$langs;
     
     		$info=array();
    @@ -953,7 +1007,7 @@ class UserGroup extends CommonObject
     	 *  @param      int			$hidedetails    Hide details of lines
     	 *  @param      int			$hidedesc       Hide description
     	 *  @param      int			$hideref        Hide ref
    -         *  @param   null|array  $moreparams     Array to provide more information
    +     *  @param      null|array  $moreparams     Array to provide more information
     	 * 	@return     int         				0 if KO, 1 if OK
     	 */
     	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
    @@ -980,4 +1034,3 @@ class UserGroup extends CommonObject
     		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
     	}
     }
    -
    diff --git a/htdocs/user/clicktodial.php b/htdocs/user/clicktodial.php
    index a6c43e2dc62..918d8c394ca 100644
    --- a/htdocs/user/clicktodial.php
    +++ b/htdocs/user/clicktodial.php
    @@ -213,10 +213,8 @@ if ($id > 0)
         }
     
         print "</div>\n";
    -
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/document.php b/htdocs/user/document.php
    index 2c41c1bf922..decc53a379c 100644
    --- a/htdocs/user/document.php
    +++ b/htdocs/user/document.php
    @@ -141,7 +141,7 @@ if ($object->id)
         print '<div class="fichecenter">';
         print '<div class="underbanner clearboth"></div>';
     
    -	// Construit liste des fichiers
    +	// Build file list
     	$filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview.*\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1);
     	$totalsize=0;
     	foreach($filearray as $key => $file)
    @@ -178,6 +178,6 @@ else
     	accessforbidden('',0,0);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php
    index 47a5a5df9eb..44eef8dfc1f 100644
    --- a/htdocs/user/group/card.php
    +++ b/htdocs/user/group/card.php
    @@ -586,5 +586,6 @@ else
         }
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/group/index.html b/htdocs/user/group/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/user/group/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php
    index bb9d05d59f1..5bc6130a2b6 100644
    --- a/htdocs/user/group/ldap.php
    +++ b/htdocs/user/group/ldap.php
    @@ -212,5 +212,6 @@ else
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/group/list.php b/htdocs/user/group/list.php
    index 946ba132af8..745f9002055 100644
    --- a/htdocs/user/group/list.php
    +++ b/htdocs/user/group/list.php
    @@ -227,6 +227,6 @@ else
         dol_print_error($db);
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/group/perms.php b/htdocs/user/group/perms.php
    index c1f8d1fe5b0..4b4b181cdc8 100644
    --- a/htdocs/user/group/perms.php
    +++ b/htdocs/user/group/perms.php
    @@ -231,7 +231,14 @@ if ($object->id > 0)
         print '<table width="100%" class="noborder">';
         print '<tr class="liste_titre">';
         print '<td>'.$langs->trans("Module").'</td>';
    -    if ($caneditperms) print '<td width="24">&nbsp</td>';
    +    if ($caneditperms)
    +    {
    +    	print '<td align="center" class="nowrap">';
    +    	print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module=allmodules">'.$langs->trans("All")."</a>";
    +    	print '/';
    +    	print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module=allmodules">'.$langs->trans("None")."</a>";
    +    	print '</td>';
    +    }
         print '<td align="center" width="24">&nbsp;</td>';
         print '<td>'.$langs->trans("Permissions").'</td>';
         print '</tr>';
    @@ -342,5 +349,6 @@ if ($object->id > 0)
         dol_fiche_end();
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php
    index 9b2bd34b156..3212fe6fb6e 100644
    --- a/htdocs/user/hierarchy.php
    +++ b/htdocs/user/hierarchy.php
    @@ -206,6 +206,6 @@ jQuery(document).ready(function() {
     </script>';
     */
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/home.php b/htdocs/user/home.php
    index 250bbf62b91..d232c3cf7f1 100644
    --- a/htdocs/user/home.php
    +++ b/htdocs/user/home.php
    @@ -286,6 +286,6 @@ if ($canreadperms)
     //print '</td></tr></table>';
     print '</div></div></div>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/index.html b/htdocs/user/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/user/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/user/info.php b/htdocs/user/info.php
    index 3cecf94543b..bb262804d33 100644
    --- a/htdocs/user/info.php
    +++ b/htdocs/user/info.php
    @@ -93,6 +93,6 @@ print '</div>';
     
     dol_fiche_end();
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php
    index 6b8d0b2502e..fa5e5e023eb 100644
    --- a/htdocs/user/ldap.php
    +++ b/htdocs/user/ldap.php
    @@ -218,5 +218,6 @@ else
     
     print '</table>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/list.php b/htdocs/user/list.php
    index c4664b07fb7..64c63c05426 100644
    --- a/htdocs/user/list.php
    +++ b/htdocs/user/list.php
    @@ -26,6 +26,9 @@
      */
     
     require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
    +if (! empty($conf->categorie->enabled))
    +	require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
     
     if (! $user->rights->user->user->lire && ! $user->admin)
     	accessforbidden();
    @@ -123,6 +126,8 @@ $search_thirdparty=GETPOST('search_thirdparty','alpha');
     $search_supervisor=GETPOST('search_supervisor','intcomma');
     $search_previousconn=GETPOST('search_previousconn','alpha');
     $optioncss = GETPOST('optioncss','alpha');
    +$search_categ = GETPOST("search_categ",'int');
    +$catid = GETPOST('catid','int');
     
     // Default search
     if ($search_statut == '') $search_statut='1';
    @@ -165,6 +170,7 @@ if (empty($reshook))
     		$search_date_creation="";
     		$search_date_update="";
     		$search_array_options=array();
    +        $search_categ=0;
     	}
     }
     
    @@ -173,6 +179,8 @@ if (empty($reshook))
      * View
      */
     
    +$htmlother=new FormOther($db);
    +
     $user2=new User($db);
     
     $buttonviewhierarchy='<form action="'.DOL_URL_ROOT.'/user/hierarchy.php'.(($search_statut != '' && $search_statut >= 0) ? '?search_statut='.$search_statut : '').'" method="POST"><input type="submit" class="button" style="width:120px" name="viewcal" value="'.dol_escape_htmltag($langs->trans("HierarchicView")).'"></form>';
    @@ -193,6 +201,7 @@ $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
     if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user_extrafields as ef on (u.rowid = ef.fk_object)";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid";
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid";
    +if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_user as cu ON u.rowid = cu.fk_user"; // We'll need this table joined to the select in order to filter by categ
     // Add fields from hooks
     $parameters=array();
     $reshook=$hookmanager->executeHooks('printUserListWhere',$parameters);    // Note that $action and $object may have been modified by hook
    @@ -216,6 +225,10 @@ if ($search_accountancy_code != '')  $sql.= natural_search("u.accountancy_code",
     if ($search_email != '')             $sql.= natural_search("u.email", $search_email);
     if ($search_statut != '' && $search_statut >= 0) $sql.= " AND u.statut IN (".$db->escape($search_statut).")";
     if ($sall)                           $sql.= natural_search(array_keys($fieldstosearchall), $sall);
    +if ($catid > 0)     $sql.= " AND cu.fk_categorie = ".$catid;
    +if ($catid == -2)   $sql.= " AND cu.fk_categorie IS NULL";
    +if ($search_categ > 0)   $sql.= " AND cu.fk_categorie = ".$db->escape($search_categ);
    +if ($search_categ == -2) $sql.= " AND cu.fk_categorie IS NULL";
     // Add where from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
     // Add where from hooks
    @@ -268,6 +281,7 @@ if ($search_supervisor > 0) $param.="&search_supervisor=".$search_supervisor;
     if ($search_statut != '') $param.="&search_statut=".$search_statut;
     if ($optioncss != '') $param.='&optioncss='.$optioncss;
     if ($mode != '')      $param.='&mode='.$mode;
    +if ($search_categ > 0) $param.="&search_categ=".urlencode($search_categ);
     // Add $param from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
     
    @@ -296,6 +310,15 @@ $morehtmlright = '<a class="nohover" href="'.DOL_URL_ROOT.'/user/hierarchy.php'.
     
     print_barre_liste($text, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, "", $num, $nbtotalofrecords, 'title_generic', 0, $morehtmlright.' '.$newcardbutton, '', $limit);
     
    +if (! empty($catid))
    +{
    +    print "<div id='ways'>";
    +    $c = new Categorie($db);
    +    $ways = $c->print_all_ways(' &gt; ','user/list.php');
    +    print " &gt; ".$ways[0]."<br>\n";
    +    print "</div><br>";
    +}
    +
     if ($sall)
     {
     	foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    @@ -304,7 +327,29 @@ if ($sall)
     
     $moreforfilter='';
     
    +// Filter on categories
    +if (! empty($conf->categorie->enabled))
    +{
    +    $moreforfilter.='<div class="divsearchfield">';
    +    $moreforfilter.=$langs->trans('Categories'). ': ';
    +    $moreforfilter.=$htmlother->select_categories(Categorie::TYPE_USER,$search_categ,'search_categ',1);
    +    $moreforfilter.='</div>';
    +}
    +
    +$parameters=array();
    +$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters);    // Note that $action and $object may have been modified by hook
    +if (empty($reshook)) $moreforfilter.=$hookmanager->resPrint;
    +else $moreforfilter=$hookmanager->resPrint;
    +
    +if ($moreforfilter)
    +{
    +    print '<div class="liste_titre liste_titre_bydiv centpercent">';
    +    print $moreforfilter;
    +    print '</div>';
    +}
    +
     $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
    +
     $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage);	// This also change content of $arrayfields
     
     
    @@ -629,5 +674,6 @@ print "</form>\n";
     
     $db->free($result);
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/logout.php b/htdocs/user/logout.php
    index ceeaf35fddf..4250465ff09 100644
    --- a/htdocs/user/logout.php
    +++ b/htdocs/user/logout.php
    @@ -42,10 +42,11 @@ if (!empty($_SESSION["dol_authmode"]) && ($_SESSION["dol_authmode"] == 'forceuse
     global $conf, $langs, $user;
     
     // Appel des triggers
    -include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    -$interface=new Interfaces($db);
    -$result=$interface->run_triggers('USER_LOGOUT',$user,$user,$langs,$conf);
    -if ($result < 0) { $error++; }
    +// TODO @deprecated Remove this. Hook must be used, not this trigger.
    +//include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
    +//$interface=new Interfaces($db);
    +//$result=$interface->run_triggers('USER_LOGOUT',$user,$user,$langs,$conf);
    +//if ($result < 0) { $error++; }
     // Fin appel triggers
     
     // Hooks on logout
    @@ -70,13 +71,20 @@ if (GETPOST('dol_no_mouse_hover'))       $url.=(preg_match('/\?/',$url)?'&':'?')
     if (GETPOST('dol_use_jmobile'))          $url.=(preg_match('/\?/',$url)?'&':'?').'dol_use_jmobile=1';
     
     // Destroy session
    -$prefix=dol_getprefix('');
    +/*$prefix=dol_getprefix('');
     $sessionname='DOLSESSID_'.$prefix;
     $sessiontimeout='DOLSESSTIMEOUT_'.$prefix;
     if (! empty($_COOKIE[$sessiontimeout])) ini_set('session.gc_maxlifetime',$_COOKIE[$sessiontimeout]);
     session_name($sessionname);
     session_destroy();
     dol_syslog("End of session ".$sessionname);
    +*/
    +dol_syslog("End of session ".session_id());
    +if (session_status() === PHP_SESSION_ACTIVE)
    +{
    +	session_destroy();
    +}
    +
     
     // Not sure this is required
     unset($_SESSION['dol_login']);
    diff --git a/htdocs/user/note.php b/htdocs/user/note.php
    index 87a6785615e..1cf994db9e9 100644
    --- a/htdocs/user/note.php
    +++ b/htdocs/user/note.php
    @@ -158,6 +158,6 @@ if ($id)
     	print "</form>\n";
     }
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/notify/card.php b/htdocs/user/notify/card.php
    index 9403694faa9..f4e06075e79 100644
    --- a/htdocs/user/notify/card.php
    +++ b/htdocs/user/notify/card.php
    @@ -1,7 +1,7 @@
     <?php
     /* Copyright (C) 2003      Rodolphe Quiedeville <rodolphe@quiedeville.org>
      * Copyright (C) 2004-2014 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2010-2014 Juanjo Menent	<jmenent@2byte.es>
    + * Copyright (C) 2010-2014 Juanjo Menent	    <jmenent@2byte.es>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2016      Abbes Bahfir         <contact@dolibarrpar.com>
      *
    @@ -67,7 +67,7 @@ if ($action == 'add')
     
         if ($actionid <= 0)
         {
    -	    setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Action")), 'errors');
    +	    setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Action")), null, 'errors');
             $error++;
         }
     
    @@ -188,7 +188,7 @@ if ($result > 0)
     
     
         // Add notification form
    -    print_fiche_titre($langs->trans("AddNewNotification"),'','');
    +    print load_fiche_titre($langs->trans("AddNewNotification"),'','');
     
         print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$id.'" method="post">';
         print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    @@ -276,7 +276,7 @@ if ($result > 0)
         }
     
         // List of active notifications
    -    print_fiche_titre($langs->trans("ListOfActiveNotifications").' ('.$num.')','','');
    +    print load_fiche_titre($langs->trans("ListOfActiveNotifications").' ('.$num.')','','');
     
         // Line with titles
         print '<table width="100%" class="noborder">';
    @@ -507,7 +507,6 @@ if ($result > 0)
     }
     else dol_print_error('','RecordNotFound');
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/user/notify/index.html b/htdocs/user/notify/index.html
    new file mode 100644
    index 00000000000..8b137891791
    --- /dev/null
    +++ b/htdocs/user/notify/index.html
    @@ -0,0 +1 @@
    +
    diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php
    index 60f1e23334f..e0e6935bc48 100644
    --- a/htdocs/user/param_ihm.php
    +++ b/htdocs/user/param_ihm.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2005-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2010-2015 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2013	   Florian Henry        <florian.henry@open-concept.pro.com>
    + * Copyright (C) 2018      Ferran Marcet        <fmarcet@2byte.es>
      *
      * 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
    @@ -109,6 +110,12 @@ if (empty($reshook)) {
     				$tabparam["MAIN_SIZE_LISTE_LIMIT"] = '';
     			}
     
    +			if (GETPOST("check_AGENDA_DEFAULT_VIEW") == "on") {
    +				$tabparam["AGENDA_DEFAULT_VIEW"] = $_POST["AGENDA_DEFAULT_VIEW"];
    +			} else {
    +				$tabparam["AGENDA_DEFAULT_VIEW"] = '';
    +			}
    +
     			if (GETPOST("check_MAIN_THEME") == "on") {
     				$tabparam["MAIN_THEME"] = $_POST["main_theme"];
     			} else {
    @@ -137,6 +144,12 @@ if (empty($reshook)) {
     				$tabparam["THEME_ELDY_USE_HOVER"] = 0;
     			}
     
    +			if (GETPOST('check_THEME_ELDY_USE_CHECKED') == 'on') {
    +				$tabparam["THEME_ELDY_USE_CHECKED"] = 1;
    +			} else {
    +				$tabparam["THEME_ELDY_USE_CHECKED"] = 0;
    +			}
    +
     			$result = dol_set_user_param($db, $conf, $object, $tabparam);
     
     			header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
    @@ -216,6 +229,9 @@ if ($action == 'edit')
                     if (jQuery("#check_SIZE_LISTE_LIMIT").prop("checked")) { jQuery("#main_size_liste_limit").removeAttr(\'disabled\'); }
             		else { jQuery("#main_size_liste_limit").attr(\'disabled\',\'disabled\'); }
     
    +                if (jQuery("#check_AGENDA_DEFAULT_VIEW").prop("checked")) { jQuery("#AGENDA_DEFAULT_VIEW").removeAttr(\'disabled\'); }
    +        		else { jQuery("#AGENDA_DEFAULT_VIEW").attr(\'disabled\',\'disabled\'); }
    +
                     if (jQuery("#check_MAIN_THEME").prop("checked")) { jQuery(".themethumbs").removeAttr(\'disabled\'); }
             		else { jQuery(".themethumbs").attr(\'disabled\',\'disabled\'); }
     
    @@ -224,8 +240,9 @@ if ($action == 'edit')
                 }
             	init_myfunc();
             	jQuery("#check_MAIN_LANDING_PAGE").click(function() { init_myfunc(); });
    -            jQuery("#check_SIZE_LISTE_LIMIT").click(function() { init_myfunc(); });
                 jQuery("#check_MAIN_LANG_DEFAULT").click(function() { init_myfunc(); });
    +            jQuery("#check_SIZE_LISTE_LIMIT").click(function() { init_myfunc(); });
    +            jQuery("#check_AGENDA_DEFAULT_VIEW").click(function() { init_myfunc(); });
                 jQuery("#check_MAIN_THEME").click(function() { init_myfunc(); });
                 jQuery("#check_THEME_ELDY_TOPMENU_BACK1").click(function() { init_myfunc(); });
                 jQuery("#check_THEME_ELDY_BACKTITLE1").click(function() { init_myfunc(); });
    @@ -244,7 +261,7 @@ if ($action == 'edit')
         print '<td>';
         print (empty($conf->global->MAIN_LANDING_PAGE)?'':$conf->global->MAIN_LANDING_PAGE);
         print '</td>';
    -    print '<td align="left" class="nowrap" width="20%"><input '.$bc[$var].' name="check_MAIN_LANDING_PAGE" id="check_MAIN_LANDING_PAGE" type="checkbox" '.(! empty($object->conf->MAIN_LANDING_PAGE)?" checked":"");
    +    print '<td class="nowrap" width="20%"><input class="oddeven" name="check_MAIN_LANDING_PAGE" id="check_MAIN_LANDING_PAGE" type="checkbox" '.(! empty($object->conf->MAIN_LANDING_PAGE)?" checked":"");
         print empty($dolibarr_main_demo)?'':' disabled="disabled"';	// Disabled for demo
         print '> '.$langs->trans("UsePersonalValue").'</td>';
         print '<td>';
    @@ -252,28 +269,40 @@ if ($action == 'edit')
         //print info_admin($langs->trans("WarningYouMayLooseAccess"), 0, 0, 0);
         print '</td></tr>';
     
    -    // Langue par defaut
    +    // Language by default
         print '<tr class="oddeven"><td>'.$langs->trans("Language").'</td>';
         print '<td>';
         $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT);
         print $s?$s.' ':'';
         print ($conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT));
         print '</td>';
    -    print '<td align="left" class="nowrap" width="20%"><input '.$bc[$var].' name="check_MAIN_LANG_DEFAULT" id="check_MAIN_LANG_DEFAULT" type="checkbox" '.(! empty($object->conf->MAIN_LANG_DEFAULT)?" checked":"");
    +    print '<td class="nowrap" width="20%"><input class="oddeven" name="check_MAIN_LANG_DEFAULT" id="check_MAIN_LANG_DEFAULT" type="checkbox" '.(! empty($object->conf->MAIN_LANG_DEFAULT)?" checked":"");
         print empty($dolibarr_main_demo)?'':' disabled="disabled"';	// Disabled for demo
         print '> '.$langs->trans("UsePersonalValue").'</td>';
         print '<td>';
         print $formadmin->select_language((! empty($object->conf->MAIN_LANG_DEFAULT)?$object->conf->MAIN_LANG_DEFAULT:''),'main_lang_default',1,null,0,0,(! empty($dolibarr_main_demo)));
         print '</td></tr>';
     
    -    // Taille max des listes
    +    // Max size of lists
         print '<tr class="oddeven"><td>'.$langs->trans("MaxSizeList").'</td>';
         print '<td>'.$conf->global->MAIN_SIZE_LISTE_LIMIT.'</td>';
    -    print '<td align="left" class="nowrap" width="20%"><input '.$bc[$var].' name="check_SIZE_LISTE_LIMIT" id="check_SIZE_LISTE_LIMIT" type="checkbox" '.(! empty($object->conf->MAIN_SIZE_LISTE_LIMIT)?" checked":"");
    +    print '<td class="nowrap" width="20%"><input class="oddeven" name="check_SIZE_LISTE_LIMIT" id="check_SIZE_LISTE_LIMIT" type="checkbox" '.(! empty($object->conf->MAIN_SIZE_LISTE_LIMIT)?" checked":"");
         print empty($dolibarr_main_demo)?'':' disabled="disabled"';	// Disabled for demo
         print '> '.$langs->trans("UsePersonalValue").'</td>';
         print '<td><input class="flat" name="main_size_liste_limit" id="main_size_liste_limit" size="4" value="' . (! empty($object->conf->MAIN_SIZE_LISTE_LIMIT)?$object->conf->MAIN_SIZE_LISTE_LIMIT:'') . '"></td></tr>';
     
    +    // AGENDA_DEFAULT_VIEW
    +    print '<tr class="oddeven">'."\n";
    +    print '<td>'.$langs->trans("AGENDA_DEFAULT_VIEW").'</td>'."\n";
    +    print '<td align="center">&nbsp;</td>'."\n";
    +    print '<td class="nowrap" width="20%"><input class="oddeven" name="check_AGENDA_DEFAULT_VIEW" id="check_AGENDA_DEFAULT_VIEW" type="checkbox" '.(! empty($object->conf->AGENDA_DEFAULT_VIEW)?" checked":"");
    +    print empty($dolibarr_main_demo)?'':' disabled="disabled"';	// Disabled for demo
    +    print '> '.$langs->trans("UsePersonalValue").'</td>';
    +    print '<td>'."\n";
    +    $tmplist=array(''=>'&nbsp;', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser"));
    +    print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, '');
    +    print '</td></tr>'."\n";
    +
         print '</table><br>';
     
         // Theme
    @@ -287,7 +316,6 @@ if ($action == 'edit')
         print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
         print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
         print '</div>';
    -
     }
     else
     {
    @@ -301,12 +329,11 @@ else
         print '<tr class="liste_titre"><td width="25%">'.$langs->trans("Parameter").'</td><td width="25%">'.$langs->trans("DefaultValue").'</td><td>&nbsp;</td><td>'.$langs->trans("PersonalValue").'</td></tr>';
     
         // Landing page
    -
         print '<tr class="oddeven"><td>'.$langs->trans("LandingPage").'</td>';
         print '<td>';
         print (empty($conf->global->MAIN_LANDING_PAGE)?'':$conf->global->MAIN_LANDING_PAGE);
         print '</td>';
    -    print '<td align="left" class="nowrap"><input '.$bc[$var].' name="check_MAIN_LANDING_PAGE" disabled id="check_MAIN_LANDING_PAGE" type="checkbox" '.(! empty($object->conf->MAIN_LANDING_PAGE)?" checked":"");
    +    print '<td class="nowrap"><input class="oddeven" name="check_MAIN_LANDING_PAGE" disabled id="check_MAIN_LANDING_PAGE" type="checkbox" '.(! empty($object->conf->MAIN_LANDING_PAGE)?" checked":"");
         print empty($dolibarr_main_demo)?'':' disabled="disabled"';	// Disabled for demo
         print '> '.$langs->trans("UsePersonalValue").'</td>';
         print '<td>';
    @@ -319,26 +346,35 @@ else
         print '</td></tr>';
     
         // Language
    -
         print '<tr class="oddeven"><td>'.$langs->trans("Language").'</td>';
         print '<td>';
         $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT);
         print ($s?$s.' ':'');
         print (isset($conf->global->MAIN_LANG_DEFAULT) && $conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT));
         print '</td>';
    -    print '<td align="left" class="nowrap"><input '.$bc[$var].' type="checkbox" disabled '.(! empty($object->conf->MAIN_LANG_DEFAULT)?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>';
    +    print '<td class="nowrap"><input class="oddeven" type="checkbox" disabled '.(! empty($object->conf->MAIN_LANG_DEFAULT)?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>';
         print '<td>';
         $s=(isset($object->conf->MAIN_LANG_DEFAULT) ? picto_from_langcode($object->conf->MAIN_LANG_DEFAULT) : '');
         print ($s?$s.' ':'');
         print (isset($object->conf->MAIN_LANG_DEFAULT) && $object->conf->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):(! empty($object->conf->MAIN_LANG_DEFAULT)?$langs->trans("Language_".$object->conf->MAIN_LANG_DEFAULT):''));
         print '</td></tr>';
     
    -
    +	// Max size for lists
         print '<tr class="oddeven"><td>'.$langs->trans("MaxSizeList").'</td>';
         print '<td>'.(! empty($conf->global->MAIN_SIZE_LISTE_LIMIT)?$conf->global->MAIN_SIZE_LISTE_LIMIT:'&nbsp;').'</td>';
    -    print '<td align="left" class="nowrap" width="20%"><input '.$bc[$var].' type="checkbox" disabled '.(! empty($object->conf->MAIN_SIZE_LISTE_LIMIT)?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>';
    +    print '<td class="nowrap" width="20%"><input class="oddeven" type="checkbox" disabled '.(! empty($object->conf->MAIN_SIZE_LISTE_LIMIT)?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>';
         print '<td>' . (! empty($object->conf->MAIN_SIZE_LISTE_LIMIT)?$object->conf->MAIN_SIZE_LISTE_LIMIT:'&nbsp;') . '</td></tr>';
     
    +    // AGENDA_DEFAULT_VIEW
    +    print '<tr class="oddeven">'."\n";
    +    print '<td>'.$langs->trans("AGENDA_DEFAULT_VIEW").'</td>'."\n";
    +    print '<td align="center">&nbsp;</td>'."\n";
    +    print '<td class="nowrap" width="20%"><input class="oddeven" type="checkbox" disabled '.(! empty($object->conf->AGENDA_DEFAULT_VIEW)?" checked":"").'> '.$langs->trans("UsePersonalValue").'</td>';
    +    print '<td>'."\n";
    +    $tmplist=array(''=>'&nbsp;', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser"));
    +    if (! empty($object->conf->AGENDA_DEFAULT_VIEW)) print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, '', 0, 0, 1);
    +    print '</td></tr>'."\n";
    +
         print '</table><br>';
     
     
    @@ -366,7 +402,6 @@ else
         }
     
         print '</div>';
    -
     }
     
     if ($action == 'edit')
    @@ -374,5 +409,6 @@ if ($action == 'edit')
         print '</form>';
     }
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/user/passwordforgotten.php b/htdocs/user/passwordforgotten.php
    index cf13529d23a..26555d6f59e 100644
    --- a/htdocs/user/passwordforgotten.php
    +++ b/htdocs/user/passwordforgotten.php
    @@ -177,11 +177,11 @@ $rowspan=2;
     $urllogo=DOL_URL_ROOT.'/theme/login_logo.png';
     if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('thumbs/'.$mysoc->logo_small);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
     }
     elseif (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo))
     {
    -	$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode($mysoc->logo);
    +	$urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&amp;modulepart=mycompany&amp;file='.urlencode('logos/'.$mysoc->logo);
     	$width=128;
     }
     elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'))
    diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php
    index 574aa44f89d..8b7599f3707 100644
    --- a/htdocs/user/perms.php
    +++ b/htdocs/user/perms.php
    @@ -245,7 +245,7 @@ if ($user->rights->user->user->lire || $user->admin) {
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
     
     
    -//print '<div class="underbanner clearboth"></div>';
    +print '<div class="underbanner clearboth"></div>';
     
     if ($user->admin) print info_admin($langs->trans("WarningOnlyPermissionOfActivatedModules"));
     // Show warning about external users
    @@ -257,10 +257,18 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e
     
     
     print "\n";
    +print '<div class="div-table-responsive">';
     print '<table width="100%" class="noborder">';
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("Module").'</td>';
    -if ($caneditperms) print '<td>&nbsp</td>';
    +if ($caneditperms && empty($objMod->rights_admin_allowed) || empty($object->admin))
    +{
    +	print '<td align="center" class="nowrap">';
    +	print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module=allmodules">'.$langs->trans("All")."</a>";
    +	print '/';
    +	print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module=allmodules">'.$langs->trans("None")."</a>";
    +	print '</td>';
    +}
     print '<td align="center" width="24">&nbsp;</td>';
     print '<td>'.$langs->trans("Permissions").'</td>';
     print '</tr>'."\n";
    @@ -385,6 +393,7 @@ if ($result)
     }
     else dol_print_error($db);
     print '</table>';
    +print '</div>';
     
     $parameters=array();
     $reshook=$hookmanager->executeHooks('insertExtraFooter',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    @@ -393,6 +402,6 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e
     
     dol_fiche_end();
     
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/variants/admin/admin.php b/htdocs/variants/admin/admin.php
    index dc039bf6d5f..43700b281c7 100644
    --- a/htdocs/variants/admin/admin.php
    +++ b/htdocs/variants/admin/admin.php
    @@ -1,6 +1,6 @@
     <?php
    -
    -/* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    +/* Copyright (C) 2016   Marcos García   <marcosgdf@gmail.com>
    + * Copyright (C) 2018   Frédéric France <frederic.france@netlogic.fr>
      *
      * 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
    @@ -31,17 +31,16 @@ if ($_POST) {
     	$value = GETPOST('PRODUIT_ATTRIBUTES_HIDECHILD');
     
     	if (dolibarr_set_const($db, 'PRODUIT_ATTRIBUTES_HIDECHILD', $value, 'chaine', 0, '', $conf->entity)) {
    -		setEventMessage($langs->trans('RecordSaved'));
    +		setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     	} else {
    -		setEventMessage($langs->trans('CoreErrorMessage'), 'errors');
    +		setEventMessages($langs->trans('CoreErrorMessage'), null, 'errors');
     	}
     
            if (dolibarr_set_const($db, 'PRODUIT_ATTRIBUTES_SEPARATOR', GETPOST('PRODUIT_ATTRIBUTES_SEPARATOR'), 'chaine', 0, '', $conf->entity)) {
    -               setEventMessage($langs->trans('RecordSaved'));
    +               setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
            } else {
    -               setEventMessage($langs->trans('CoreErrorMessage'), 'errors');
    +               setEventMessages($langs->trans('CoreErrorMessage'), null, 'errors');
            }
    -
     }
     
     $title = $langs->trans('ModuleSetup').' '.$langs->trans('ProductAttributes');
    @@ -62,16 +61,15 @@ print '<tr class="oddeven"><td>'.$langs->trans('HideProductCombinations').'</td>
     print $form->selectyesno("PRODUIT_ATTRIBUTES_HIDECHILD",$conf->global->PRODUIT_ATTRIBUTES_HIDECHILD,1).'</td></tr>';
     print '<tr class="oddeven"><td>'.$langs->trans('CombinationsSeparator').'</td>';
     if(isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) {
    -       $separator = $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR;
    +    $separator = $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR;
     } else {
    -       $separator = "_";
    +    $separator = "_";
     }
     print '<td align="right"><input size="3" type="text" class="flat" name="PRODUIT_ATTRIBUTES_SEPARATOR" value="'.$separator.'"></td></tr>';
     print '</table>';
     print '<br><div style="text-align: center"><input type="submit" value="'.$langs->trans('Save').'" class="button"></div>';
     print '</form>';
     
    +// End of page
     llxFooter();
    -
     $db->close();
    -
    diff --git a/htdocs/variants/card.php b/htdocs/variants/card.php
    index 547a82d0f63..1f04e5edb87 100644
    --- a/htdocs/variants/card.php
    +++ b/htdocs/variants/card.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    +/* Copyright (C) 2016   Marcos García   <marcosgdf@gmail.com>
    + * Copyright (C) 2018   Frédéric France <frederic.france@netlogic.fr>
      *
      * 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
    @@ -50,9 +51,9 @@ if ($_POST) {
     		$object->label = $label;
     
     		if ($object->update($user) < 1) {
    -			setEventMessage($langs->trans('CoreErrorMessage'), 'errors');
    +			setEventMessages($langs->trans('CoreErrorMessage'), $object->errors, 'errors');
     		} else {
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			header('Location: '.dol_buildpath('/variants/card.php?id='.$id, 2));
     			exit();
     		}
    @@ -77,9 +78,9 @@ if ($_POST) {
     			if (! $error)
     			{
     				if ($objectval->update($user) > 0) {
    -					setEventMessage($langs->trans('RecordSaved'));
    +					setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     				} else {
    -					setEventMessage($langs->trans('CoreErrorMessage'), 'errors');
    +					setEventMessage($langs->trans('CoreErrorMessage'), $objectval->errors, 'errors');
     				}
     			}
     		}
    @@ -87,7 +88,6 @@ if ($_POST) {
     		header('Location: '.dol_buildpath('/variants/card.php?id='.$object->id, 2));
     		exit();
     	}
    -
     }
     
     if ($confirm == 'yes') {
    @@ -99,11 +99,11 @@ if ($confirm == 'yes') {
     
     		if ($res < 1 || ($object->delete() < 1)) {
     			$db->rollback();
    -			setEventMessage($langs->trans('CoreErrorMessage'), 'errors');
    +			setEventMessages($langs->trans('CoreErrorMessage'), $object->errors, 'errors');
     			header('Location: '.dol_buildpath('/variants/card.php?id='.$object->id, 2));
     		} else {
     			$db->commit();
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			header('Location: '.dol_buildpath('/variants/list.php', 2));
     		}
     		exit();
    @@ -113,9 +113,9 @@ if ($confirm == 'yes') {
     		if ($objectval->fetch($valueid) > 0) {
     
     			if ($objectval->delete() < 1) {
    -				setEventMessage($langs->trans('CoreErrorMessage'), 'errors');
    +				setEventMessages($langs->trans('CoreErrorMessage'), $objectval->errors, 'errors');
     			} else {
    -				setEventMessage($langs->trans('RecordSaved'));
    +				setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			}
     
     			header('Location: '.dol_buildpath('/variants/card.php?id='.$object->id, 2));
    @@ -132,11 +132,10 @@ if ($confirm == 'yes') {
     $langs->load('products');
     
     $title = $langs->trans('ProductAttributeName', dol_htmlentities($object->label));
    -$var = false;
     
     llxHeader('', $title);
     
    -//print_fiche_titre($title);
    +//print load_fiche_titre($title);
     
     $h=0;
     $head[$h][0] = DOL_URL_ROOT.'/variants/card.php?id='.$object->id;
    @@ -242,7 +241,7 @@ if ($action == 'edit') { ?>
     
     	<?php
     
    -	print_fiche_titre($langs->trans("PossibleValues"));
    +	print load_fiche_titre($langs->trans("PossibleValues"));
     
     	if ($action == 'edit_value') {
     		print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    @@ -299,5 +298,6 @@ if ($action == 'edit') { ?>
     	<?php
     }
     
    +// End of page
     llxFooter();
    -$db->close();
    +$db->close();;
    diff --git a/htdocs/variants/class/ProductAttribute.class.php b/htdocs/variants/class/ProductAttribute.class.php
    index 0fa25cdba6e..bdaaff20988 100644
    --- a/htdocs/variants/class/ProductAttribute.class.php
    +++ b/htdocs/variants/class/ProductAttribute.class.php
    @@ -53,6 +53,11 @@ class ProductAttribute
     	 */
     	public $rang;
     
    +    /**
    +     * Constructor
    +     *
    +     * @param   DoliDB $db     Database handler
    +     */
     	public function __construct(DoliDB $db)
     	{
     		global $conf;
    diff --git a/htdocs/variants/class/ProductAttributeValue.class.php b/htdocs/variants/class/ProductAttributeValue.class.php
    index 9b455851507..2988fd9715e 100644
    --- a/htdocs/variants/class/ProductAttributeValue.class.php
    +++ b/htdocs/variants/class/ProductAttributeValue.class.php
    @@ -52,8 +52,13 @@ class ProductAttributeValue
     	 */
     	public $value;
     
    -	public function __construct(DoliDB $db)
    -	{
    +    /**
    +     * Constructor
    +     *
    +     * @param   DoliDB $db     Database handler
    +     */
    +    public function __construct(DoliDB $db)
    +    {
     		global $conf;
     
     		$this->db = $db;
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 92bba2f70f8..ef9ec4997f3 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -1,6 +1,7 @@
     <?php
     
     /* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    + * Copyright (C) 2018	Juanjo Menent	<jmenent@2byte.es>
      *
      * 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
    @@ -70,7 +71,12 @@ class ProductCombination
     	 */
     	public $entity;
     
    -	public function __construct(DoliDB $db)
    +    /**
    +     * Constructor
    +     *
    +     * @param   DoliDB $db     Database handler
    +     */
    +    public function __construct(DoliDB $db)
     	{
     		global $conf;
     
    @@ -324,6 +330,8 @@ class ProductCombination
     		$child->price_autogen = $parent->price_autogen;
     		$child->weight = $parent->weight + $this->variation_weight;
     		$child->weight_units = $parent->weight_units;
    +		$varlabel = $this->getCombinationLabel($this->fk_product_child);
    +		$child->label = $parent->label.$varlabel;
     
     		if ($child->update($child->id, $user) > 0) {
     
    @@ -332,14 +340,33 @@ class ProductCombination
     
     			// MultiPrix
     			if (! empty($conf->global->PRODUIT_MULTIPRICES)) {
    -				$new_type = $parent->multiprices_base_type[1];
    -				$new_min_price = $parent->multiprices_min[1];
    -				$new_psq = $parent->multiprices_recuperableonly[1];
    +				for ($i=1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++)
    +				{
    +					if ($parent->multiprices[$i] != '') {
    +						$new_type = $parent->multiprices_base_type[$i];
    +						$new_min_price = $parent->multiprices_min[$i];
    +						if ($parent->prices_by_qty_list[$i]) {
    +							$new_psq = 1;
    +						} else {
    +							$new_psq = 0;
    +						}
     
    -				if ($new_type == 'TTC') {
    -					$new_price = $parent->multiprices_ttc[1];
    -				} else {
    -					$new_price = $parent->multiprices[1];
    +						if ($new_type == 'TTC') {
    +							$new_price = $parent->multiprices_ttc[$i];
    +						} else {
    +							$new_price = $parent->multiprices[$i];
    +						}
    +
    +						if ($this->variation_price_percentage) {
    +							if ($new_price != 0) {
    +								$new_price *= 1 + ($this->variation_price / 100);
    +							}
    +						} else {
    +							$new_price += $this->variation_price;
    +						}
    +
    +						$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq);
    +					}
     				}
     			} else {
     				$new_type = $parent->price_base_type;
    @@ -351,15 +378,17 @@ class ProductCombination
     				} else {
     					$new_price = $parent->price;
     				}
    -			}
     
    -			if ($this->variation_price_percentage) {
    -				$new_price *= 1 + ($this->variation_price/100);
    -			} else {
    -				$new_price += $this->variation_price;
    -			}
    +				if ($this->variation_price_percentage) {
    +					if ($new_price != 0) {
    +						$new_price *= 1 + ($this->variation_price / 100);
    +					}
    +				} else {
    +					$new_price += $this->variation_price;
    +				}
     
    -			$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
    +				$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
    +			}
     
     			$this->db->commit();
     
    @@ -629,7 +658,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
     		}
     
     		$db->commit();
    -		return 1;
    +		return $newproduct->id;
     	}
     
     	/**
    @@ -676,4 +705,38 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
     
     		return 1;
     	}
    +
    +	/**
    +	 * Return label for combinations
    +	 * @param 	int 	$prod_child		id of child
    +	 * @return 	string					combination label
    +	 */
    +	public function getCombinationLabel($prod_child)
    +	{
    +		$label = '';
    +		$sql = 'SELECT pav.value AS label';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'product_attribute_combination pac';
    +		$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_attribute_combination2val pac2v ON pac2v.fk_prod_combination=pac.rowid';
    +		$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_attribute_value pav ON pav.rowid=pac2v.fk_prod_attr_val';
    +		$sql.= ' WHERE pac.fk_product_child='.$prod_child;
    +
    +		$resql = $this->db->query($sql);
    +		if ($resql) {
    +			$num = $this->db->num_rows($resql);
    +
    +			$i = 0;
    +
    +			while ($i < $num)
    +			{
    +				$obj = $this->db->fetch_object($resql);
    +
    +				if ($obj->label)
    +				{
    +					$label.=' '.$obj->label;
    +				}
    +				$i++;
    +			}
    +		}
    +		return $label;
    +	}
     }
    diff --git a/htdocs/variants/class/ProductCombination2ValuePair.class.php b/htdocs/variants/class/ProductCombination2ValuePair.class.php
    index 874cedb101a..7332670f684 100644
    --- a/htdocs/variants/class/ProductCombination2ValuePair.class.php
    +++ b/htdocs/variants/class/ProductCombination2ValuePair.class.php
    @@ -52,10 +52,15 @@ class ProductCombination2ValuePair
     	 */
     	public $fk_prod_attr_val;
     
    -	public function __construct(DoliDB $db)
    -	{
    -		$this->db = $db;
    -	}
    +    /**
    +     * Constructor
    +     *
    +     * @param   DoliDB $db     Database handler
    +     */
    +    public function __construct(DoliDB $db)
    +    {
    +        $this->db = $db;
    +    }
     
     	/**
     	 * Translates this class to a human-readable string
    diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php
    index dbc413542c4..79076e8ac50 100644
    --- a/htdocs/variants/combinations.php
    +++ b/htdocs/variants/combinations.php
    @@ -1,6 +1,7 @@
     <?php
    -/* Copyright (C) 2016	Marcos García	      <marcosgdf@gmail.com>
    - * Copyright (C) 2017	Laurent Destailleur   <eldy@users.sourceforge.net>
    +/* Copyright (C) 2016   Marcos García       <marcosgdf@gmail.com>
    + * Copyright (C) 2017   Laurent Destailleur <eldy@users.sourceforge.net>
    + * Copyright (C) 2018   Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -24,10 +25,8 @@ require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'
     require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
     require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination2ValuePair.class.php';
     
    -$langs->load("products");
    -$langs->load("other");
    +$langs->loadLangs(array("products", "other"));
     
    -$var = false;
     $id = GETPOST('id', 'int');
     $valueid = GETPOST('valueid', 'int');
     $ref = GETPOST('ref');
    @@ -104,7 +103,7 @@ if ($_POST) {
             $features = $_SESSION['addvariant_'.$object->id];
     
     		if (!$features) {
    -			setEventMessage($langs->trans('ErrorFieldsRequired'), 'errors');
    +			setEventMessages($langs->trans('ErrorFieldsRequired'), null, 'errors');
     		}
     		else
     		{
    @@ -147,7 +146,7 @@ if ($_POST) {
     				$result = $prodcomb->createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact);
     				if ($result > 0)
     				{
    -					setEventMessage($langs->trans('RecordSaved'));
    +					setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     					unset($_SESSION['addvariant_'.$object->id]);
     
     					$db->commit();
    @@ -211,12 +210,10 @@ if ($_POST) {
     			} else {
     				setEventMessages($langs->trans('CoreErrorMessage'), null, 'errors');
     			}
    -
     		} else {
     			$db->commit();
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     		}
    -
     	}
     	elseif ($valueid > 0) {
     
    @@ -230,7 +227,7 @@ if ($_POST) {
     		$prodcomb->variation_weight = $weight_impact;
     
     		if ($prodcomb->update($user) > 0) {
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2));
     			exit();
     		} else {
    @@ -250,13 +247,13 @@ if ($action === 'confirm_deletecombination') {
     
     		if ($prodcomb->delete($user) > 0 && $prodstatic->fetch($prodcomb->fk_product_child) > 0 && $prodstatic->delete($user) > 0) {
     			$db->commit();
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			header('Location: '.dol_buildpath('/variants/combinations.php?id='.$object->id, 2));
     			exit();
     		}
     
     		$db->rollback();
    -		setEventMessage($langs->trans('ProductCombinationAlreadyUsed'), 'errors');
    +		setEventMessages($langs->trans('ProductCombinationAlreadyUsed'), null, 'errors');
     		$action = '';
     	}
     } elseif ($action === 'edit') {
    @@ -284,14 +281,12 @@ if ($action === 'confirm_deletecombination') {
     				header('Location: '.dol_buildpath('/variants/combinations.php?id='.$prodstatic->id, 2));
     				exit();
     			} else {
    -				setEventMessage($langs->trans('ErrorCopyProductCombinations'), 'errors');
    +				setEventMessages($langs->trans('ErrorCopyProductCombinations'), null, 'errors');
     			}
     		}
    -
     	} else {
    -		setEventMessage($langs->trans('ErrorDestinationProductNotFound'), 'errors');
    +		setEventMessages($langs->trans('ErrorDestinationProductNotFound'), null, 'errors');
     	}
    -
     }
     
     
    @@ -319,6 +314,66 @@ if (! empty($id) || ! empty($ref))
     
         dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1);
     
    +	print '<div class="fichecenter">';
    +
    +	print '<div class="underbanner clearboth"></div>';
    +	print '<table class="border tableforfield" width="100%">';
    +
    +    // TVA
    +    print '<tr><td class="titlefield">' . $langs->trans("DefaultTaxRate") . '</td><td>';
    +
    +    $positiverates='';
    +    if (price2num($object->tva_tx))       $positiverates.=($positiverates?'/':'').price2num($object->tva_tx);
    +    if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx);
    +    if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx);
    +    if (empty($positiverates)) $positiverates='0';
    +    echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr);
    +    /*
    +    if ($object->default_vat_code)
    +    {
    +        print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')';
    +    }
    +    else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/
    +    print '</td></tr>';
    +
    +    // Price
    +    print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    +    if ($object->price_base_type == 'TTC') {
    +        print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
    +    } else {
    +        print price($object->price) . ' ' . $langs->trans($object->price_base_type);
    +    }
    +    print '</td></tr>';
    +
    +    // Price minimum
    +    print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    +    if ($object->price_base_type == 'TTC') {
    +        print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
    +    } else {
    +        print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
    +    }
    +    print '</td></tr>';
    +
    +	// Weight
    +	print '<tr><td>'.$langs->trans("Weight").'</td><td>';
    +	if ($object->weight != '')
    +	{
    +		print $object->weight." ".measuring_units_string($object->weight_units,"weight");
    +	}
    +	else
    +	{
    +		print '&nbsp;';
    +	}
    +	print "</td></tr>\n";
    +
    +
    +
    +
    +	print "</table>\n";
    +
    +	print '</div>';
    +	print '<div style="clear:both"></div>';
    +
     	dol_fiche_end();
     
     
    @@ -327,7 +382,7 @@ if (! empty($id) || ! empty($ref))
     
     		if ($action == 'add') {
     			$title = $langs->trans('NewProductCombination');
    -			print dol_fiche_head();
    +			//print dol_fiche_head();
     			$features = $_SESSION['addvariant_'.$object->id];
     			//First, sanitize
     			print '<div id="parttoaddvariant">';
    @@ -348,7 +403,8 @@ if (! empty($id) || ! empty($ref))
     				}
     			}
     			print '</div>';
    -			print dol_fiche_end();
    +			print '<br><br>';
    +			//print dol_fiche_end();
     		} else {
     			$title = $langs->trans('EditProductCombination');
     		}
    @@ -449,7 +505,7 @@ if (! empty($id) || ! empty($ref))
                     if($valueid > 0) {
                         print '<input type="hidden" name="valueid" value="' . $valueid .'">'."\n";
                     }
    -                    
    +
     		print dol_fiche_head();
     
     		?>
    @@ -634,12 +690,14 @@ if (! empty($id) || ! empty($ref))
     		print '<div class="tabsAction">';
     
     		print '	<div class="inline-block divButAction">';
    -		if ($productCombinations) {
    -		    print '<a href="combinations.php?id='.$object->id.'&action=copy" class="butAction">'.$langs->trans('PropagateVariant').'</a>';
    -		}
     
     		print '<a href="combinations.php?id='.$object->id.'&action=add" class="butAction">'.$langs->trans('NewProductCombination').'</a>'; // NewVariant
     
    +		if ($productCombinations)
    +		{
    +			print '<a href="combinations.php?id='.$object->id.'&action=copy" class="butAction">'.$langs->trans('PropagateVariant').'</a>';
    +		}
    +
     		// Too much bugged page.
     		/*
     		print '<a href="generator.php?id='.$object->id.'" class="butAction">'.$langs->trans('ProductCombinationGenerator').'</a>';
    @@ -773,7 +831,6 @@ if (! empty($id) || ! empty($ref))
     	// not found
     }
     
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/variants/create.php b/htdocs/variants/create.php
    index f1a34a835b6..4f2d53bb75f 100644
    --- a/htdocs/variants/create.php
    +++ b/htdocs/variants/create.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    +/* Copyright (C) 2016   Marcos García   <marcosgdf@gmail.com>
    + * Copyright (C) 2018   Frédéric France <frederic.france@netlogic.fr>
      *
      * 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
    @@ -29,7 +30,7 @@ $backtopage = GETPOST('backtopage', 'alpha');
     
     if ($_POST) {
     	if (empty($ref) || empty($label)) {
    -		setEventMessage($langs->trans('ErrorFieldsRequired'), 'errors');
    +		setEventMessages($langs->trans('ErrorFieldsRequired'), null, 'errors');
     	} else {
     
     		$prodattr = new ProductAttribute($db);
    @@ -38,7 +39,7 @@ if ($_POST) {
     
     		$resid = $prodattr->create($user);
     		if ($resid > 0) {
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			if ($backtopage)
     			{
     				header('Location: '.$backtopage);
    @@ -49,7 +50,7 @@ if ($_POST) {
     			}
     			exit;
     		} else {
    -			setEventMessage($langs->trans('ErrorRecordAlreadyExists'), 'errors');
    +			setEventMessages($langs->trans('ErrorRecordAlreadyExists'), $prodattr->errors, 'errors');
     		}
     	}
     }
    @@ -65,7 +66,7 @@ $title = $langs->trans('NewProductAttribute');
     
     llxHeader('', $title);
     
    -print_fiche_titre($title);
    +print load_fiche_titre($title);
     
     dol_fiche_head();
     
    @@ -97,5 +98,6 @@ print '<div class="center"><input type="submit" class="button" value="'.$langs->
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/variants/create_val.php b/htdocs/variants/create_val.php
    index b290182a042..86372df9f59 100644
    --- a/htdocs/variants/create_val.php
    +++ b/htdocs/variants/create_val.php
    @@ -1,5 +1,6 @@
     <?php
     /* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    + * Copyright (C) 2018   Frédéric France <frederic.france@netlogic.fr>
      *
      * 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
    @@ -58,7 +59,7 @@ if ($cancel)
     if ($action == 'add')
     {
     	if (empty($ref) || empty($value)) {
    -		setEventMessage($langs->trans('ErrorFieldsRequired'), 'errors');
    +		setEventMessages($langs->trans('ErrorFieldsRequired'), null, 'errors');
     	} else {
     
     		$objectval->fk_product_attribute = $object->id;
    @@ -66,11 +67,11 @@ if ($action == 'add')
     		$objectval->value = $value;
     
     		if ($objectval->create($user) > 0) {
    -			setEventMessage($langs->trans('RecordSaved'));
    +			setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     			header('Location: '.DOL_URL_ROOT.'/variants/card.php?id='.$object->id);
     			exit();
     		} else {
    -			setEventMessage($langs->trans('ErrorCreatingProductAttributeValue'), 'errors');
    +			setEventMessages($langs->trans('ErrorCreatingProductAttributeValue'), $objectval->errors, 'errors');
     		}
     	}
     }
    @@ -117,7 +118,7 @@ print '<input type="hidden" name="action" value="add">';
     print '<input type="hidden" name="id" value="'.$object->id.'">';
     print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
     
    -print_fiche_titre($langs->trans('NewProductAttributeValue'));
    +print load_fiche_titre($langs->trans('NewProductAttributeValue'));
     
     dol_fiche_head();
     
    @@ -144,5 +145,6 @@ print '</div>';
     
     print '</form>';
     
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/variants/generator.php b/htdocs/variants/generator.php
    index 4daa2d8f45a..420c90147ea 100644
    --- a/htdocs/variants/generator.php
    +++ b/htdocs/variants/generator.php
    @@ -1,6 +1,6 @@
     <?php
    -
    -/* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    +/* Copyright (C) 2016   Marcos García   <marcosgdf@gmail.com>
    + * Copyright (C) 2018   Frédéric France <frederic.france@netlogic.fr>
      *
      * 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
    @@ -24,8 +24,7 @@ require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductAttributeValue.class.php'
     require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
     require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination2ValuePair.class.php';
     
    -$langs->load("products");
    -$langs->load('other');
    +$langs->loadLangs(array("products", "other"));
     
     $id = GETPOST('id', 'int');
     $ref = GETPOST('ref');
    @@ -103,7 +102,7 @@ if ($_POST) {
     
     			$res = 1;
     
    -			foreach (cartesianArray($adapted_values) as $currcomb) 
    +			foreach (cartesianArray($adapted_values) as $currcomb)
     			{
     				$res = $combination->createProductCombination($product, $currcomb, $sanitized_values, $price_var_percent);
     				if ($res < 0) {
    @@ -115,18 +114,17 @@ if ($_POST) {
     
     			if ($res > 0) {
     				$db->commit();
    -				setEventMessage($langs->trans('RecordSaved'));
    +				setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
     				header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2));
     				exit;
     			}
     		} else {
    -			setEventMessage($langs->trans('ErrorDeletingGeneratedProducts'), 'errors');
    +			setEventMessages($langs->trans('ErrorDeletingGeneratedProducts'), null, 'errors');
     		}
     
     		$db->rollback();
    -
     	} else {
    -		setEventMessage($langs->trans('ErrorFieldsRequired'), 'errors');
    +		setEventMessages($langs->trans('ErrorFieldsRequired'), null, 'errors');
     	}
     }
     
    @@ -146,21 +144,21 @@ if (! empty($id) || ! empty($ref)) {
     	{
     		$showbarcode=empty($conf->barcode->enabled)?0:1;
     		if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) $showbarcode=0;
    -		 
    +
     		$head=product_prepare_head($object);
     		$titre=$langs->trans("CardProduct".$object->type);
     		$picto=($object->type== Product::TYPE_SERVICE?'service':'product');
     		dol_fiche_head($head, 'combinations', $titre, 0, $picto);
    -		 
    +
     		$linkback = '<a href="'.DOL_URL_ROOT.'/product/list.php?type='.$object->type.'">'.$langs->trans("BackToList").'</a>';
     		$object->next_prev_filter=" fk_product_type = ".$object->type;
    -		 
    +
     		dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1);
    -		
    +
     		dol_fiche_end();
     	}
     
    -	print_fiche_titre($langs->trans('ProductCombinationGenerator'));
    +	print load_fiche_titre($langs->trans('ProductCombinationGenerator'));
     
     	$dictionary_attr = array();
     
    @@ -374,5 +372,8 @@ if (! empty($id) || ! empty($ref)) {
     
     	<?php
     
    -	llxFooter();
    -}
    \ No newline at end of file
    +  // End of page
    +  llxFooter();
    +}
    +
    +$db->close();
    diff --git a/htdocs/variants/list.php b/htdocs/variants/list.php
    index af859175946..f9420919e91 100644
    --- a/htdocs/variants/list.php
    +++ b/htdocs/variants/list.php
    @@ -50,7 +50,6 @@ if ($action == 'up') {
     
     $langs->load('products');
     
    -$var = false;
     $title = $langs->trans($langs->trans('ProductAttributes'));
     
     $variants = $object->fetchAll();
    @@ -122,7 +121,7 @@ $forcereloadpage=empty($conf->global->MAIN_FORCE_RELOAD_PAGE)?0:1;
     			<th class="liste_titre" colspan="2"></th>
     		</tr>
     		<?php foreach ($variants as $key => $attribute): ?>
    -		<tr id="row-<?php echo $attribute->id ?>" <?php echo $bcdd[$var] ?>>
    +		<tr id="row-<?php echo $attribute->id ?>" class="drag drop oddeven">
     			<td><a href="card.php?id=<?php echo $attribute->id ?>"><?php echo dol_htmlentities($attribute->ref) ?></a></td>
     			<td><a href="card.php?id=<?php echo $attribute->id ?>"><?php echo dol_htmlentities($attribute->label) ?></a></td>
     			<td align="right"><?php echo $attribute->countChildValues() ?></td>
    @@ -143,7 +142,6 @@ $forcereloadpage=empty($conf->global->MAIN_FORCE_RELOAD_PAGE)?0:1;
     			</td>
     		</tr>
     		<?php
    -			$var = !$var;
     			endforeach
     		?>
     
    @@ -151,4 +149,6 @@ $forcereloadpage=empty($conf->global->MAIN_FORCE_RELOAD_PAGE)?0:1;
     
     <?php
     
    -llxFooter();
    \ No newline at end of file
    +// End of page
    +llxFooter();
    +$db->close();
    \ No newline at end of file
    diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php
    index ae2a538ca04..45393d07303 100644
    --- a/htdocs/viewimage.php
    +++ b/htdocs/viewimage.php
    @@ -37,7 +37,8 @@ if (! defined('NOREQUIREHTML'))		define('NOREQUIREHTML','1');
     if (! defined('NOREQUIREAJAX'))		define('NOREQUIREAJAX','1');
     
     // Some value of modulepart can be used to get resources that are public so no login are required.
    -if ((isset($_GET["modulepart"]) && ($_GET["modulepart"] == 'mycompany' || $_GET["modulepart"] == 'companylogo')))
    +// Note that only directory logo is free to access without login.
    +if (isset($_GET["modulepart"]) && $_GET["modulepart"] == 'mycompany' && preg_match('/^\/?logos\//', $_GET['file']))
     {
     	if (! defined("NOLOGIN"))		define("NOLOGIN",1);
     	if (! defined("NOCSRFCHECK"))	define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
    @@ -56,28 +57,32 @@ if ((isset($_GET["modulepart"]) && $_GET["modulepart"] == 'medias'))
     	if (! defined("NOLOGIN"))		define("NOLOGIN",1);
     	if (! defined("NOCSRFCHECK"))	define("NOCSRFCHECK",1);	// We accept to go on this page from external web site.
     	if (! defined("NOIPCHECK"))		define("NOIPCHECK",1);		// Do not check IP defined into conf $dolibarr_main_restrict_ip
    -	// For multicompany
    -	$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
    -	if (is_numeric($entity)) define("DOLENTITY", $entity);
     }
     
    +// For multicompany
    +$entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
    +if (is_numeric($entity)) define("DOLENTITY", $entity);
    +
     /**
      * Header empty
      *
      * @return	void
      */
    -function llxHeader() { }
    +function llxHeader()
    +{
    +}
     /**
      * Footer empty
      *
      * @return	void
      */
    -function llxFooter() { }
    +function llxFooter()
    +{
    +}
     
     require 'main.inc.php';	// Load $user and permissions
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     
    -
     $action=GETPOST('action','alpha');
     $original_file=GETPOST('file','alpha');		// Do not use urldecode here ($_GET are already decoded by PHP).
     $hashp=GETPOST('hashp','aZ09');
    @@ -91,6 +96,7 @@ if (empty($original_file) && empty($hashp) && $modulepart != 'barcode') accessfo
     if ($modulepart == 'fckeditor') $modulepart='medias';   // For backward compatibility
     
     
    +
     /*
      * Actions
      */
    diff --git a/htdocs/webservices/admin/index.php b/htdocs/webservices/admin/index.php
    index e0e549cf2a7..5c49e457c4f 100644
    --- a/htdocs/webservices/admin/index.php
    +++ b/htdocs/webservices/admin/index.php
    @@ -156,6 +156,6 @@ if (! empty($conf->use_javascript_ajax))
     	print '</script>';
     }
     
    -
    +// End of page
     llxFooter();
     $db->close();
    diff --git a/htdocs/webservices/server_actioncomm.php b/htdocs/webservices/server_actioncomm.php
    index a00e014d88a..a9edcb0557a 100644
    --- a/htdocs/webservices/server_actioncomm.php
    +++ b/htdocs/webservices/server_actioncomm.php
    @@ -25,12 +25,12 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once("../master.inc.php");
    -require_once(NUSOAP_PATH.'/nusoap.php');		// Include SOAP
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/ws.lib.php");
    +require "../master.inc.php";
    +require_once NUSOAP_PATH.'/nusoap.php';		// Include SOAP
    +require_once DOL_DOCUMENT_ROOT."/core/lib/ws.lib.php";
     
    -require_once(DOL_DOCUMENT_ROOT."/comm/action/class/actioncomm.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/comm/action/class/cactioncomm.class.php");
    +require_once DOL_DOCUMENT_ROOT."/comm/action/class/actioncomm.class.php";
    +require_once DOL_DOCUMENT_ROOT."/comm/action/class/cactioncomm.class.php";
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
     
    @@ -378,7 +378,6 @@ function getListActionCommType($authentication)
     				 $objectresp = array(
     			    	'result'=>array('result_code'=>'OK', 'result_label'=>''),
     			        'actioncommtypes'=>$resultarray);
    -
     			}
     			else
     			{
    diff --git a/htdocs/webservices/server_category.php b/htdocs/webservices/server_category.php
    index 9ef07dda952..a941c2aceff 100644
    --- a/htdocs/webservices/server_category.php
    +++ b/htdocs/webservices/server_category.php
    @@ -23,10 +23,10 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once("../master.inc.php");
    -require_once(NUSOAP_PATH.'/nusoap.php');		// Include SOAP
    +require "../master.inc.php";
    +require_once NUSOAP_PATH.'/nusoap.php';		// Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
    -require_once(DOL_DOCUMENT_ROOT."/categories/class/categorie.class.php");
    +require_once DOL_DOCUMENT_ROOT."/categories/class/categorie.class.php";
     
     
     dol_syslog("Call Dolibarr webservices interfaces");
    @@ -92,7 +92,7 @@ $server->wsdl->addComplexType(
     /*
      * Les catégories filles, sous tableau dez la catégorie
      */
    - $server->wsdl->addComplexType(
    +$server->wsdl->addComplexType(
         'FillesArray',
         'complexType',
         'array',
    @@ -108,38 +108,38 @@ $server->wsdl->addComplexType(
      /*
       * Image of product
      */
    - $server->wsdl->addComplexType(
    - 		'PhotosArray',
    - 		'complexType',
    - 		'array',
    - 		'sequence',
    - 		'',
    - 		array(
    - 				'image' => array(
    - 						'name' => 'image',
    - 						'type' => 'tns:image',
    - 						'minOccurs' => '0',
    - 						'maxOccurs' => 'unbounded'
    - 				)
    - 		)
    - );
    +$server->wsdl->addComplexType(
    +		'PhotosArray',
    +		'complexType',
    +		'array',
    +		'sequence',
    +		'',
    +		array(
    +				'image' => array(
    +						'name' => 'image',
    +						'type' => 'tns:image',
    +						'minOccurs' => '0',
    +						'maxOccurs' => 'unbounded'
    +				)
    +		)
    +);
     
      /*
       * An image
      */
    - $server->wsdl->addComplexType(
    - 		'image',
    - 		'complexType',
    - 		'struct',
    - 		'all',
    - 		'',
    - 		array(
    - 				'photo' => array('name'=>'photo','type'=>'xsd:string'),
    - 				'photo_vignette' => array('name'=>'photo_vignette','type'=>'xsd:string'),
    - 				'imgWidth' => array('name'=>'imgWidth','type'=>'xsd:string'),
    - 				'imgHeight' => array('name'=>'imgHeight','type'=>'xsd:string')
    - 		)
    - );
    +$server->wsdl->addComplexType(
    +		'image',
    +		'complexType',
    +		'struct',
    +		'all',
    +		'',
    +		array(
    +				'photo' => array('name'=>'photo','type'=>'xsd:string'),
    +				'photo_vignette' => array('name'=>'photo_vignette','type'=>'xsd:string'),
    +				'imgWidth' => array('name'=>'imgWidth','type'=>'xsd:string'),
    +				'imgHeight' => array('name'=>'imgHeight','type'=>'xsd:string')
    +		)
    +);
     
     /*
      * Retour
    @@ -250,9 +250,7 @@ function getCategory($authentication,$id)
     								'dir' => $pdir,
     								'photos' => $fille->liste_photos($dir,$nbmax=10)
     							);
    -
     						}
    -
     					}
     
     			    // Create
    diff --git a/htdocs/webservices/server_contact.php b/htdocs/webservices/server_contact.php
    index 6791864ba8b..9ffde3cdf80 100644
    --- a/htdocs/webservices/server_contact.php
    +++ b/htdocs/webservices/server_contact.php
    @@ -23,11 +23,11 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once("../master.inc.php");
    -require_once(NUSOAP_PATH.'/nusoap.php');		// Include SOAP
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/ws.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/contact/class/contact.class.php");
    -require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
    +require "../master.inc.php";
    +require_once NUSOAP_PATH.'/nusoap.php';		// Include SOAP
    +require_once DOL_DOCUMENT_ROOT."/core/lib/ws.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/contact/class/contact.class.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/extrafields.class.php";
     
     
     dol_syslog("Call Contact webservices interfaces");
    diff --git a/htdocs/webservices/server_invoice.php b/htdocs/webservices/server_invoice.php
    index c93605ab2ea..03931701659 100644
    --- a/htdocs/webservices/server_invoice.php
    +++ b/htdocs/webservices/server_invoice.php
    @@ -23,7 +23,7 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';		// Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
    @@ -635,7 +635,6 @@ function createInvoice($authentication,$invoice)
                 $errorlabel=$new_invoice->error;
                 dol_syslog("Function: createInvoice error while creating".$errorlabel);
             }
    -
         }
     
         if ($error)
    @@ -707,7 +706,6 @@ function createInvoiceFromOrder($authentication,$id_order='', $ref_order='', $re
     						$error++;
     						dol_syslog("Webservice server_invoice:: invoice creation from order failed", LOG_ERR);
     					}
    -
     				}
     			}
     			else
    diff --git a/htdocs/webservices/server_order.php b/htdocs/webservices/server_order.php
    index eb42dd74ce4..d41b2880210 100644
    --- a/htdocs/webservices/server_order.php
    +++ b/htdocs/webservices/server_order.php
    @@ -22,14 +22,13 @@
      *       \brief      File that is entry point to call Dolibarr WebServices
      */
     
    -if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
    +if (! defined("NOCSRFCHECK")) define("NOCSRFCHECK",'1');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
    -
    -require_once(DOL_DOCUMENT_ROOT."/commande/class/commande.class.php");
    +require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php";
     
     
     dol_syslog("Call Dolibarr webservices interfaces");
    @@ -660,7 +659,7 @@ function createOrder($authentication,$order)
     {
     	global $db,$conf,$langs;
     
    -	require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    +	include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
     	$now=dol_now();
     
    @@ -750,7 +749,6 @@ function createOrder($authentication,$order)
     		{
     			dol_syslog("Webservice server_order:: order creation failed", LOG_ERR);
     			$error++;
    -
     		}
     
     		if ($order['status'] == 1)   // We want order to have status validated
    @@ -778,7 +776,6 @@ function createOrder($authentication,$order)
     			$errorcode='KO';
     			$errorlabel=$newobject->error;
     		}
    -
     	}
     
     	if ($error)
    @@ -832,7 +829,6 @@ function validOrder($authentication,$id='',$id_warehouse=0)
     					// Define output language
     					$outputlangs = $langs;
     					$order->generateDocument($order->modelpdf, $outputlangs);
    -
     				}
     				else
     				{
    @@ -849,7 +845,6 @@ function validOrder($authentication,$id='',$id_warehouse=0)
     				$errorcode='KO';
     				$errorlabel=$newobject->error;
     			}
    -
     		}
     		else
     		{
    @@ -858,7 +853,6 @@ function validOrder($authentication,$id='',$id_warehouse=0)
     			$errorcode='KO';
     			$errorlabel=$newobject->error;
     		}
    -
     	}
     
     	if ($error)
    @@ -927,7 +921,6 @@ function updateOrder($authentication,$order)
     						// Define output language
     						$outputlangs = $langs;
     						$object->generateDocument($order->modelpdf, $outputlangs);
    -
     					}
     				}
     				if ($order['status'] == 0)  $result=$object->set_reopen($fuser);
    diff --git a/htdocs/webservices/server_other.php b/htdocs/webservices/server_other.php
    index 8ac519ae87e..895e5d55af4 100644
    --- a/htdocs/webservices/server_other.php
    +++ b/htdocs/webservices/server_other.php
    @@ -22,7 +22,7 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
    diff --git a/htdocs/webservices/server_payment.php b/htdocs/webservices/server_payment.php
    index d6cd261a686..9356b6a558a 100644
    --- a/htdocs/webservices/server_payment.php
    +++ b/htdocs/webservices/server_payment.php
    @@ -27,7 +27,7 @@
     // This is to make Dolibarr working with Plesk
     set_include_path($_SERVER['DOCUMENT_ROOT'].'/htdocs');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';                // Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
    diff --git a/htdocs/webservices/server_productorservice.php b/htdocs/webservices/server_productorservice.php
    index 6094d2e0798..1e301350063 100644
    --- a/htdocs/webservices/server_productorservice.php
    +++ b/htdocs/webservices/server_productorservice.php
    @@ -25,14 +25,14 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
     
     require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
    -require_once(DOL_DOCUMENT_ROOT."/categories/class/categorie.class.php");
    +require_once DOL_DOCUMENT_ROOT."/categories/class/categorie.class.php";
     require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
     
     
    @@ -570,7 +570,7 @@ function createProductOrService($authentication,$product)
             	// Update stock if stock count is provided and differs from database after creation or update
     			if (isset($product['stock_real']) && $product['stock_real'] != '' && ! empty($conf->global->stock->enabled))
     			{
    -				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
    +				include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
     
     				$savstockreal=$newobject->stock_reel;
     				$newobject->load_stock('novirtual,nobatch');		// This overwrite ->stock_reel, surely 0 because we have just created product
    @@ -617,7 +617,6 @@ function createProductOrService($authentication,$product)
                 $errorcode='KO';
                 $errorlabel=$newobject->error;
             }
    -
         }
     
         if ($error)
    @@ -739,7 +738,7 @@ function updateProductOrService($authentication,$product)
             	// Update stock if stock count is provided and differs from database after creation or update
     			if (isset($product['stock_real']) && $product['stock_real'] != '' && ! empty($conf->global->stock->enabled))
     			{
    -				require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
    +				include_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
     
     				$savstockreal=$newobject->stock_reel;
     				$newobject->load_stock('novirtual,nobatch');		// This overwrite ->stock_reel
    @@ -806,7 +805,6 @@ function updateProductOrService($authentication,$product)
                 $errorcode='KO';
                 $errorlabel=$newobject->error;
             }
    -
         }
     
         if ($error)
    @@ -1105,7 +1103,6 @@ function getProductsForCategory($authentication,$id,$lang='')
     
     							$iProduct++;
     						}
    -
     					}
     
     					// Retour
    @@ -1113,14 +1110,12 @@ function getProductsForCategory($authentication,$id,$lang='')
     					'result'=>array('result_code'=>'OK', 'result_label'=>''),
     					'products'=> $products
     					);
    -
     				}
     				else
     				{
     					$errorcode='NORECORDS_FOR_ASSOCIATION'; $errorlabel='No products associated'.$sql;
     					$objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel));
     					dol_syslog("getProductsForCategory:: ".$c->error, LOG_DEBUG);
    -
     				}
     			}
     			else
    diff --git a/htdocs/webservices/server_project.php b/htdocs/webservices/server_project.php
    index bc26de37601..822081011aa 100644
    --- a/htdocs/webservices/server_project.php
    +++ b/htdocs/webservices/server_project.php
    @@ -23,7 +23,7 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    diff --git a/htdocs/webservices/server_supplier_invoice.php b/htdocs/webservices/server_supplier_invoice.php
    index fcfd73270aa..50e5498dbe1 100644
    --- a/htdocs/webservices/server_supplier_invoice.php
    +++ b/htdocs/webservices/server_supplier_invoice.php
    @@ -22,11 +22,10 @@
     
     if (! defined("NOCSRFCHECK"))    define("NOCSRFCHECK",'1');
     
    -require_once '../master.inc.php';
    +require '../master.inc.php';
     require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
    -
     require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
     
     
    diff --git a/htdocs/webservices/server_thirdparty.php b/htdocs/webservices/server_thirdparty.php
    index c2236368d18..7f0b590ee9a 100644
    --- a/htdocs/webservices/server_thirdparty.php
    +++ b/htdocs/webservices/server_thirdparty.php
    @@ -816,7 +816,6 @@ function deleteThirdParty($authentication,$id='',$ref='',$ref_ext='')
     			{
     				$error++;
     				$errorcode='NOT_FOUND'; $errorlabel='Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext;
    -
     			}
     		}
     		else
    diff --git a/htdocs/webservices/server_user.php b/htdocs/webservices/server_user.php
    index 60bf95bd20c..81702c55456 100644
    --- a/htdocs/webservices/server_user.php
    +++ b/htdocs/webservices/server_user.php
    @@ -681,7 +681,8 @@ function createUserFromThirdparty($authentication,$thirdpartywithuser)
      * @param	array		$shortuser			Array of login/password info
      * @return	mixed
      */
    -function setUserPassword($authentication,$shortuser) {
    +function setUserPassword($authentication,$shortuser)
    +{
     
     	global $db,$conf,$langs;
     
    @@ -732,7 +733,6 @@ function setUserPassword($authentication,$shortuser) {
     				$error++;
     				$errorcode='NOT_FOUND'; $errorlabel='User not found';
     			}
    -
     		}
     		else
     		{
    diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php
    index c3d18b889e7..3f51f669829 100644
    --- a/htdocs/website/class/website.class.php
    +++ b/htdocs/website/class/website.class.php
    @@ -1,9 +1,9 @@
     <?php
    -/* Copyright (C) 2007-2012  Laurent Destailleur <eldy@users.sourceforge.net>
    +/* Copyright (C) 2007-2018  Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
      * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) ---Put here your own copyright and developer email---
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * 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
    @@ -39,47 +39,57 @@ class Website extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'website';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'website';
    +
     	/**
     	 * @var array  Does website support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
     	 */
     	public $ismultientitymanaged = 1;
    +
     	/**
     	 * @var string String with name of icon for website. Must be the part after the 'object_' into object_myobject.png
     	 */
     	public $picto = 'globe';
     
     	/**
    -	 * @var int
    +	 * @var int Entity
     	 */
     	public $entity;
    +
     	/**
    -	 * @var string
    +	 * @var string Ref
     	 */
     	public $ref;
    +
     	/**
    -	 * @var string
    +	 * @var string description
     	 */
     	public $description;
    +
     	/**
    -	 * @var int
    +	 * @var int Status
     	 */
     	public $status;
    +
     	/**
     	 * @var mixed
     	 */
     	public $date_creation;
    +
     	/**
     	 * @var mixed
     	 */
     	public $tms = '';
    +
     	/**
     	 * @var integer
     	 */
     	public $fk_default_home;
    +
     	/**
     	 * @var string
     	 */
    @@ -127,11 +137,17 @@ class Website extends CommonObject
     		if (isset($this->status)) {
     			 $this->status = trim($this->status);
     		}
    -		if (empty($this->date_creation)) $this->date_creation = $now;
    -		if (empty($this->date_modification)) $this->date_modification = $now;
    +		if (empty($this->date_creation)) {
    +            $this->date_creation = $now;
    +        }
    +		if (empty($this->date_modification)) {
    +            $this->date_modification = $now;
    +        }
     
     		// Check parameters
    -		if (empty($this->entity)) { $this->entity = $conf->entity; }
    +		if (empty($this->entity)) {
    +            $this->entity = $conf->entity;
    +        }
     
     		// Insert request
     		$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . $this->table_element . '(';
    @@ -141,17 +157,17 @@ class Website extends CommonObject
     		$sql.= 'status,';
     		$sql.= 'fk_default_home,';
     		$sql.= 'virtualhost,';
    -		$sql.= 'fk_user_create,';
    +		$sql.= 'fk_user_creat,';
     		$sql.= 'date_creation,';
     		$sql.= 'tms';
     		$sql .= ') VALUES (';
     		$sql .= ' '.((empty($this->entity) && $this->entity != '0')?'NULL':$this->entity).',';
     		$sql .= ' '.(! isset($this->ref)?'NULL':"'".$this->db->escape($this->ref)."'").',';
     		$sql .= ' '.(! isset($this->description)?'NULL':"'".$this->db->escape($this->description)."'").',';
    -		$sql .= ' '.(! isset($this->status)?'NULL':$this->status).',';
    +		$sql .= ' '.(! isset($this->status)?'1':$this->status).',';
     		$sql .= ' '.(! isset($this->fk_default_home)?'NULL':$this->fk_default_home).',';
     		$sql .= ' '.(! isset($this->virtualhost)?'NULL':"'".$this->db->escape($this->virtualhost)."'").",";
    -		$sql .= ' '.(! isset($this->fk_user_create)?$user->id:$this->fk_user_create).',';
    +		$sql .= ' '.(! isset($this->fk_user_creat)?$user->id:$this->fk_user_creat).',';
     		$sql .= ' '.(! isset($this->date_creation) || dol_strlen($this->date_creation)==0?'NULL':"'".$this->db->idate($this->date_creation)."'").",";
     		$sql .= ' '.(! isset($this->date_modification) || dol_strlen($this->date_modification)==0?'NULL':"'".$this->db->idate($this->date_creation)."'");
     		$sql .= ')';
    @@ -168,16 +184,16 @@ class Website extends CommonObject
     		if (!$error) {
     			$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . $this->table_element);
     
    -			if (!$notrigger) {
    -				// Uncomment this and change MYOBJECT to your own tag if you
    -				// want this action to call a trigger.
    +            // Uncomment this and change MYOBJECT to your own tag if you
    +            // want this action to call a trigger.
    +            // if (!$notrigger) {
     
    -				//// Call triggers
    -				//$result=$this->call_trigger('MYOBJECT_CREATE',$user);
    -				//if ($result < 0) $error++;
    -				//// End call triggers
    -			}
    -		}
    +            //     // Call triggers
    +            //     $result = $this->call_trigger('MYOBJECT_CREATE',$user);
    +            //     if ($result < 0) $error++;
    +            //     // End call triggers
    +            // }
    +        }
     
     		// Commit or rollback
     		if ($error) {
    @@ -210,7 +226,7 @@ class Website extends CommonObject
     		$sql .= " t.status,";
     		$sql .= " t.fk_default_home,";
     		$sql .= " t.virtualhost,";
    -		$sql .= " t.fk_user_create,";
    +		$sql .= " t.fk_user_creat,";
     		$sql .= " t.fk_user_modif,";
     		$sql .= " t.date_creation,";
     		$sql .= " t.tms as date_modification";
    @@ -236,7 +252,7 @@ class Website extends CommonObject
     				$this->status = $obj->status;
     				$this->fk_default_home = $obj->fk_default_home;
     				$this->virtualhost = $obj->virtualhost;
    -				$this->fk_user_create = $obj->fk_user_create;
    +				$this->fk_user_creat = $obj->fk_user_creat;
     				$this->fk_user_modif = $obj->fk_user_modif;
     				$this->date_creation = $this->db->jdate($obj->date_creation);
     				$this->date_modification = $this->db->jdate($obj->date_modification);
    @@ -300,7 +316,7 @@ class Website extends CommonObject
     		$sql .= " t.status,";
     		$sql .= " t.fk_default_home,";
     		$sql .= " t.virtualhost,";
    -		$sql .= " t.fk_user_create,";
    +		$sql .= " t.fk_user_creat,";
     		$sql .= " t.fk_user_modif,";
     		$sql .= " t.date_creation,";
     		$sql .= " t.tms as date_modification";
    @@ -340,7 +356,7 @@ class Website extends CommonObject
     				$line->status = $obj->status;
     				$line->fk_default_home = $obj->fk_default_home;
     				$line->virtualhost = $obj->virtualhost;
    -				$this->fk_user_create = $obj->fk_user_create;
    +				$this->fk_user_creat = $obj->fk_user_creat;
     				$this->fk_user_modif = $obj->fk_user_modif;
     				$line->date_creation = $this->db->jdate($obj->date_creation);
     				$line->date_modification = $this->db->jdate($obj->date_modification);
    @@ -474,6 +490,14 @@ class Website extends CommonObject
     			}
     		}
     
    +		if (! $error && ! empty($this->ref))
    +		{
    +			global $dolibarr_main_data_root;
    +			$pathofwebsite=$dolibarr_main_data_root.'/website/'.$this->ref;
    +
    +			dol_delete_dir_recursive($pathofwebsite);
    +		}
    +
     		// Commit or rollback
     		if ($error) {
     			$this->db->rollback();
    @@ -493,9 +517,10 @@ class Website extends CommonObject
     	 * @param	User	$user		User making the clone
     	 * @param 	int 	$fromid 	Id of object to clone
     	 * @param	string	$newref		New ref
    +	 * @param	string	$newlang	New language
     	 * @return 	mixed 				New object created, <0 if KO
     	 */
    -	public function createFromClone($user, $fromid, $newref)
    +	public function createFromClone($user, $fromid, $newref, $newlang='')
     	{
             global $hookmanager, $langs;
     		global $dolibarr_main_data_root;
    @@ -572,7 +597,7 @@ class Website extends CommonObject
     				dol_delete_file($filetplold);
     
     				// Create new file
    -				$objectpagenew = $objectpageold->createFromClone($user, $pageid, $objectpageold->pageurl, '', 0, $object->id);
    +				$objectpagenew = $objectpageold->createFromClone($user, $pageid, $objectpageold->pageurl, '', 0, $object->id, 1);
     				//print $pageid.' = '.$objectpageold->pageurl.' -> '.$objectpagenew->id.' = '.$objectpagenew->pageurl.'<br>';
     				if (is_object($objectpagenew) && $objectpagenew->pageurl)
     				{
    @@ -613,10 +638,11 @@ class Website extends CommonObject
     		    if (! $error)
     		    {
     		    	$filetpl=$pathofwebsitenew.'/page'.$newidforhome.'.tpl.php';
    +		    	$filewrapper=$pathofwebsitenew.'/wrapper.php';
     
     		    	// Generate the index.php page to be the home page
     		    	//-------------------------------------------------
    -		    	$result = dolSaveIndexPage($pathofwebsitenew, $fileindex, $filetpl);
    +		    	$result = dolSaveIndexPage($pathofwebsitenew, $fileindex, $filetpl, $filewrapper);
     		    }
     		}
     
    @@ -684,6 +710,7 @@ class Website extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un status donne
     	 *
    @@ -693,35 +720,30 @@ class Website extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
    -		if ($mode == 0)
    -		{
    -			$prefix='';
    -			if ($status == 1) return $langs->trans('Enabled');
    -			if ($status == 0) return $langs->trans('Disabled');
    -		}
    -		if ($mode == 1)
    +		if ($mode == 0 || $mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
     			if ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    @@ -747,12 +769,10 @@ class Website extends CommonObject
     		$this->status = '';
     		$this->fk_default_home = null;
     		$this->virtualhost = 'http://myvirtualhost';
    -		$this->fk_user_create = $user->id;
    +		$this->fk_user_creat = $user->id;
     		$this->fk_user_modif = $user->id;
     		$this->date_creation = dol_now();
     		$this->tms = dol_now();
    -
    -
     	}
     
     
    @@ -763,7 +783,7 @@ class Website extends CommonObject
     	 */
     	function exportWebSite()
     	{
    -		global $conf;
    +		global $conf, $mysoc;
     
     		$website = $this;
     
    @@ -781,25 +801,33 @@ class Website extends CommonObject
     			return '';
     		}
     
    -		$srcdir = $conf->website->dir_output.'/'.$website->ref;
    -		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/containers';
    +		$destdir = $conf->website->dir_temp.'/'.$website->ref;
    +
    +		dol_syslog("Clear temp dir ".$destdir);
    +		$count=0; $countreallydeleted=0;
    +		$counttodelete = dol_delete_dir_recursive($destdir, $count, 1, 0, $countreallydeleted);
    +		if ($counttodelete != $countreallydeleted)
    +		{
    +			setEventMessages("Failed to clean temp directory ".$destdir, null, 'errors');
    +			return '';
    +		}
     
     		$arrayreplacement=array();
     
    -		dol_syslog("Clear temp dir ".$destdir);
    -		dol_delete_dir($destdir, 1);
    +		$srcdir = $conf->website->dir_output.'/'.$website->ref;
    +		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/containers';
     
     		dol_syslog("Copy content from ".$srcdir." into ".$destdir);
     		dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacement);
     
     		$srcdir = DOL_DATA_ROOT.'/medias/image/'.$website->ref;
    -		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/image/'.$website->ref;
    +		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/image/websitekey';
     
     		dol_syslog("Copy content from ".$srcdir." into ".$destdir);
     		dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacement);
     
     		$srcdir = DOL_DATA_ROOT.'/medias/js/'.$website->ref;
    -		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/js/'.$website->ref;
    +		$destdir = $conf->website->dir_temp.'/'.$website->ref.'/medias/js/websitekey';
     
     		dol_syslog("Copy content from ".$srcdir." into ".$destdir);
     		dolCopyDir($srcdir, $destdir, 0, 1, $arrayreplacement);
    @@ -844,25 +872,65 @@ class Website extends CommonObject
     		}
     		foreach($listofpages as $pageid => $objectpageold)
     		{
    -			$line = 'INSERT INTO llx_website_page(rowid, fk_page, fk_website, pageurl, title, description, keyword, status, date_creation, tms, lang, import_key, grabbed_from, content)';
    +			$allaliases = $objectpageold->pageurl;
    +			$allaliases.= ($objectpageold->aliasalt ? ','.$objectpageold->aliasalt : '');
    +
    +			$line = '-- Page ID '.$objectpageold->id.' -> '.$objectpageold->newid.'__+MAX_llx_website_page__ - Aliases '.$allaliases.' --;';	// newid start at 1, 2...
    +			$line.= "\n";
    +			fputs($fp, $line);
    +
    +			// Warning: We must keep llx_ here. It is a generic SQL.
    +			$line = 'INSERT INTO llx_website_page(rowid, fk_page, fk_website, pageurl, aliasalt, title, description, keywords, status, date_creation, tms, lang, import_key, grabbed_from, type_container, htmlheader, content)';
     			$line.= " VALUES(";
    -			$line.= $objectpageold->newid."+__MAXROWID__, ";
    -			$line.= ($objectpageold->newfk_page ? $this->db->escape($objectpageold->newfk_page)."+__MAXROWID__" : "null").", ";
    +			$line.= $objectpageold->newid."__+MAX_llx_website_page__, ";
    +			$line.= ($objectpageold->newfk_page ? $this->db->escape($objectpageold->newfk_page)."__+MAX_llx_website_page__" : "null").", ";
     			$line.= "__WEBSITE_ID__, ";
     			$line.= "'".$this->db->escape($objectpageold->pageurl)."', ";
    +			$line.= "'".$this->db->escape($objectpageold->aliasalt)."', ";
     			$line.= "'".$this->db->escape($objectpageold->title)."', ";
     			$line.= "'".$this->db->escape($objectpageold->description)."', ";
    -			$line.= "'".$this->db->escape($objectpageold->keyword)."', ";
    +			$line.= "'".$this->db->escape($objectpageold->keywords)."', ";
     			$line.= "'".$this->db->escape($objectpageold->status)."', ";
     			$line.= "'".$this->db->idate($objectpageold->date_creation)."', ";
     			$line.= "'".$this->db->idate($objectpageold->date_modification)."', ";
     			$line.= "'".$this->db->escape($objectpageold->lang)."', ";
     			$line.= ($objectpageold->import_key ? "'".$this->db->escape($objectpageold->import_key)."'" : "null").", ";
     			$line.= "'".$this->db->escape($objectpageold->grabbed_from)."', ";
    -			$line.= "'".$this->db->escape($objectpageold->content)."'";
    +			$line.= "'".$this->db->escape($objectpageold->type_container)."', ";
    +
    +			$stringtoexport = $objectpageold->htmlheader;
    +			$stringtoexport = str_replace(array("\r\n","\r","\n"), "__N__", $stringtoexport);
    +			$stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport);
    +			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport);
    +			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport);
    +			$line.= "'".$this->db->escape(str_replace(array("\r\n","\r","\n"), "__N__", $stringtoexport))."', ";	// Replace \r \n to have record on 1 line
    +
    +			$stringtoexport = $objectpageold->content;
    +			$stringtoexport = str_replace(array("\r\n","\r","\n"), "__N__", $stringtoexport);
    +			$stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport);
    +			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport);
    +			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport);
    +			$stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport);
    +			$line.= "'".$this->db->escape($stringtoexport)."'";		// Replace \r \n to have record on 1 line
     			$line.= ");";
     			$line.= "\n";
     			fputs($fp, $line);
    +
    +			// Add line to update home page id during import
    +			//var_dump($this->fk_default_home.' - '.$objectpageold->id.' - '.$objectpageold->newid);exit;
    +			if ($this->fk_default_home > 0 && ($objectpageold->id == $this->fk_default_home) && ($objectpageold->newid > 0))	// This is the record with home page
    +			{
    +				$line = "UPDATE llx_website SET fk_default_home = ".($objectpageold->newid > 0 ? $this->db->escape($objectpageold->newid)."__+MAX_llx_website_page__" : "null")." WHERE rowid = __WEBSITE_ID__;";
    +				$line.= "\n";
    +				fputs($fp, $line);
    +			}
     		}
     
     		fclose($fp);
    @@ -870,7 +938,7 @@ class Website extends CommonObject
     			@chmod($filesql, octdec($conf->global->MAIN_UMASK));
     
     		// Build zip file
    -		$filedir  = $conf->website->dir_temp.'/'.$website->ref;
    +		$filedir  = $conf->website->dir_temp.'/'.$website->ref.'/.';
     		$fileglob = $conf->website->dir_temp.'/'.$website->ref.'/website_'.$website->ref.'-*.zip';
     		$filename = $conf->website->dir_temp.'/'.$website->ref.'/website_'.$website->ref.'-'.dol_print_date(dol_now(),'dayhourlog').'.zip';
     
    @@ -889,11 +957,19 @@ class Website extends CommonObject
     	 */
     	function importWebSite($pathtofile)
     	{
    -		global $conf;
    +		global $conf, $mysoc;
     
    -		$result = 0;
    +		$error = 0;
     
    -		$object = new Website($this->db);
    +		$object = $this;
    +		if (empty($object->ref))
    +		{
    +			$this->error = 'Function importWebSite called on object not loaded (object->ref is empty)';
    +			return -1;
    +		}
    +
    +		dol_delete_dir_recursive(dirname($pathtofile).'/'.$object->ref);
    +		dol_mkdir(dirname($pathtofile).'/'.$object->ref);
     
     		$filename = basename($pathtofile);
     		if (! preg_match('/^website_(.*)-(.*)$/', $filename, $reg))
    @@ -902,14 +978,229 @@ class Website extends CommonObject
     			return -1;
     		}
     
    -		$websitecode = $reg[1];
    -
    -		$sql = "INSERT INTO ".MAIN_DB_PREFIX."website(ref, entity, description, status) values('".$websitecode."', ".$conf->entity.", 'Portal to sell your SaaS. Do not remove this entry.', 1)";
    -		$resql = $this->db->query($sql);
    +		$result = dol_uncompress($pathtofile, $conf->website->dir_temp.'/'.$object->ref);
    +		if (! empty($result['error']))
    +		{
    +			$this->errors[]='Failed to unzip file '.$pathtofile.'.';
    +			return -1;
    +		}
     
     
    -		return $result;
    +		dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/containers', $conf->website->dir_output.'/'.$object->ref, 0, 1);	// Overwrite if exists
    +
    +		// Now generate the master.inc.php page
    +		$filemaster=$conf->website->dir_output.'/'.$object->ref.'/master.inc.php';
    +		$result = dolSaveMasterFile($filemaster);
    +		if (! $result)
    +		{
    +			$this->errors[]='Failed to write file '.$filemaster;
    +			$error++;
    +		}
    +
    +		dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/image/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/image/'.$object->ref, 0, 1);	// Medias can be shared, do not overwrite if exists
    +		dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/js/websitekey',    $conf->website->dir_output.'/'.$object->ref.'/medias/js/'.$object->ref, 0, 1);	    // Medias can be shared, do not overwrite if exists
    +
    +		$sqlfile = $conf->website->dir_temp.'/'.$object->ref.'/website_pages.sql';
    +
    +		$arrayreplacement = array();
    +		$arrayreplacement['__WEBSITE_ID__'] = $object->id;
    +		$arrayreplacement['__WEBSITE_KEY__'] = $object->ref;
    +		$arrayreplacement['__N__'] = $this->db->escape("\n");			// Restore \n
    +		$arrayreplacement['__LOGO_SMALL_KEY__'] = $this->db->escape($mysoc->logo_small);
    +		$arrayreplacement['__LOGO_MINI_KEY__'] = $this->db->escape($mysoc->logo_mini);
    +		$arrayreplacement['__LOGO_KEY__'] = $this->db->escape($mysoc->logo);
    +		$result = dolReplaceInFile($sqlfile, $arrayreplacement);
    +
    +		$this->db->begin();
    +
    +		// Search the $maxrowid because we need it later
    +		$sqlgetrowid='SELECT MAX(rowid) as max from '.MAIN_DB_PREFIX.'website_page';
    +		$resql=$this->db->query($sqlgetrowid);
    +		if ($resql)
    +		{
    +			$obj=$this->db->fetch_object($resql);
    +			$maxrowid=$obj->max;
    +		}
    +
    +		// Load sql record
    +		$runsql = run_sql($sqlfile, 1, '', 0, '', 'none', 0, 1);	// The maxrowid of table is searched into this function two
    +		if ($runsql <= 0)
    +		{
    +			$this->errors[]='Failed to load sql file '.$sqlfile;
    +			$error++;
    +		}
    +
    +		$objectpagestatic = new WebsitePage($this->db);
    +
    +		// Make replacement of IDs
    +		$fp = fopen($sqlfile,"r");
    +		if ($fp)
    +		{
    +			while (! feof($fp))
    +			{
    +				// Warning fgets with second parameter that is null or 0 hang.
    +				$buf = fgets($fp, 65000);
    +				if (preg_match('/^-- Page ID (\d+)\s[^\s]+\s(\d+).*Aliases\s(.*)\s--;/i', $buf, $reg))
    +				{
    +					$oldid = $reg[1];
    +					$newid = ($reg[2] + $maxrowid);
    +					$aliasesarray = explode(',', $reg[3]);
    +
    +					$objectpagestatic->fetch($newid);
    +
    +					dol_syslog("Found ID ".$oldid." to replace with ID ".$newid." and shortcut aliases to create: ".$reg[3]);
    +
    +					dol_move($conf->website->dir_output.'/'.$object->ref.'/page'.$oldid.'.tpl.php', $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php', 0, 1, 0, 0);
    +
    +					// The move is not enough, so we regenerate page
    +					$filetpl=$conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php';
    +					dolSavePageContent($filetpl, $object, $objectpagestatic);
    +
    +					// Regenerate alternative aliases pages
    +					foreach($aliasesarray as $aliasshortcuttocreate)
    +					{
    +						$filealias=$conf->website->dir_output.'/'.$object->ref.'/'.$aliasshortcuttocreate.'.php';
    +						dolSavePageAlias($filealias, $object, $objectpagestatic);
    +					}
    +				}
    +			}
    +		}
    +
    +		if ($error)
    +		{
    +			$this->db->rollback();
    +			return -1;
    +		}
    +		else
    +		{
    +			$this->db->commit();
    +			return $object->id;
    +		}
     	}
     
    -}
    +	/**
    +	 * Component to select language inside a container (Full CSS Only)
    +	 *
    +	 * @param	array|string	$languagecodes			'auto' to show all languages available for page, or language codes array like array('en_US','fr_FR','de_DE','es_ES')
    +	 * @param	Translate		$weblangs				Language Object
    +	 * @param	string			$morecss				More CSS class on component
    +	 * @param	string			$htmlname				Suffix for HTML name
    +	 * @return 	string									HTML select component
    +	 */
    +	public function componentSelectLang($languagecodes, $weblangs, $morecss='', $htmlname='')
    +	{
    +		global $websitepagefile, $website;
     
    +		if (! is_object($weblangs)) return 'ERROR componentSelectLang called with parameter $weblangs not defined';
    +
    +		// Load tmppage if we have $websitepagefile defined
    +		$tmppage=new WebsitePage($this->db);
    +
    +		$pageid = 0;
    +		if (! empty($websitepagefile))
    +		{
    +			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +			if ($pageid > 0)
    +			{
    +				$tmppage->fetch($pageid);
    +			}
    +		}
    +
    +		// Fill with existing translation, nothing if none
    +		if (! is_array($languagecodes) && $pageid > 0)
    +		{
    +			$languagecodes = array();
    +
    +			$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    +			$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
    +			$sql.=" WHERE wp.fk_website = ".$website->id;
    +			$sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
    +			if ($tmppage->fk_page > 0) $sql.=" OR wp.fk_page = ".$tmppage->fk_page." OR wp.rowid = ".$tmppage->fk_page;
    +			$sql.=")";
    +
    +			$resql = $this->db->query($sql);
    +			if ($resql)
    +			{
    +				while ($obj = $this->db->fetch_object($resql))
    +				{
    +					$newlang = $obj->lang;
    +					if ($obj->rowid == $pageid) $newlang = $obj->lang;
    +					if (! in_array($newlang, $languagecodes)) $languagecodes[]=$newlang;
    +				}
    +			}
    +		}
    +		// Now $languagecodes is always an array
    +
    +		$languagecodeselected= $weblangs->defaultlang;	// Because we must init with a value, but real value is the lang of main parent container
    +		if (! empty($websitepagefile))
    +		{
    +			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +			if ($pageid > 0)
    +			{
    +
    +				$languagecodeselected=$tmppage->lang;
    +				if (! in_array($tmppage->lang, $languagecodes)) $languagecodes[]=$tmppage->lang;	// We add language code of page into combo list
    +			}
    +		}
    +
    +		$weblangs->load('languages');
    +		//var_dump($weblangs->defaultlang);
    +
    +		$url = $_SERVER["REQUEST_URI"];
    +		$url = preg_replace('/(\?|&)l=([a-zA-Z_]*)/', '', $url);	// We remove param l from url
    +		//$url = preg_replace('/(\?|&)lang=([a-zA-Z_]*)/', '', $url);	// We remove param lang from url
    +		$url.= (preg_match('/\?/', $url) ? '&' : '?').'l=';
    +
    +		$HEIGHTOPTION=40;
    +		$MAXHEIGHT = 4 * $HEIGHTOPTION;
    +		$nboflanguage = count($languagecodes);
    +
    +		$out ='<!-- componentSelectLang'.$htmlname.' -->'."\n";
    +
    +		$out.= '<style>';
    +		$out.= '.componentSelectLang'.$htmlname.':hover { height: '.min($MAXHEIGHT, ($HEIGHTOPTION * $nboflanguage)).'px; overflow-x: hidden; overflow-y: '.((($HEIGHTOPTION * $nboflanguage) > $MAXHEIGHT) ? ' scroll' : 'hidden').'; }'."\n";
    +		$out.= '.componentSelectLang'.$htmlname.' li { line-height: '.$HEIGHTOPTION.'px; }'."\n";
    +		$out.= '.componentSelectLang'.$htmlname.' {
    +			display: inline-block;
    +			padding: 0;
    +			height: '.$HEIGHTOPTION.'px;
    +			overflow: hidden;
    +			transition: all .3s ease;
    +			margin: 0 50px 0 0;
    +			vertical-align: top;
    +		}
    +		.componentSelectLang'.$htmlname.':hover, .componentSelectLang'.$htmlname.':hover a { background-color: #fff; color: #000 !important; }
    +		ul.componentSelectLang'.$htmlname.' { width: 150px; }
    +		ul.componentSelectLang'.$htmlname.':hover .fa { visibility: hidden; }
    +		.componentSelectLang'.$htmlname.' a { text-decoration: none; width: 100%; }
    +		.componentSelectLang'.$htmlname.' li { display: block; padding: 0px 20px; }
    +		.componentSelectLang'.$htmlname.' li:hover { background-color: #EEE; }
    +		';
    +		$out.= '</style>';
    +		$out.= '<ul class="componentSelectLang'.$htmlname.($morecss?' '.$morecss:'').'">';
    +		if ($languagecodeselected)
    +		{
    +			$shortcode = strtolower(substr($languagecodeselected, -2));
    +			$label = $weblangs->trans("Language_".$languagecodeselected);
    +			if ($shortcode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label);
    +			$out.= '<a href="'.$url.$languagecodeselected.'"><li><img height="12px" src="medias/image/common/flags/'.$shortcode.'.png" style="margin-right: 5px;"/>'.$label;
    +			$out.= '<span class="fa fa-caret-down" style="padding-left: 5px;" />';
    +			$out.= '</li></a>';
    +		}
    +		$i=0;
    +		foreach($languagecodes as $languagecode)
    +		{
    +			if ($languagecode == $languagecodeselected) continue;	// Already output
    +			$shortcode = strtolower(substr($languagecode, -2));
    +			$label = $weblangs->trans("Language_".$languagecode);
    +			if ($shortcode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label);
    +			$out.= '<a href="'.$url.$languagecode.'"><li><img height="12px" src="medias/image/common/flags/'.$shortcode.'.png" style="margin-right: 5px;"/>'.$label;
    +			if (empty($i) && empty($languagecodeselected)) $out.= '<span class="fa fa-caret-down" style="padding-left: 5px;" />';
    +			$out.= '</li></a>';
    +			$i++;
    +		}
    +		$out.= '</ul>';
    +
    +		return $out;
    +	}
    +}
    diff --git a/htdocs/website/class/websitepage.class.php b/htdocs/website/class/websitepage.class.php
    index c0b6aaa7ab9..6f8713b5adc 100644
    --- a/htdocs/website/class/websitepage.class.php
    +++ b/htdocs/website/class/websitepage.class.php
    @@ -1,9 +1,8 @@
     <?php
    -/* Copyright (C) 2007-2012  Laurent Destailleur <eldy@users.sourceforge.net>
    +/* Copyright (C) 2007-2018  Laurent Destailleur <eldy@users.sourceforge.net>
      * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
      * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) ---Put here your own copyright and developer email---
      *
      * 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
    @@ -39,29 +38,42 @@ class WebsitePage extends CommonObject
     	 * @var string Id to identify managed objects
     	 */
     	public $element = 'websitepage';
    +
     	/**
     	 * @var string Name of table without prefix where object is stored
     	 */
     	public $table_element = 'website_page';
    +
     	/**
     	 * @var string String with name of icon for websitepage. Must be the part after the 'object_' into object_myobject.png
     	 */
     	public $picto = 'label';
     
     	/**
    -	 */
    -
    +     * @var int ID
    +     */
     	public $fk_website;
    +
     	public $pageurl;
     	public $aliasalt;
     	public $type_container;
     	public $title;
    +
    +	/**
    +	 * @var string description
    +	 */
     	public $description;
    +
     	public $keywords;
     	public $htmlheader;
     	public $content;
     	public $grabbed_from;
    +
    +	/**
    +	 * @var int Status
    +	 */
     	public $status;
    +
     	public $date_creation;
     	public $date_modification;
     
    @@ -88,8 +100,8 @@ class WebsitePage extends CommonObject
     	    'date_creation'  =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
     		'tms'            =>array('type'=>'timestamp',    'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>501),
     		//'date_valid'    =>array('type'=>'datetime',     'label'=>'DateValidation',     'enabled'=>1, 'visible'=>-1, 'position'=>502),
    -		//'fk_user_creat' =>array('type'=>'integer',      'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>510),
    -		//'fk_user_modif' =>array('type'=>'integer',      'label'=>'UserModif',        'enabled'=>1, 'visible'=>-1, 'position'=>511),
    +		'fk_user_creat'  =>array('type'=>'integer',      'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-1, 'notnull'=>true, 'position'=>510),
    +		'fk_user_modif'  =>array('type'=>'integer',      'label'=>'UserModif',        'enabled'=>1, 'visible'=>-1, 'position'=>511),
     		//'fk_user_valid' =>array('type'=>'integer',      'label'=>'UserValidation',        'enabled'=>1, 'visible'=>-1, 'position'=>512),
     		'import_key'     =>array('type'=>'varchar(14)',  'label'=>'ImportId',         'enabled'=>1, 'visible'=>-1,  'index'=>1,  'position'=>1000, 'notnull'=>-1),
     	);
    @@ -125,7 +137,9 @@ class WebsitePage extends CommonObject
     	/**
     	 * Load object in memory from the database
     	 *
    -	 * @param int		$id         	Id object. If this is 0, the value into $page will be used. If not found of $page not defined, the default page of website_id will be used or the first page found if not set.
    +	 * @param int		$id				Id object.
    +	 * 									- If this is 0, the value into $page will be used. If not found or $page not defined, the default page of website_id will be used or the first page found if not set.
    +	 * 									- If value is < 0, we must exclude this ID.
     	 * @param string	$website_id 	Web site id (page name must also be filled if this parameter is used)
     	 * @param string	$page       	Page name (website id must also be filled if this parameter is used)
     	 * @param string	$aliasalt		Alternative alias to search page (slow)
    @@ -152,7 +166,9 @@ class WebsitePage extends CommonObject
     		$sql .= " t.status,";
     		$sql .= " t.grabbed_from,";
     		$sql .= " t.date_creation,";
    -		$sql .= " t.tms as date_modification";
    +		$sql .= " t.tms as date_modification,";
    +		$sql .= " t.fk_user_creat,";
    +		$sql .= " t.fk_user_modif";
     		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
     		//$sql .= ' WHERE entity IN ('.getEntity('website').')';       // entity is on website level
     		$sql .= ' WHERE 1 = 1';
    @@ -162,6 +178,7 @@ class WebsitePage extends CommonObject
     		}
     		else
     		{
    +			if ($id < 0) $sql .= ' AND t.rowid <> ' . abs($id);
     			if (null !== $website_id) {
     			    $sql .= " AND t.fk_website = '" . $this->db->escape($website_id) . "'";
     			    if ($page)		$sql .= " AND t.pageurl = '" . $this->db->escape($page) . "'";
    @@ -180,8 +197,11 @@ class WebsitePage extends CommonObject
     
     				$this->fk_website = $obj->fk_website;
     				$this->type_container = $obj->type_container;
    +
     				$this->pageurl = $obj->pageurl;
    +				$this->ref = $obj->pageurl;
     				$this->aliasalt = preg_replace('/,+$/', '', preg_replace('/^,+/', '', $obj->aliasalt));
    +
     				$this->title = $obj->title;
     				$this->description = $obj->description;
     				$this->keywords = $obj->keywords;
    @@ -193,6 +213,8 @@ class WebsitePage extends CommonObject
     				$this->grabbed_from = $obj->grabbed_from;
     				$this->date_creation = $this->db->jdate($obj->date_creation);
     				$this->date_modification = $this->db->jdate($obj->date_modification);
    +				$this->fk_user_creat = $obj->fk_user_creat;
    +				$this->fk_user_modif = $obj->fk_user_modif;
     			}
     			$this->db->free($resql);
     
    @@ -243,7 +265,9 @@ class WebsitePage extends CommonObject
     		$sql .= " t.status,";
     		$sql .= " t.grabbed_from,";
     		$sql .= " t.date_creation,";
    -		$sql .= " t.tms as date_modification";
    +		$sql .= " t.tms as date_modification,";
    +		$sql .= " t.fk_user_creat,";
    +		$sql .= " t.fk_user_modif";
     		$sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element. ' as t';
     		$sql .= ' WHERE t.fk_website = '.$websiteid;
     		// Manage filter
    @@ -258,11 +282,11 @@ class WebsitePage extends CommonObject
     			}
     		}
     		if (count($sqlwhere) > 0) {
    -			$sql .= ' AND ' . implode(' '.$filtermode.' ', $sqlwhere);
    +			$sql .= ' AND (' . implode(' '.$filtermode.' ', $sqlwhere).')';
     		}
     
     		if (!empty($sortfield)) {
    -			$sql .= $this->db->order($sortfield,$sortorder);
    +			$sql .= $this->db->order($sortfield, $sortorder);
     		}
     		if (!empty($limit)) {
                 $sql .=  ' ' . $this->db->plimit($limit, $offset);
    @@ -292,6 +316,8 @@ class WebsitePage extends CommonObject
     				$record->grabbed_from = $obj->grabbed_from;
     				$record->date_creation = $this->db->jdate($obj->date_creation);
     				$record->date_modification = $this->db->jdate($obj->date_modification);
    +				$record->fk_user_creat = $obj->fk_user_creat;
    +				$record->fk_user_modif = $obj->fk_user_modif;
     				//var_dump($record->id);
     				$records[$record->id] = $record;
     			}
    @@ -362,10 +388,11 @@ class WebsitePage extends CommonObject
     	 * @param	string	$newref				New ref/alias of page
     	 * @param	string	$newlang			New language
     	 * @param	int		$istranslation		1=New page is a translation of the cloned page.
    -	 * @param	int		$newwebsite			0=Same web site, 1=New web site
    +	 * @param	int		$newwebsite			0=Same web site, >0=Id of new website
    +	 * @param	int		$keeptitleunchanged	1=Keep title unchanged
     	 * @return 	mixed 						New object created, <0 if KO
     	 */
    -	public function createFromClone(User $user, $fromid, $newref, $newlang='', $istranslation=0, $newwebsite=0)
    +	public function createFromClone(User $user, $fromid, $newref, $newlang='', $istranslation=0, $newwebsite=0, $keeptitleunchanged=0)
     	{
     		global $hookmanager, $langs;
     		$error = 0;
    @@ -385,7 +412,8 @@ class WebsitePage extends CommonObject
     		$object->ref = $newref;
     		$object->pageurl = $newref;
     		$object->aliasalt = '';
    -		$object->title = $langs->trans("CopyOf").' '.$object->title;
    +		$object->fk_user_creat = $user->id;
    +		$object->title = ($keeptitleunchanged ? '' : $langs->trans("CopyOf").' ').$object->title;
     		if (! empty($newlang)) $object->lang=$newlang;
     		if ($istranslation) $object->fk_page = $fromid;
     		else $object->fk_page = 0;
    @@ -464,6 +492,7 @@ class WebsitePage extends CommonObject
     		return $this->LibStatut($this->status,$mode);
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *  Renvoi le libelle d'un status donne
     	 *
    @@ -473,6 +502,7 @@ class WebsitePage extends CommonObject
     	 */
     	function LibStatut($status,$mode=0)
     	{
    +        // phpcs:enable
     		global $langs;
     
     		if ($mode == 0)
    @@ -481,27 +511,27 @@ class WebsitePage extends CommonObject
     			if ($status == 1) return $langs->trans('Enabled');
     			if ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 1)
    +		elseif ($mode == 1)
     		{
     			if ($status == 1) return $langs->trans('Enabled');
     			if ($status == 0) return $langs->trans('Disabled');
     		}
    -		if ($mode == 2)
    +		elseif ($mode == 2)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 3)
    +		elseif ($mode == 3)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5');
     		}
    -		if ($mode == 4)
    +		elseif ($mode == 4)
     		{
     			if ($status == 1) return img_picto($langs->trans('Enabled'),'statut4').' '.$langs->trans('Enabled');
     			if ($status == 0) return img_picto($langs->trans('Disabled'),'statut5').' '.$langs->trans('Disabled');
     		}
    -		if ($mode == 5)
    +		elseif ($mode == 5)
     		{
     			if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'),'statut4');
     			if ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'),'statut5');
    @@ -517,6 +547,8 @@ class WebsitePage extends CommonObject
     	 */
     	public function initAsSpecimen()
     	{
    +		global $user;
    +
     		$this->id = 0;
     
     		$now=dol_now();
    @@ -534,6 +566,6 @@ class WebsitePage extends CommonObject
     		$this->grabbed_from = '';
     		$this->date_creation = $now - (24 * 30 * 3600);
     		$this->date_modification = $now - (24 * 7 * 3600);
    +		$this->fk_user_creat = $user->id;
     	}
    -
     }
    diff --git a/htdocs/website/index.php b/htdocs/website/index.php
    index e1460f497f1..4f969851ad4 100644
    --- a/htdocs/website/index.php
    +++ b/htdocs/website/index.php
    @@ -1,5 +1,5 @@
     <?php
    -/* Copyright (C) 2016-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2016-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
      *
      * 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
    @@ -45,7 +45,7 @@ if (! ((GETPOST('testmenuhider','int') || ! empty($conf->global->MAIN_TESTMENUHI
     }
     
     $error=0;
    -$website=GETPOST('website', 'alpha');
    +$websitekey=GETPOST('website', 'alpha');
     $page=GETPOST('page', 'alpha');
     $pageid=GETPOST('pageid', 'int');
     $pageref=GETPOST('pageref', 'aZ09');
    @@ -58,6 +58,7 @@ $type_container=GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha');
     $section_dir = GETPOST('section_dir', 'alpha');
     $file_manager = GETPOST('file_manager', 'alpha');
     
    +if (GETPOST('deletesite','alpha')) { $action='deletesite'; }
     if (GETPOST('delete','alpha')) { $action='delete'; }
     if (GETPOST('preview','alpha')) $action='preview';
     if (GETPOST('createsite','alpha')) { $action='createsite'; }
    @@ -68,6 +69,8 @@ if (GETPOST('setashome','alpha')) { $action='setashome'; }
     if (GETPOST('editmeta','alpha')) { $action='editmeta'; }
     if (GETPOST('editsource','alpha')) { $action='editsource'; }
     if (GETPOST('editcontent','alpha')) { $action='editcontent'; }
    +if (GETPOST('exportsite','alpha')) { $action='exportsite'; }
    +if (GETPOST('importsite','alpha')) { $action='importsite'; }
     if (GETPOST('createfromclone','alpha')) { $action='createfromclone'; }
     if (GETPOST('createpagefromclone','alpha')) { $action='createpagefromclone'; }
     if (empty($action) && $file_manager) $action='file_manager';
    @@ -89,46 +92,82 @@ if (empty($action)) $action='preview';
     $object=new Website($db);
     $objectpage=new WebsitePage($db);
     
    -$object->fetchAll();    // Init $object->records
    +$object->fetchAll();    // Init $object->records with list of websites
     
     // If website not defined, we take first found
    -if (empty($website))
    +if (empty($websitekey))
     {
     	foreach($object->records as $key => $valwebsite)
     	{
    -		$website=$valwebsite->ref;
    +		$websitekey=$valwebsite->ref;
     		break;
     	}
     }
    -if ($website)
    +if ($websitekey)
     {
    -	$res = $object->fetch(0, $website);
    +	$res = $object->fetch(0, $websitekey);
     }
    +$website = $object;
     
    +// Check pageid received as aprameter
     if ($pageid < 0) $pageid = 0;
     if (($pageid > 0 || $pageref) && $action != 'addcontainer')
     {
     	$res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), $pageref);
    -	//var_dump($res);exit;
    -	//if ($res == 0)		// Page ref not found, we check in alias
    -	//{
    -	//	$res = $objectpage->fetch($pageid, ($object->id > 0 ? $object->id : null), $pageref);
    -	//}
     
     	// Check if pageid is inside the new website, if not we reset param pageid
    -	if ($object->id > 0 && ($objectpage->fk_website != $object->id))
    +	if ($res >= 0 && $object->id > 0)
     	{
    -		$res = $objectpage->fetch(0, $object->id, '');;
    -		if ($res == 0)	// Page was not found, we reset it
    +		if ($objectpage->fk_website != $object->id)	// We have a bad page that does not belong to web site
     		{
    -			$objectpage=new WebsitePage($db);
    +			if ($object->fk_default_home > 0)
    +			{
    +				$res = $objectpage->fetch($object->fk_default_home, $object->id, '');	// We search first page of web site
    +				if ($res > 0) $pageid = $object->fk_default_home;
    +			}
    +			else
    +			{
    +				$res = $objectpage->fetch(0, $object->id, '');	// We search first page of web site
    +				if ($res == 0)	// Page was not found, we reset it
    +				{
    +					$objectpage=new WebsitePage($db);
    +				}
    +				else			// We found a page, we set pageid to it.
    +				{
    +					$pageid = $objectpage->id;
    +				}
    +			}
    +		}
    +		else	// We have a valid page. We force pageid for the case we got the page with a fetch on ref.
    +		{
    +			$pageid = $objectpage->id;
     		}
     	}
    -	$pageid = $objectpage->id;
     }
     
    +// Define pageid if pageid and pageref not received as parameter or was wrong
    +if (empty($pageid) && empty($pageref) && $object->id > 0 && $action != 'createcontainer')
    +{
    +	$pageid = $object->fk_default_home;
    +	if (empty($pageid))
    +	{
    +		$array=$objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
    +		if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors);
    +		$atleastonepage=(is_array($array) && count($array) > 0);
    +
    +		$firstpageid=0;$homepageid=0;
    +		foreach($array as $key => $valpage)
    +		{
    +			if (empty($firstpageid)) $firstpageid=$valpage->id;
    +			if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid=$valpage->id;
    +		}
    +		$pageid=($homepageid?$homepageid:$firstpageid);   // We choose home page and if not defined yet, we take first page
    +	}
    +}
    +
    +
     global $dolibarr_main_data_root;
    -$pathofwebsite=$dolibarr_main_data_root.'/website/'.$website;
    +$pathofwebsite=$dolibarr_main_data_root.'/website/'.$websitekey;
     $filehtmlheader=$pathofwebsite.'/htmlheader.html';
     $filecss=$pathofwebsite.'/styles.css.php';
     $filejs=$pathofwebsite.'/javascript.js.php';
    @@ -136,6 +175,7 @@ $filerobot=$pathofwebsite.'/robots.txt';
     $filehtaccess=$pathofwebsite.'/.htaccess';
     $filetpl=$pathofwebsite.'/page'.$pageid.'.tpl.php';
     $fileindex=$pathofwebsite.'/index.php';
    +$filewrapper=$pathofwebsite.'/wrapper.php';
     
     // Define $urlwithroot
     $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
    @@ -167,11 +207,39 @@ $htmlheadercontentdefault.='-->'."\n";
      * Actions
      */
     
    -$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$website.'&pageid='.$pageid;	// used after a confirm_deletefile into actions_linkedfiles.inc.php
    +$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid.(GETPOST('section_dir','alpha')?'&section_dir='.urlencode(GETPOST('section_dir','alpha')):'');	// used after a confirm_deletefile into actions_linkedfiles.inc.php
     include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
     
     if ($action == 'renamefile') $action='file_manager';		// After actions_linkedfiles, if action were renamefile, we set it to 'file_manager'
     
    +if ($action == 'seteditinline')
    +{
    +	dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 1);
    +	setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings');
    +	dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 0);	// Force disable of show included containers
    +	header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website','alphanohtml').'&pageid='.GETPOST('pageid','int'));
    +	exit;
    +}
    +if ($action == 'unseteditinline')
    +{
    +	dolibarr_del_const($db, 'WEBSITE_EDITINLINE');
    +	header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website','alphanohtml').'&pageid='.GETPOST('pageid','int'));
    +	exit;
    +}
    +if ($action == 'setshowsubcontainers')
    +{
    +	dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 1);
    +	dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 0);	// Force disable of edit inline
    +	header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website','alphanohtml').'&pageid='.GETPOST('pageid','int'));
    +	exit;
    +}
    +if ($action == 'unsetshowsubcontainers')
    +{
    +	dolibarr_del_const($db, 'WEBSITE_SUBCONTAINERSINLINE');
    +	header("Location: ".$_SERVER["PHP_SELF"].'?website='.GETPOST('website','alphanohtml').'&pageid='.GETPOST('pageid','int'));
    +	exit;
    +}
    +
     // Add directory
     /*
     if ($action == 'adddir' && $permtouploadfile)
    @@ -197,12 +265,12 @@ if ($action == 'adddir' && $permtouploadfile)
     */
     
     
    -if (GETPOST('refreshsite'))		// If we change the site, we reset the pageid and cancel addsite action.
    +if (GETPOST('refreshsite','alpha'))		// If we change the site, we reset the pageid and cancel addsite action.
     {
     	$pageid=0;
     	if ($action == 'addsite') $action = 'preview';
     }
    -if (GETPOST('refreshpage') && ! in_array($action, array('updatecss'))) $action='preview';
    +if (GETPOST('refreshpage','alpha') && ! in_array($action, array('updatecss'))) $action='preview';
     
     
     // Add site
    @@ -213,6 +281,7 @@ if ($action == 'addsite')
     	if (! $error && ! GETPOST('WEBSITE_REF','alpha'))
     	{
     		$error++;
    +		$langs->load("errors");
     		setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
     	}
     	if (! $error && ! preg_match('/^[a-z0-9_\-\.]+$/i', GETPOST('WEBSITE_REF','alpha')))
    @@ -327,7 +396,7 @@ if ($action == 'addcontainer')
     				// Remove comments
     				$tmp['content'] = removeHtmlComment($tmp['content']);
     
    -				preg_match('/<head>(.*)<\/head>/is', $tmp['content'], $reg);
    +				preg_match('/<head>(.*)<\/head>/ims', $tmp['content'], $reg);
     				$head = $reg[1];
     
     				$objectpage->type_container = 'page';
    @@ -390,6 +459,7 @@ if ($action == 'addcontainer')
     				//$objectpage->htmlheader = preg_replace('/<meta name="msvalidate.01[^>]*>\n*/ims', '', $objectpage->htmlheader);
     				$objectpage->htmlheader = preg_replace('/<title>[^<]*<\/title>\n*/ims', '', $objectpage->htmlheader);
     				$objectpage->htmlheader = preg_replace('/<link[^>]*rel="shortcut[^>]*>\n/ims', '', $objectpage->htmlheader);
    +				$objectpage->htmlheader = preg_replace('/<link[^>]*rel="canonical[^>]*>\n/ims', '', $objectpage->htmlheader);
     
     				// Now loop to fetch JS
     				$tmp = $objectpage->htmlheader;
    @@ -623,13 +693,13 @@ if ($action == 'addcontainer')
     			if ($result)
     			{
     				setEventMessages($langs->trans("Saved"), null, 'mesgs');
    -				//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +				//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
     				//exit;
     			}
     			else
     			{
     				setEventMessages('Failed to write file '.$filetpl, null, 'errors');
    -				//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +				//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
     				//exit;
     			}
     		}
    @@ -697,6 +767,41 @@ if ($action == 'addcontainer')
     	}
     }
     
    +// Delete site
    +if ($action == 'deletesite')
    +{
    +	$error = 0;
    +
    +	$db->begin();
    +
    +	$res = $object->fetch(0, $websitekey);
    +	$website = $object;
    +
    +	if ($res > 0)
    +	{
    +		$res = $object->delete($user);
    +		if ($res <= 0)
    +		{
    +			$error++;
    +			setEventMessages($object->error, $object->errors, 'errors');
    +		}
    +	}
    +
    +	if (! $error)
    +	{
    +		$db->commit();
    +		setEventMessages($langs->trans("SiteDeleted", $object->ref, $websitekey), null, 'mesgs');
    +
    +		header("Location: ".$_SERVER["PHP_SELF"]);
    +		exit;
    +	}
    +	else
    +	{
    +		$db->rollback();
    +		dol_print_error($db);
    +	}
    +}
    +
     // Delete page
     if ($action == 'delete')
     {
    @@ -704,7 +809,8 @@ if ($action == 'delete')
     
     	$db->begin();
     
    -	$res = $object->fetch(0, $website);
    +	$res = $object->fetch(0, $websitekey);
    +	$website = $object;
     
     	$res = $objectpage->fetch($pageid, $object->fk_website);
     
    @@ -721,9 +827,9 @@ if ($action == 'delete')
     	if (! $error)
     	{
     		$db->commit();
    -		setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $website), null, 'mesgs');
    +		setEventMessages($langs->trans("PageDeleted", $objectpage->pageurl, $websitekey), null, 'mesgs');
     
    -		header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website);
    +		header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey);
     		exit;
     	}
     	else
    @@ -742,7 +848,8 @@ if ($action == 'updatecss')
     	}
     	else
     	{
    -		$res = $object->fetch(0, $website);
    +		$res = $object->fetch(0, $websitekey);
    +		$website = $object;
     
     		// Html header file
     		$htmlheadercontent ='';
    @@ -750,7 +857,7 @@ if ($action == 'updatecss')
     		/* We disable php code since htmlheader is never executed as an include but only read by fgets_content.
     	    $htmlheadercontent.= "<?php // BEGIN PHP\n";
     	    $htmlheadercontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -	    $htmlheadercontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n";
    +	    $htmlheadercontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Not already loaded"."\n";
     	    $htmlheadercontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     	    $htmlheadercontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
     	    $htmlheadercontent.= "ob_start();\n";
    @@ -773,7 +880,7 @@ if ($action == 'updatecss')
     
     		$csscontent.= "<?php // BEGIN PHP\n";
     		$csscontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -		$csscontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n";	// For the css, we need to set path of master using the dirname of css file.
    +		$csscontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n";	// For the css, we need to set path of master using the dirname of css file.
     		$csscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     		$csscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
     		$csscontent.= "ob_start();\n";
    @@ -805,7 +912,7 @@ if ($action == 'updatecss')
     
     		$jscontent.= "<?php // BEGIN PHP\n";
     		$jscontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -		$jscontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n";	// For the css, we need to set path of master using the dirname of css file.
    +		$jscontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once dirname(__FILE__).'/master.inc.php'; } // Not already loaded"."\n";	// For the css, we need to set path of master using the dirname of css file.
     		$jscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     		$jscontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
     		$jscontent.= "ob_start();\n";
    @@ -837,7 +944,7 @@ if ($action == 'updatecss')
     
     		/*$robotcontent.= "<?php // BEGIN PHP\n";
     	    $robotcontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -	    $robotcontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n";
    +	    $robotcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Not already loaded"."\n";
     	    $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     	    $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
     	    $robotcontent.= "ob_start();\n";
    @@ -869,7 +976,7 @@ if ($action == 'updatecss')
     
     		/*$robotcontent.= "<?php // BEGIN PHP\n";
         	 $robotcontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    -    	 $robotcontent.= "if (! defined('USEDOLIBARRSERVER')) { require_once './master.inc.php'; } // Not already loaded"."\n";
    +    	 $robotcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Not already loaded"."\n";
         	 $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
         	 $robotcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
         	 $robotcontent.= "ob_start();\n";
    @@ -909,7 +1016,8 @@ if ($action == 'updatecss')
     if ($action == 'setashome')
     {
     	$db->begin();
    -	$object->fetch(0, $website);
    +	$object->fetch(0, $websitekey);
    +	$website = $object;
     
     	$object->fk_default_home = $pageid;
     	$res = $object->update($user);
    @@ -925,7 +1033,7 @@ if ($action == 'setashome')
     
     		// Generate the index.php page to be the home page
     		//-------------------------------------------------
    -		$result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl);
    +		$result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper);
     
     		if ($result) setEventMessages($langs->trans("Saved"), null, 'mesgs');
     		else setEventMessages('Failed to write file '.$fileindex, null, 'errors');
    @@ -943,7 +1051,8 @@ if ($action == 'updatemeta')
     {
     	$db->begin();
     
    -	$object->fetch(0, $website);
    +	$result = $object->fetch(0, $websitekey);
    +	$website = $object;
     
     	$objectpage->fk_website = $object->id;
     
    @@ -956,13 +1065,59 @@ if ($action == 'updatemeta')
     		$action='editmeta';
     	}
     
    -	$res = $objectpage->fetch($pageid, $object->fk_website);
    +	$res = $objectpage->fetch($pageid, $object->id);
     	if ($res <= 0)
     	{
     		$error++;
     		setEventMessages('Page not found '.$objectpage->error, $objectpage->errors, 'errors');
     	}
     
    +	// Check alias not exists
    +	if (! $error && GETPOST('WEBSITE_PAGENAME', 'alpha'))
    +	{
    +		$websitepagetemp=new WebsitePage($db);
    +		$result = $websitepagetemp->fetch(-1 * $objectpage->id, $object->id, GETPOST('WEBSITE_PAGENAME', 'alpha'));
    +		if ($result < 0)
    +		{
    +			$error++;
    +			$langs->load("errors");
    +			setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
    +			$action = 'editmeta';
    +		}
    +		if ($result > 0)
    +		{
    +			$error++;
    +			$langs->load("errors");
    +			setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
    +			$action = 'editmeta';
    +		}
    +	}
    +	if (! $error && GETPOST('WEBSITE_ALIASALT', 'alpha'))
    +	{
    +		$arrayofaliastotest=explode(',', GETPOST('WEBSITE_ALIASALT', 'alpha'));
    +		$websitepagetemp=new WebsitePage($db);
    +		foreach($arrayofaliastotest as $aliastotest)
    +		{
    +			$result = $websitepagetemp->fetch(-1 * $objectpage->id, $object->id, $aliastotest);
    +			if ($result < 0)
    +			{
    +				$error++;
    +				$langs->load("errors");
    +				setEventMessages($websitepagetemp->error, $websitepagetemp->errors, 'errors');
    +				$action = 'editmeta';
    +				break;
    +			}
    +			if ($result > 0)
    +			{
    +				$error++;
    +				$langs->load("errors");
    +				setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists", $websitepagetemp->pageurl), null, 'errors');
    +				$action = 'editmeta';
    +				break;
    +			}
    +		}
    +	}
    +
     	if (! $error)
     	{
     		$objectpage->old_object = clone $objectpage;
    @@ -977,10 +1132,23 @@ if ($action == 'updatemeta')
     		$objectpage->htmlheader = trim(GETPOST('htmlheader', 'none'));
     
     		$res = $objectpage->update($user);
    -		if (! $res > 0)
    +		if (! ($res > 0))
     		{
    -			$error++;
    -			setEventMessages($objectpage->error, $objectpage->errors, 'errors');
    +			$langs->load("errors");
    +			if ($db->lasterrno == 'DB_ERROR_RECORD_ALREADY_EXISTS')
    +			{
    +				$error++;
    +				$langs->load("errors");
    +				setEventMessages($langs->trans("ErrorAPageWithThisNameOrAliasAlreadyExists"), null, 'errors');
    +				$action = 'editmeta';
    +			}
    +			else
    +			{
    +				$error++;
    +				$langs->load("errors");
    +				setEventMessages($objectpage->error, $objectpage->errors, 'errors');
    +				$action = 'editmeta';
    +			}
     		}
     	}
     
    @@ -1003,19 +1171,7 @@ if ($action == 'updatemeta')
     
     
     		// Now generate the master.inc.php page
    -		dol_syslog("We regenerate the master file (because we update meta)");
    -		dol_delete_file($filemaster);
    -
    -		$mastercontent = '<?php'."\n";
    -		$mastercontent.= '// File generated to link to the master file - DO NOT MODIFY - It is just an include'."\n";
    -		$mastercontent.= "if (! defined('USEDOLIBARRSERVER')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n";
    -		//$mastercontent.= "include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';"."\n";
    -		//$mastercontent.= '$website = new WebSite($db)'."\n";
    -		$mastercontent.= '?>'."\n";
    -		$result = file_put_contents($filemaster, $mastercontent);
    -		if (! empty($conf->global->MAIN_UMASK))
    -			@chmod($filemaster, octdec($conf->global->MAIN_UMASK));
    -
    +		$result = dolSaveMasterFile($filemaster);
     		if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors');
     
     		// Now delete the alias.php page
    @@ -1061,13 +1217,13 @@ if ($action == 'updatemeta')
     		if ($result)
     		{
     			setEventMessages($langs->trans("Saved"), null, 'mesgs');
    -			//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +			//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
     			//exit;
     		}
     		else
     		{
     			setEventMessages('Failed to write file '.$filetpl, null, 'errors');
    -			//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +			//header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
        			//exit;
     		}
     
    @@ -1079,10 +1235,13 @@ if ($action == 'updatemeta')
     if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'confirm_createfromclone' || $action == 'confirm_createpagefromclone')
     	|| ($action == 'preview' && (GETPOST('refreshsite') || GETPOST('refreshpage') || GETPOST('preview'))))
     {
    -	$object->fetch(0, $website);
    +	$object->fetch(0, $websitekey);
    +	$website = $object;
     
     	if ($action == 'confirm_createfromclone')
     	{
    +		$db->begin();
    +
     		$objectnew = new Website($db);
     		$result = $objectnew->createFromClone($user, GETPOST('id','int'), GETPOST('siteref','aZ09'), (GETPOST('newlang','aZ09')?GETPOST('newlang','aZ09'):''));
     		if ($result < 0)
    @@ -1090,12 +1249,17 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
     			$error++;
     			setEventMessages($objectnew->error, $objectnew->errors, 'errors');
     			$action='preview';
    +
    +			$db->rollback();
     		}
     		else
     		{
     			$object = $objectnew;
     			$id = $object->id;
     			$pageid = $object->fk_default_home;
    +			$websitekey = GETPOST('siteref','aZ09');
    +
    +			$db->commit();
     		}
     	}
     
    @@ -1114,17 +1278,51 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
     
     		if (! $error)
     		{
    +			$db->begin();
    +
    +			$newwebsiteid = GETPOST('newwebsite','int');
    +			$pathofwebsitenew = $pathofwebsite;
    +
    +			$tmpwebsite=new Website($db);
    +			if ($newwebsiteid > 0 && $newwebsiteid != $object->id)
    +			{
    +				$tmpwebsite->fetch($newwebsiteid);
    +				$pathofwebsitenew = $dolibarr_main_data_root.'/website/'.$tmpwebsite->ref;
    +			}
    +			else
    +			{
    +				$tmpwebsite = $object;
    +			}
    +
     			$objectpage = new WebsitePage($db);
    -			$result = $objectpage->createFromClone($user, $pageid, GETPOST('pageurl','aZ09'), (GETPOST('newlang','aZ09')?GETPOST('newlang','aZ09'):''), $istranslation, GETPOST('newwebsite','int'));
    -			if ($result < 0)
    +			$resultpage = $objectpage->createFromClone($user, $pageid, GETPOST('pageurl','aZ09'), (GETPOST('newlang','aZ09')?GETPOST('newlang','aZ09'):''), $istranslation, $newwebsiteid);
    +			if ($resultpage < 0)
     			{
     				$error++;
     				setEventMessages($objectpage->error, $objectpage->errors, 'errors');
     				$action='createpagefromclone';
    +
    +				$db->rollback();
     			}
     			else
     			{
    -				// TODO Switch on the new page ?
    +				$fileindex=$pathofwebsitenew.'/index.php';
    +				$filetpl=$pathofwebsitenew.'/page'.$resultpage->id.'.tpl.php';
    +				$filewrapper=$pathofwebsitenew.'/wrapper.php';
    +
    +				//var_dump($pathofwebsitenew);
    +				//var_dump($filetpl);
    +				//exit;
    +
    +				dolSavePageContent($filetpl, $tmpwebsite, $resultpage);
    +
    +				// Switch on the new page if web site of new page/container is same
    +				if (empty($newwebsiteid) || $newwebsiteid == $object->id)
    +				{
    +					$pageid = $resultpage->id;
    +				}
    +
    +				$db->commit();
     			}
     		}
     	}
    @@ -1178,7 +1376,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
     			$objectpage->content = GETPOST('PAGE_CONTENT','none');
     
     			// Clean data. We remove all the head section.
    -			$objectpage->content = preg_replace('/<head>.*<\/head>/s', '', $objectpage->content);
    +			$objectpage->content = preg_replace('/<head>.*<\/head>/ims', '', $objectpage->content);
     			/* $objectpage->content = preg_replace('/<base\s+href=[\'"][^\'"]+[\'"]\s/?>/s', '', $objectpage->content); */
     
     
    @@ -1201,16 +1399,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
     
     
     				// Now generate the master.inc.php page
    -				dol_syslog("We regenerate the master file");
    -				dol_delete_file($filemaster);
    -
    -				$mastercontent = '<?php'."\n";
    -				$mastercontent.= '// File generated to link to the master file'."\n";
    -				$mastercontent.= "if (! defined('USEDOLIBARRSERVER')) require_once '".DOL_DOCUMENT_ROOT."/master.inc.php';\n";
    -				$mastercontent.= '?>'."\n";
    -				$result = file_put_contents($filemaster, $mastercontent);
    -				if (! empty($conf->global->MAIN_UMASK))
    -					@chmod($filemaster, octdec($conf->global->MAIN_UMASK));
    +				$result = dolSaveMasterFile($filemaster);
     
     				if (! $result) setEventMessages('Failed to write file '.$filemaster, null, 'errors');
     
    @@ -1231,13 +1420,13 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
     				if ($result)
     				{
     					setEventMessages($langs->trans("Saved"), null, 'mesgs');
    -					header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +					header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
     	   				exit;
     				}
     				else
     				{
     					setEventMessages('Failed to write file '.$filetpl, null, 'errors');
    -					header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +					header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
     	   				exit;
     				}
     			}
    @@ -1248,18 +1437,22 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
     		}
     		else
     		{
    -			header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website.'&pageid='.$pageid);
    +			header("Location: ".$_SERVER["PHP_SELF"].'?website='.$websitekey.'&pageid='.$pageid);
     			exit;
     		}
     	}
     	else
     	{
    -		if (! $error) setEventMessages($langs->trans("NoPageYet"), null, 'warnings');
    +		if (! $error)
    +		{
    +			setEventMessages($langs->trans("NoPageYet"), null, 'warnings');
    +			setEventMessages($langs->trans("YouCanCreatePageOrImportTemplate"), null, 'warnings');
    +		}
     	}
     }
     
     // Export site
    -if (GETPOST('exportsite','alpha'))
    +if ($action == 'exportsite')
     {
     	$fileofzip = $object->exportWebSite();
     
    @@ -1276,6 +1469,84 @@ if (GETPOST('exportsite','alpha'))
     	}
     }
     
    +// Import site
    +if ($action == 'importsiteconfirm')
    +{
    +	if (empty($_FILES))
    +	{
    +		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
    +		$action = 'importsite';
    +	}
    +	else
    +	{
    +		if (! empty($_FILES))
    +		{
    +			// Check symlink to medias and restore it if ko
    +			$pathtomedias=DOL_DATA_ROOT.'/medias';
    +			$pathtomediasinwebsite=$pathofwebsite.'/medias';
    +			if (! is_link(dol_osencode($pathtomediasinwebsite)))
    +			{
    +				dol_syslog("Create symlink for ".$pathtomedias." into name ".$pathtomediasinwebsite);
    +				dol_mkdir(dirname($pathtomediasinwebsite));     // To be sure dir for website exists
    +				$result = symlink($pathtomedias, $pathtomediasinwebsite);
    +				if (! $result)
    +				{
    +					setEventMessages($langs->trans("ErrorFieldToCreateSymLinkToMedias", $pathtomediasinwebsite, $pathtomedias), null, 'errors');
    +					$action = 'importsite';
    +				}
    +			}
    +
    +			if (is_array($_FILES['userfile']['tmp_name'])) $userfiles=$_FILES['userfile']['tmp_name'];
    +			else $userfiles=array($_FILES['userfile']['tmp_name']);
    +
    +			foreach($userfiles as $key => $userfile)
    +			{
    +				if (empty($_FILES['userfile']['tmp_name'][$key]))
    +				{
    +					$error++;
    +					if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2){
    +						setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors');
    +						$action = 'importsite';
    +					}
    +					else {
    +						setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
    +						$action = 'importsite';
    +					}
    +				}
    +			}
    +
    +			if (! $error)
    +			{
    +				$upload_dir = $conf->website->dir_temp;
    +				$result = dol_add_file_process($upload_dir, 1, -1, 'userfile', '');
    +
    +				// Get name of file (take last one if several name provided)
    +				$fileofzip = $upload_dir.'/unknown';
    +				foreach($_FILES as $key => $ifile)
    +				{
    +					foreach($ifile['name'] as $key2 => $ifile2)
    +					{
    +						$fileofzip = $upload_dir . '/' .$ifile2;
    +					}
    +				}
    +
    +				$result = $object->importWebSite($fileofzip);
    +				if ($result < 0)
    +				{
    +					setEventMessages($object->error, $object->errors, 'errors');
    +					$action = 'importsite';
    +				}
    +				else
    +				{
    +					header("Location: ".$_SERVER["PHP_SELF"].'?website='.$object->ref);
    +					exit();
    +				}
    +			}
    +		}
    +	}
    +}
    +
    +
     
     
     /*
    @@ -1350,6 +1621,10 @@ if ($action == 'edit')
     {
     	print '<input type="hidden" name="action" value="update">';
     }
    +if ($action == 'importsite')
    +{
    +	print '<input type="hidden" name="action" value="importsiteconfirm">';
    +}
     if ($action == 'file_manager')
     {
     	print '<input type="hidden" name="action" value="file_manager">';
    @@ -1367,7 +1642,7 @@ if (! GETPOST('hide_websitemenu'))
     //var_dump($objectpage);exit;
     print '<div class="centpercent websitebar">';
     
    -if (count($object->records) > 0)
    +if (count($object->records) > 0)	// There is at least one web site
     {
     	// ***** Part for web sites
     
    @@ -1388,10 +1663,10 @@ if (count($object->records) > 0)
     	$i=0;
     	foreach($object->records as $key => $valwebsite)
     	{
    -		if (empty($website)) $website=$valwebsite->ref;
    +		if (empty($websitekey)) $websitekey=$valwebsite->ref;
     
     		$out.='<option value="'.$valwebsite->ref.'"';
    -		if ($website == $valwebsite->ref) $out.=' selected';		// To preselect a value
    +		if ($websitekey == $valwebsite->ref) $out.=' selected';		// To preselect a value
     		$out.='>';
     		$out.=$valwebsite->ref;
     		$out.='</option>';
    @@ -1401,17 +1676,22 @@ if (count($object->records) > 0)
     	$out.=ajax_combobox('website');
     	print $out;
     	//print '<input type="submit" class="button" name="refreshsite" value="'.$langs->trans("Load").'">';
    -	print '<input type="image" class="valignbottom" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshpage" value="'.$langs->trans("Load").'">';
    +	print '<input type="image" class="valignmiddle" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshpage" value="'.$langs->trans("Load").'">';
     
     
    -	if ($website)
    +	if ($websitekey)
     	{
     		$virtualurl='';
    -		$dataroot=DOL_DATA_ROOT.'/website/'.$website;
    +		$dataroot=DOL_DATA_ROOT.'/website/'.$websitekey;
     		if (! empty($object->virtualhost)) $virtualurl=$object->virtualhost;
     	}
     
    -	if ($website && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone'))
    +
    +	$array=$objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
    +	if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors);
    +	$atleastonepage=(is_array($array) && count($array) > 0);
    +
    +	if ($websitekey && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone'))
     	{
     		$disabled='';
     		if (empty($user->rights->website->write)) $disabled=' disabled="disabled"';
    @@ -1422,6 +1702,16 @@ if (count($object->records) > 0)
     		//print '<input type="submit" class="button"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditMenu")).'" name="editmenu">';
     		print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("CloneSite")).'" name="createfromclone">';
     		print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ExportSite")).'" name="exportsite">';
    +		if (! $atleastonepage)
    +		{
    +			print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ImportSite")).'" name="importsite">';
    +		}
    +		else
    +		{
    +			print '<input type="submit" class="button nobordertransp" disabled="disabled" value="'.dol_escape_htmltag($langs->trans("ImportSite")).'" name="importsite">';
    +		}
    +
    +		print '<input type="submit" class="buttonDelete" name="deletesite" value="'.$langs->trans("Delete").'"'.($atleastonepage?' disabled="disabled"':'').'>';
     
     		print ' &nbsp; ';
     
    @@ -1430,7 +1720,7 @@ if (count($object->records) > 0)
     		print '<script language="javascript">
     			jQuery(document).ready(function () {
                		jQuery(".button_file_manager").click(function () {
    -					var $dialog = $(\'<div></div>\').html(\'<iframe style="border: 0px;" src="'.DOL_URL_ROOT.'/website/index.php?hide_websitemenu=1&dol_hide_topmenu=1&dol_hide_leftmenu=1&file_manager=1&website='.$website.'&pageid='.$pageid.'" width="100%" height="100%"></iframe>\')
    +					var $dialog = $(\'<div></div>\').html(\'<iframe style="border: 0px;" src="'.DOL_URL_ROOT.'/website/index.php?hide_websitemenu=1&dol_hide_topmenu=1&dol_hide_leftmenu=1&file_manager=1&website='.$websitekey.'&pageid='.$pageid.'" width="100%" height="100%"></iframe>\')
     					.dialog({
     						autoOpen: false,
     						modal: true,
    @@ -1447,31 +1737,33 @@ if (count($object->records) > 0)
     
     	print '</div>';
     
    -	// Button for website
    +
    +	// Toolbar for websites
    +
     	print '<div class="websitetools">';
     
     	if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')
     	{
     		$urlext=$virtualurl;
    -		$urlint=$urlwithroot.'/public/website/index.php?website='.$website;
    +		$urlint=$urlwithroot.'/public/website/index.php?website='.$websitekey;
     
     		$htmltext = $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $urlint, $dataroot);
     		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    -		print '<a class="websitebuttonsitepreview" id="previewsite" href="'.$urlwithroot.'/public/website/index.php?website='.$website.'" target="tab'.$website.'" alt="'.dol_escape_htmltag($htmltext).'">';
    +		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
    +		print '<a class="websitebuttonsitepreview" id="previewsite" href="'.$urlwithroot.'/public/website/index.php?website='.$websitekey.'" target="tab'.$websitekey.'" alt="'.dol_escape_htmltag($htmltext).'">';
     		print $form->textwithpicto('', $htmltext, 1, 'preview');
     		print '</a>';
     
     		print '<div class="websiteinputurl" id="websiteinputurl">';
     		print '<input type="text" id="previewsiteurl" class="minwidth200imp" name="previewsite" placeholder="'.$langs->trans("http://myvirtualhost").'" value="'.$virtualurl.'">';
    -		//print '<input type="submit" class="button" name="previewwebsite" target="tab'.$website.'" value="'.$langs->trans("ViewSiteInNewTab").'">';
    +		//print '<input type="submit" class="button" name="previewwebsite" target="tab'.$websitekey.'" value="'.$langs->trans("ViewSiteInNewTab").'">';
     		$htmltext =$langs->trans("SetHereVirtualHost", $dataroot);
     		$htmltext.='<br>';
    +		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    +		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
    +		$htmltext.='<br>';
     		$htmltext.='<br>';
     		$htmltext.=$langs->trans("YouCanAlsoTestWithPHPS", $dataroot);
    -		$htmltext.='<br>';
    -		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
     		print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helpvirtualhost');
     		print '</div>';
     
    @@ -1481,7 +1773,7 @@ if (count($object->records) > 0)
     			$htmltext.='<br>';
     			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
     			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    -			print '<span class="websitebuttonsitepreview websitebuttonsitepreviewdisabled cursornotallowed" id="previewsiteextdisabled" href="" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">';
    +			print '<span class="websitebuttonsitepreview websitebuttonsitepreviewdisabled cursornotallowed" id="previewsiteextdisabled" href="" target="tab'.$websitekey.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">';
     			print $form->textwithpicto('', $htmltext, 1, 'preview_ext');
     			print '</span>';
     		}
    @@ -1490,8 +1782,8 @@ if (count($object->records) > 0)
     			$htmltext = $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>');
     			$htmltext.='<br>';
     			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    -			print '<a class="websitebuttonsitepreview'.($urlext?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewsiteext" href="'.$urlext.'" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">';
    +			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
    +			print '<a class="websitebuttonsitepreview'.($urlext?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewsiteext" href="'.$urlext.'" target="tab'.$websitekey.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">';
     			print $form->textwithpicto('', $htmltext, 1, 'preview_ext');
     			print '</a>';
     		}
    @@ -1507,16 +1799,12 @@ if (count($object->records) > 0)
     	print '</div>';
     
     
    -	// ***** Part for pages
    +	// Toolbar for pages
     
    -	if ($website && ! in_array($action, array('editcss','editmenu')))
    +	if ($websitekey && ! in_array($action, array('editcss','editmenu','importsite')))
     	{
     		print '</div>';	// Close current websitebar to open a new one
     
    -		$array=$objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl');
    -		if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors);
    -		$atleastonepage=(is_array($array) && count($array) > 0);
    -
     		print '<div class="centpercent websitebar"'.($style?' style="'.$style.'"':'').'">';
     
     		print '<div class="websiteselection hideonsmartphoneimp minwidth100 tdoverflowmax100">';
    @@ -1551,7 +1839,7 @@ if (count($object->records) > 0)
     					$out.='<option value="'.$key.'"';
     					if ($pageid > 0 && $pageid == $key) $out.=' selected';		// To preselect a value
     					$out.='>';
    -					$out.='['.$valpage->type_container.' '.$valpage->id.'] ';
    +					$out.='['.$valpage->type_container.' '.sprintf("%03d", $valpage->id).'] ';
     					$out.=$valpage->pageurl.' - '.$valpage->title;
     					if ($object->fk_default_home && $key == $object->fk_default_home) $out.=' ('.$langs->trans("HomePage").')';
     					$out.='</option>';
    @@ -1568,7 +1856,7 @@ if (count($object->records) > 0)
     		}
     
     		//print '<input type="submit" class="button" name="refreshpage" value="'.$langs->trans("Load").'"'.($atleastonepage?'':' disabled="disabled"').'>';
    -		print '<input type="image" class="valignbottom" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshpage" value="'.$langs->trans("Load").'"'.($atleastonepage?'':' disabled="disabled"').'>';
    +		print '<input type="image" class="valignmiddle" src="'.img_picto('', 'refresh', '', 0, 1).'" name="refreshpage" value="'.$langs->trans("Load").'"'.($atleastonepage?'':' disabled="disabled"').'>';
     
     
     		// Print nav arrows
    @@ -1600,10 +1888,10 @@ if (count($object->records) > 0)
     			else dol_print_error($db);
     		}
     
    -		if ($pagepreviousid) print '<a href="'.$_SERVER['PHP_SELF'].'?website='.urlencode($object->ref).'&pageid='.$pagepreviousid.'&action='.$action.'">'.img_previous($langs->trans("PreviousContainer")).'</a>';
    -		else print '<span class="opacitymedium">'.img_previous($langs->trans("PreviousContainer")).'</span>';
    -		if ($pagenextid) print '<a href="'.$_SERVER['PHP_SELF'].'?website='.urlencode($object->ref).'&pageid='.$pagenextid.'&action='.$action.'">'.img_next($langs->trans("NextContainer")).'</a>';
    -		else print '<span class="opacitymedium">'.img_next($langs->trans("NextContainer")).'</span>';
    +		if ($pagepreviousid) print '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?website='.urlencode($object->ref).'&pageid='.$pagepreviousid.'&action='.$action.'">'.img_previous($langs->trans("PreviousContainer")).'</a>';
    +		else print '<span class="valignmiddle opacitymedium">'.img_previous($langs->trans("PreviousContainer")).'</span>';
    +		if ($pagenextid) print '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?website='.urlencode($object->ref).'&pageid='.$pagenextid.'&action='.$action.'">'.img_next($langs->trans("NextContainer")).'</a>';
    +		else print '<span class="valignmiddle opacitymedium">'.img_next($langs->trans("NextContainer")).'</span>';
     
     		$websitepage = new WebSitePage($db);
     		if ($pageid > 0 && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone'))
    @@ -1636,11 +1924,13 @@ if (count($object->records) > 0)
     				// Confirmation to clone
     				if ($action == 'createpagefromclone') {
     					// Create an array for form
    +					$preselectedlanguage = GETPOST('newlang', 'az09') ? GETPOST('newlang', 'az09') : ($objectpage->lang ? $objectpage->lang : $langs->defaultlang);
     					$formquestion = array(
    -						array('type' => 'text', 'name' => 'pageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME")  ,'value'=> 'copy_of_'.$objectpage->pageurl),
    -						array('type' => 'checkbox', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0),
    -						array('type' => 'other','name' => 'newlang','label' => $langs->trans("Language"), 'value' => $formadmin->select_language(GETPOST('newlang', 'az09')?GETPOST('newlang', 'az09'):$langs->defaultlang, 'newlang', 0, null, 1, 0, 0, 'minwidth200')),
    -						array('type' => 'other','name' => 'newwebsite','label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)),
    +						array('type' => 'hidden', 'name' => 'sourcepageurl', 'value'=> $objectpage->pageurl),
    +						array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0),
    +						array('type' => 'other','name' => 'newlang', 'label' => $langs->trans("Language"), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, 1, 0, 0, 'minwidth200', 0, 1)),
    +						array('type' => 'other','name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)),
    +						array('type' => 'text', 'tdclass'=>'maxwidth200 fieldrequired', 'name' => 'pageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME"), 'value'=> 'copy_of_'.$objectpage->pageurl),
     					);
     
     				   	$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?website='.$object->ref.'&pageid=' . $pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 300, 550);
    @@ -1651,16 +1941,51 @@ if (count($object->records) > 0)
     				print ' &nbsp; ';
     
     				print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditPageMeta")).'" name="editmeta">';
    +
    +				print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditHTMLSource")).'" name="editsource">';
    +
    +				print '<!-- button EditInLine and ShowSubcontainers -->'."\n";
    +				print '<div class="websiteselectionsection inline-block">';
    +				print '<div class="inline-block">';
    +				print $langs->trans("EditInLine");
     				if ($websitepage->grabbed_from)
     				{
    -					print '<input type="submit" class="button nobordertransp" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'" value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
    +					//print '<input type="submit" class="button nobordertransp" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'" value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
    +					print '<a class="button nobordertransp opacitymedium nohoverborder"'.$disabled.' href="#" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'">'.img_picto($langs->trans("OnlyEditionOfSourceForGrabbedContent"),'switch_off','',false,0,0,'','nomarginleft').'</a>';
     				}
     				else
     				{
    -					print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
    +					//print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditWithEditor")).'" name="editcontent">';
    +					if (empty($conf->global->WEBSITE_EDITINLINE))
    +					{
    +						print '<a class="button nobordertransp nohoverborder"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=seteditinline">'.img_picto($langs->trans("EditInLineOff"),'switch_off','',false,0,0,'','nomarginleft').'</a>';
    +					}
    +					else
    +					{
    +						print '<a class="button nobordertransp nohoverborder"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=unseteditinline">'.img_picto($langs->trans("EditInLineOn"),'switch_on','',false,0,0,'','nomarginleft').'</a>';
    +					}
     				}
    +				print '</div>';
    +				print '<div class="inline-block">';
    +				print $langs->trans("ShowSubcontainers");
    +				/*if ($websitepage->grabbed_from)
    +				{
    +					print '<a class="button nobordertransp opacitymedium nohoverborder"'.$disabled.' href="#" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'">'.img_picto($langs->trans("OnlyEditionOfSourceForGrabbedContent"),'switch_off','',false,0,0,'','nomarginleft').'</a>';
    +				}
    +				else
    +				{*/
    +					if (empty($conf->global->WEBSITE_SUBCONTAINERSINLINE))
    +					{
    +						print '<a class="button nobordertransp nohoverborder"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=setshowsubcontainers">'.img_picto($langs->trans("ShowSubContainersOff"),'switch_off','',false,0,0,'','nomarginleft').'</a>';
    +					}
    +					else
    +					{
    +						print '<a class="button nobordertransp nohoverborder"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=unsetshowsubcontainers">'.img_picto($langs->trans("ShowSubContainersOn"),'switch_on','',false,0,0,'','nomarginleft').'</a>';
    +					}
    +				/*}*/
    +				print '</div>';
    +				print '</div>';
     
    -				print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditHTMLSource")).'" name="editsource">';
     				if ($object->fk_default_home > 0 && $pageid == $object->fk_default_home) print '<input type="submit" class="button nobordertransp" disabled="disabled" value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">';
     				else print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("SetAsHomePage")).'" name="setashome">';
     				print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("ClonePage")).'" name="createpagefromclone">';
    @@ -1674,14 +1999,14 @@ if (count($object->records) > 0)
     
     		if ($pageid > 0 && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone'))
     		{
    -			$realpage=$urlwithroot.'/public/website/index.php?website='.$website.'&pageref='.$websitepage->pageurl;
    +			$realpage=$urlwithroot.'/public/website/index.php?website='.$websitekey.'&pageref='.$websitepage->pageurl;
     			$pagealias = $websitepage->pageurl;
     
     			$htmltext = $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage, $dataroot);
     			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     
    -			print '<a class="websitebuttonsitepreview" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$website.'" alt="'.dol_escape_htmltag($htmltext).'">';
    +			print '<a class="websitebuttonsitepreview" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$websitekey.'" alt="'.dol_escape_htmltag($htmltext).'">';
     			print $form->textwithpicto('', $htmltext, 1, 'preview');
     			print '</a>';       // View page in new Tab
     
    @@ -1692,14 +2017,14 @@ if (count($object->records) > 0)
     			print '</div>';
     
     			$urlext=$virtualurl.'/'.$pagealias.'.php';
    -			$urlint=$urlwithroot.'/public/website/index.php?website='.$website;
    +			$urlint=$urlwithroot.'/public/website/index.php?website='.$websitekey;
     
     			$htmltext = $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $dataroot, $virtualurl?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>');
     
    -			print '<a class="websitebuttonsitepreview'.($virtualurl?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewpageext" href="'.$urlext.'" target="tab'.$website.'ext" alt="'.dol_escape_htmltag($htmltext).'">';
    +			print '<a class="websitebuttonsitepreview'.($virtualurl?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewpageext" href="'.$urlext.'" target="tab'.$websitekey.'ext" alt="'.dol_escape_htmltag($htmltext).'">';
     			print $form->textwithpicto('', $htmltext, 1, 'preview_ext');
     			print '</a>';
    -			//print '<input type="submit" class="button" name="previewpage" target="tab'.$website.'"value="'.$langs->trans("ViewPageInNewTab").'">';
    +			//print '<input type="submit" class="button" name="previewpage" target="tab'.$websitekey.'"value="'.$langs->trans("ViewPageInNewTab").'">';
     
     			// TODO Add js to save alias like we save virtual host name and use dynamic virtual host for url of id=previewpageext
     		}
    @@ -1890,7 +2215,7 @@ if ($action == 'editcss')
     	print '<tr><td class="titlefieldcreate">';
     	print $langs->trans('WebSite');
     	print '</td><td>';
    -	print $website;
    +	print $websitekey;
     	print '</td></tr>';
     
     	// CSS file
    @@ -1971,7 +2296,7 @@ if ($action == 'createsite')
     
         dol_fiche_head($head, 'card', $langs->trans("AddSite"), -1, 'globe');
         */
    -	if ($action == 'createcontainer') print_fiche_titre($langs->trans("AddSite"));
    +	if ($action == 'createcontainer') print load_fiche_titre($langs->trans("AddSite"));
     
     	print '<!-- Add site -->'."\n";
     	//print '<div class="fichecenter">';
    @@ -1997,7 +2322,7 @@ if ($action == 'createsite')
     	$htmltext = $langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/website/<i>websiteref</i>');
     	$htmltext.='<br>';
     	$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -	$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +	$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     
     	print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, 'tooltipvirtual');
     	print '</td><td>';
    @@ -2027,6 +2352,27 @@ if ($action == 'createsite')
     	print '<br>';
     }
     
    +if ($action == 'importsite')
    +{
    +	print '<div class="fiche">';
    +
    +	print '<br>';
    +
    +	print load_fiche_titre($langs->trans("ImportSite"));
    +
    +	dol_fiche_head(array(), '0', '', -1);
    +
    +	print $langs->trans("ZipOfWebsitePackageToImport").'<br><br>';
    +
    +	print '<input class="flat minwidth400" type="file" name="userfile[]" accept=".zip">';
    +	print '<input type="submit" class="button" name="buttonsubmitimportfile" value="'.dol_escape_htmltag($langs->trans("Upload")).'">';
    +
    +	dol_fiche_end();
    +
    +	print '</div>';
    +
    +	print '<br>';
    +}
     
     if ($action == 'editmeta' || $action == 'createcontainer')
     {
    @@ -2044,7 +2390,7 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     
         dol_fiche_head($head, 'card', $langs->trans("AddPage"), -1, 'globe');
         */
    -	if ($action == 'createcontainer') print_fiche_titre($langs->trans("AddPage"));
    +	if ($action == 'createcontainer') print load_fiche_titre($langs->trans("AddPage"));
     
     	print '<!-- Edit or create page/container -->'."\n";
     	//print '<div class="fichecenter">';
    @@ -2058,6 +2404,7 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     		print '<tr><td class="titlefield">';
     		print $langs->trans("URL");
     		print '</td><td>';
    +		print info_admin($langs->trans("OnlyEditionOfSourceForGrabbedContentFuture"), 0, 0, 'warning');
     		print '<input class="flat minwidth300" type="text" name="externalurl" value="'.dol_escape_htmltag(GETPOST('externalurl','alpha')).'" placeholder="https://externalsite/pagetofetch"> ';
     		print '<input class="flat paddingtop" type="checkbox" name="grabimages" value="1" checked="checked"> '.$langs->trans("GrabImagesInto");
     		print ' ';
    @@ -2066,7 +2413,6 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     		print $form->selectarray('grabimagesinto', $arraygrabimagesinto, GETPOSTISSET('grabimagesinto')?GETPOST('grabimagesinto'):'root');
     		print '<br>';
     		print '<input class="button" style="margin-top: 5px" type="submit" name="fetchexternalurl" value="'.dol_escape_htmltag($langs->trans("FetchAndCreate")).'">';
    -		print '<br>'.info_admin($langs->trans("OnlyEditionOfSourceForGrabbedContentFuture"), 0, 0, '1');
     		print '</td></tr>';
     		print '</table>';
     
    @@ -2086,9 +2432,9 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     		print '</td></tr>';
     
     		print '<tr><td class="titlefield">';
    -		print $langs->trans('WEBSITE_PAGEURL');
    +		print $langs->trans('InternalURLOfPage');
     		print '</td><td>';
    -		print '/public/website/index.php?website='.urlencode($website).'&pageid='.urlencode($pageid);
    +		print '/public/website/index.php?website='.urlencode($websitekey).'&pageid='.urlencode($pageid);
     		print '</td></tr>';
     
     		/*
    @@ -2107,10 +2453,15 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     		$pagekeywords=$objectpage->keywords;
     		$pagelang=$objectpage->lang;
     		$pagehtmlheader=$objectpage->htmlheader;
    +		$pagedatecreation=$objectpage->date_creation;
    +		$pagedatemodification=$objectpage->date_modification;
    +		$pageauthorid=$objectpage->fk_user_create;
     	}
     	else
     	{
     		$type_container = 'page';
    +		$pagedatecreation=dol_now();
    +		$pageauthorid=$user->id;
     	}
     	if (GETPOST('WEBSITE_TITLE','alpha'))       $pagetitle=GETPOST('WEBSITE_TITLE','alpha');
     	if (GETPOST('WEBSITE_PAGENAME','alpha'))    $pageurl=GETPOST('WEBSITE_PAGENAME','alpha');
    @@ -2134,6 +2485,7 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     	print '<input type="text" class="flat minwidth300" name="WEBSITE_PAGENAME" id="WEBSITE_PAGENAME" value="'.dol_escape_htmltag($pageurl).'">';
     	print '</td></tr>';
     
    +	// Type of container
     	print '<tr><td class="titlefield fieldrequired">';
     	print $langs->trans('WEBSITE_TYPE_CONTAINER');
     	print '</td><td>';
    @@ -2167,6 +2519,53 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     	print $formadmin->select_language($pagelang?$pagelang:$langs->defaultlang, 'WEBSITE_LANG', 0, null, '1');
     	print '</td></tr>';
     
    +	if ($action != 'createcontainer')
    +	{
    +		// Translation of
    +		if ($objectpage->fk_page > 0)
    +		{
    +			print '<tr><td>';
    +			print $langs->trans('ThisPageIsTranslationOf');
    +			print '</td><td>';
    +			$sourcepage=new WebsitePage($db);
    +			$result = $sourcepage->fetch($objectpage->fk_page);
    +			if ($result == 0)	// not found, we can reset value
    +			{
    +
    +			}
    +			elseif ($result > 0)
    +			{
    +				print $sourcepage->getNomUrl(1);
    +			}
    +			print '</td></tr>';
    +		}
    +
    +		// Has translation pages
    +		$sql='SELECT rowid, lang from '.MAIN_DB_PREFIX.'website_page where fk_page = '.$objectpage->id;
    +		$resql = $db->query($sql);
    +		if ($resql)
    +		{
    +			$num_rows = $db->num_rows($resql);
    +			if ($num_rows > 0)
    +			{
    +				print '<tr><td>';
    +				print $langs->trans('ThisPageHasTranslationPages');
    +				print '</td><td>';
    +				$i=0;
    +				while ($obj = $db->fetch_object($resql))
    +				{
    +					$tmppage=new WebsitePage($db);
    +					$tmppage->fetch($obj->rowid);
    +					if ($i > 0) print ' - ';
    +					print $tmppage->getNomUrl(1).' ('.$tmppage->lang.')';
    +					$i++;
    +				}
    +				print '</td></tr>';
    +			}
    +		}
    +		else dol_print_error($db);
    +	}
    +
     	print '<tr><td class="titlefieldcreate">';
     	$htmlhelp=$langs->trans("WEBSITE_ALIASALTDesc");
     	print $form->textwithpicto($langs->trans('WEBSITE_ALIASALT'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
    @@ -2174,13 +2573,37 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     	print '<input type="text" class="flat minwidth300" name="WEBSITE_ALIASALT" value="'.dol_escape_htmltag($pagealiasalt).'">';
     	print '</td></tr>';
     
    +	$fuser=new User($db);
    +	$fuser->fetch($pageauthorid);
    +
    +	print '<tr><td>';
    +	print $langs->trans('Author');
    +	print '</td><td>';
    +	if ($pageauthorid > 0) print $fuser->getNomUrl(1);
    +	print '</td></tr>';
    +
    +	print '<tr><td>';
    +	print $langs->trans('DateCreation');
    +	print '</td><td>';
    +	print dol_print_date($pagedatecreation, 'dayhour');
    +	print '</td></tr>';
    +
    +	if ($action != 'createcontainer')
    +	{
    +		print '<tr><td>';
    +		print $langs->trans('DateModification');
    +		print '</td><td>';
    +		print dol_print_date($pagedatemodification, 'dayhour');
    +		print '</td></tr>';
    +	}
    +
     	print '<tr><td class="tdhtmlheader tdtop">';
     	$htmlhelp=$langs->trans("EditTheWebSiteForACommonHeader").'<br><br>';
     	$htmlhelp=$langs->trans("Example").' :<br>';
     	$htmlhelp.=dol_htmlentitiesbr($htmlheadercontentdefault);
     	print $form->textwithpicto($langs->trans('HtmlHeaderPage'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
     	print '</td><td>';
    -	$doleditor=new DolEditor('htmlheader', $pagehtmlheader, '', '180', 'ace', 'In', true, false, 'ace', 0, '100%', '');
    +	$doleditor=new DolEditor('htmlheader', $pagehtmlheader, '', '120', 'ace', 'In', true, false, 'ace', ROWS_3, '100%', '');
     	print $doleditor->Create(1, '', true, 'HTML Header', 'html');
     	print '</td></tr>';
     
    @@ -2235,7 +2658,6 @@ if ($action == 'editfile' || $action == 'file_manager')
     	include DOL_DOCUMENT_ROOT.'/core/tpl/filemanager.tpl.php';
     
     	print '</div>';
    -
     }
     
     if ($action == 'editmenu')
    @@ -2246,31 +2668,34 @@ if ($action == 'editmenu')
     
     if ($action == 'editsource')
     {
    -	/*
    -	 * Editing with source editor
    -	 */
    +	// Editing with source editor
     
     	$contentforedit = '';
    -	/*$contentforedit.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". Not yet supported by browsers
    -	 $contentforedit.=$csscontent;
    -	 $contentforedit.='</style>'."\n";*/
    +	//$contentforedit.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". Not yet supported by browsers
    +	//$contentforedit.=$csscontent;
    +	//$contentforedit.='</style>'."\n";
     	$contentforedit .= $objectpage->content;
    -
    +	//var_dump($_SESSION["dol_screenheight"]);
    +	$maxheightwin=480;
    +	if (isset($_SESSION["dol_screenheight"]))
    +	{
    +		if ($_SESSION["dol_screenheight"] > 680) $maxheightwin = $_SESSION["dol_screenheight"]-400;
    +		if ($_SESSION["dol_screenheight"] > 800) $maxheightwin = $_SESSION["dol_screenheight"]-490;
    +	}
    +	//var_dump($_SESSION["dol_screenheight"]);
     	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
    -	$doleditor=new DolEditor('PAGE_CONTENT',$contentforedit,'',500,'Full','',true,true,'ace',ROWS_5,'90%');
    +	$doleditor=new DolEditor('PAGE_CONTENT',$contentforedit,'',$maxheightwin,'Full','',true,true,'ace',ROWS_5,'40%');
     	$doleditor->Create(0, '', false, 'HTML Source', 'php');
     }
     
    -if ($action == 'editcontent')
    +/*if ($action == 'editcontent')
     {
    -	/*
    -     * Editing with default ckeditor
    -     */
    +	// Editing with default ckeditor
     
     	$contentforedit = '';
    -	/*$contentforedit.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". Not yet supported by browsers
    -    $contentforedit.=$csscontent;
    -    $contentforedit.='</style>'."\n";*/
    +	//$contentforedit.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". Not yet supported by browsers
    +    //$contentforedit.=$csscontent;
    +    //$contentforedit.='</style>'."\n";
     	$contentforedit .= $objectpage->content;
     
     	$contentforedit = preg_replace('/(<img.*src=")(?!http)/', '\1'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $contentforedit, -1, $nbrep);
    @@ -2278,40 +2703,50 @@ if ($action == 'editcontent')
     	require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
     	$doleditor=new DolEditor('PAGE_CONTENT',$contentforedit,'',500,'Full','',true,true,true,ROWS_5,'90%');
     	$doleditor->Create(0, '', false);
    -}
    +}*/
     
     print "</div>\n</form>\n";
     
     
    -
     if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone')
     {
     	if ($pageid > 0)
     	{
    +		// $filejs
    +		// $filecss
    +		// $filephp
    +
     		// Ouput page under the Dolibarr top menu
     		$objectpage->fetch($pageid);
    -		$csscontent = @file_get_contents($filecss);
     		$jscontent = @file_get_contents($filejs);
     
    -		$out = '<!-- Page content '.$filetpl.' : Div with (CSS Of website from file + Style/htmlheader of page from database + Page content from database) -->'."\n";
    +		$out = '<!-- Page content '.$filetpl.' : Div with (CSS Of website from file + Style/htmlheader of page from database + Page content from database or by include if WEBSITE_SUBCONTAINERSINLINE is on) -->'."\n";
     
     		// Include a html so we can benefit of the header of page.
     		// Note: We can't use iframe as it can be used to include another external html file
     		// Note: We can't use frame as it is deprecated.
    +		/*if ($includepageintoaframeoradiv == 'iframe')
    +		{
    +			$out .= "<iframe><body></html>";
    +		}*/
     		$out.="\n<html><head>\n";
     		$out.=dolWebsiteReplacementOfLinks($object, $objectpage->htmlheader, 1);
     		$out.="</head>\n";
     		$out.="\n<body>";
     
    -		$out.='<div id="websitecontentundertopmenu" class="websitecontentundertopmenu">'."\n";
     
    -		// Note: <div> or <section> with contenteditable="true" inside this can be edited with inline ckeditor
    +		$out.='<div id="websitecontentundertopmenu" class="websitecontentundertopmenu">'."\n";
     
     		// REPLACEMENT OF LINKS When page called by website editor
     
     		$out.='<style scoped>'."\n";        // "scoped" means "apply to parent element only". No more supported by browsers, snif !
     		$tmpout='';
     		$tmpout.= '/* Include website CSS file */'."\n";
    +		//$csscontent = @file_get_contents($filecss);
    +		ob_start();
    +		include $filecss;
    +		$csscontent = ob_get_contents();
    +		ob_end_clean();
     		$tmpout.= dolWebsiteReplacementOfLinks($object, $csscontent, 1);
     		$tmpout.= '/* Include style from the HTML header of page */'."\n";
     		// Clean the html header of page to get only <style> content
    @@ -2329,12 +2764,38 @@ if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpa
     		$out.=$tmpout;
     		$out.='</style>'."\n";
     
    +		// Note: <div> or <section> with contenteditable="true" inside this can be edited with inline ckeditor
    +
     		// Do not enable the contenteditable when page was grabbed, ckeditor is removing span and adding borders,
     		// so editable will be available only from container created from scratch
     		//$out.='<div id="bodywebsite" class="bodywebsite"'.($objectpage->grabbed_from ? ' contenteditable="true"' : '').'>'."\n";
    -		$out.='<div id="bodywebsite" class="bodywebsite">'."\n";
    +		$out.='<div id="divbodywebsite" class="bodywebsite">'."\n";
     
    -		$out.=dolWebsiteReplacementOfLinks($object, $objectpage->content)."\n";
    +		$newcontent = $objectpage->content;
    +
    +		// If mode WEBSITE_SUBCONTAINERSINLINE is on
    +		if (! empty($conf->global->WEBSITE_SUBCONTAINERSINLINE))
    +		{
    +			define('USEDOLIBARREDITOR', 1);
    +			//var_dump($filetpl);
    +			$filephp = $filetpl;
    +			ob_start();
    +			include $filephp;
    +			$newcontent = ob_get_contents();
    +			ob_end_clean();
    +		}
    +
    +		// Change the contenteditable to "true" or "false" when mode Edit Inline is on or off
    +		if (empty($conf->global->WEBSITE_EDITINLINE))
    +		{
    +			$newcontent = preg_replace('/(div|section)(\s[^\>]*)contenteditable="true"/', '\1\2', $newcontent);
    +		}
    +		else
    +		{
    +			// TODO Add the contenteditable="true" when mode Edit Inline is on
    +		}
    +
    +		$out.=dolWebsiteReplacementOfLinks($object, $newcontent)."\n";
     
     		$out.='</div>';
     
    @@ -2348,9 +2809,6 @@ if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpa
     
     		$out.= "\n".'<!-- End page content '.$filetpl.' -->'."\n\n";
     
    -		// For jqueryscoped (does not work as expected)
    -		//$out.="<script>$.scoped();</script>";
    -
     		print $out;
     
     		/*file_put_contents($filetpl, $out);
    @@ -2371,18 +2829,16 @@ if ($action == 'preview' || $action == 'createfromclone' || $action == 'createpa
             //include_once $original_file_osencoded;
             */
     
    -		/*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/website/index.php?website='.$website.'&pageid='.$pageid.'"/>';
    +		/*print '<iframe class="websiteiframenoborder centpercent" src="'.DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$pageid.'"/>';
             print '</iframe>';*/
     	}
     	else
     	{
    -		print '<br><br><div class="center">'.$langs->trans("PreviewOfSiteNotYetAvailable", $website).'</center><br><br><br>';
    +		print '<br><br><div class="center">'.$langs->trans("PreviewOfSiteNotYetAvailable", $object->ref).'</center><br><br><br>';
     		print '<div class="center"><div class="logo_setup"></div></div>';
     	}
     }
     
    -
    -
    +// End of page
     llxFooter();
    -
     $db->close();
    diff --git a/htdocs/website/websiteaccount_card.php b/htdocs/website/websiteaccount_card.php
    index 9a1ad910672..49965b9009a 100644
    --- a/htdocs/website/websiteaccount_card.php
    +++ b/htdocs/website/websiteaccount_card.php
    @@ -22,24 +22,11 @@
      */
     
     // Load Dolibarr environment
    -$res=0;
    -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined)
    -if (! $res && ! empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res=@include($_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php");
    -// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME
    -$tmp=empty($_SERVER['SCRIPT_FILENAME'])?'':$_SERVER['SCRIPT_FILENAME'];$tmp2=realpath(__FILE__); $i=strlen($tmp)-1; $j=strlen($tmp2)-1;
    -while($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i]==$tmp2[$j]) { $i--; $j--; }
    -if (! $res && $i > 0 && file_exists(substr($tmp, 0, ($i+1))."/main.inc.php")) $res=@include(substr($tmp, 0, ($i+1))."/main.inc.php");
    -if (! $res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php")) $res=@include(dirname(substr($tmp, 0, ($i+1)))."/main.inc.php");
    -// Try main.inc.php using relative path
    -if (! $res && file_exists("../main.inc.php")) $res=@include("../main.inc.php");
    -if (! $res && file_exists("../../main.inc.php")) $res=@include("../../main.inc.php");
    -if (! $res && file_exists("../../../main.inc.php")) $res=@include("../../../main.inc.php");
    -if (! $res) die("Include of main fails");
    -
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php');
    -include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php');
    -include_once(DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php');
    -include_once(DOL_DOCUMENT_ROOT.'/website/lib/websiteaccount.lib.php');
    +require '../main.inc.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
    +require_once DOL_DOCUMENT_ROOT.'/website/lib/websiteaccount.lib.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("website","other"));
    @@ -220,12 +207,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	    $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteWebsiteAccount'), $langs->trans('ConfirmDeleteWebsiteAccount'), 'confirm_delete', '', 0, 1);
     	}
     
    -	if (! $formconfirm) {
    -	    $parameters = array('lineid' => $lineid);
    -	    $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    -	    if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    -	    elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
    -	}
    +	// Call Hook formConfirm
    +	$parameters = array('lineid' => $lineid);
    +	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
    +	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
    +	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
     
     	// Print form confirm
     	print $formconfirm;
    @@ -395,7 +381,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
     }
     
    -
     // End of page
     llxFooter();
     $db->close();
    diff --git a/scripts/accountancy/export-thirdpartyaccount.php b/scripts/accountancy/export-thirdpartyaccount.php
    index 2d557768d7d..ad5d6b72650 100755
    --- a/scripts/accountancy/export-thirdpartyaccount.php
    +++ b/scripts/accountancy/export-thirdpartyaccount.php
    @@ -1,8 +1,9 @@
     #!/usr/bin/env php
     <?php
    -/* Copyright (C) 2013-2014 Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2013-2014 Alexandre Spangaro	<aspangaro.dolibarr@gmail.com>
    - * Copyright (C) 2014	   Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2013-2014  Olivier Geffroy     <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2014  Alexandre Spangaro  <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2014       Florian Henry       <florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * 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
    @@ -24,14 +25,11 @@
      * \brief		Page to detect empty accounting account
      */
     
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
     
    -$langs->load("companies");
    -$langs->load("compta");
    -$langs->load("main");
    -$langs->load("accountancy");
    +$langs->loadLangs(array("companies", "compta", "main", "accountancy"));
     
     // Security check
     if (!$user->admin)
    @@ -102,7 +100,7 @@ $periodlink = '';
     $exportlink = '';
     
     $nom = $langs->trans("ReportThirdParty");
    -$period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1);
    +$period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
     $description = $langs->trans("DescThirdPartyReport");
     $builddate=dol_now();
     
    diff --git a/scripts/bank/export-bank-receipts.php b/scripts/bank/export-bank-receipts.php
    index 398ec1d7a19..84af2e27f9f 100755
    --- a/scripts/bank/export-bank-receipts.php
    +++ b/scripts/bank/export-bank-receipts.php
    @@ -33,7 +33,7 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
    @@ -108,13 +108,9 @@ if (! empty($newlangid))
     		$outputlangs->setDefaultLang($newlangid);
     	}
     }
    -$outputlangs->load("main");
    -$outputlangs->load("bills");
    -$outputlangs->load("companies");
    -$outputlangs->load("banks");
    -$outputlangs->load("members");
    -$outputlangs->load("compta");
     
    +// Load translation files required by the page
    +$outputlangs->loadLangs(array("main", "companies", "bills", "banks", "members", "compta"));
     
     $acct=new Account($db);
     $result=$acct->fetch('',$bankref);
    diff --git a/scripts/company/export-contacts-xls-example.php b/scripts/company/export-contacts-xls-example.php
    index 5fd7806a26c..c4887cb5ee1 100755
    --- a/scripts/company/export-contacts-xls-example.php
    +++ b/scripts/company/export-contacts-xls-example.php
    @@ -41,13 +41,13 @@ if (! isset($argv[1]) || ! $argv[1]) {
     $now=$argv[1];
     
     
    -require_once($path."../../htdocs/master.inc.php");
    -//require_once(PHP_WRITEEXCEL_PATH."/class.writeexcel_workbook.inc.php");
    -//require_once(PHP_WRITEEXCEL_PATH."/class.writeexcel_worksheet.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
    +//require_once PHP_WRITEEXCEL_PATH."/class.writeexcel_workbook.inc.php";
    +//require_once PHP_WRITEEXCEL_PATH."/class.writeexcel_worksheet.inc.php";
     
    -require_once(PHPEXCEL_PATH."/PHPExcel.php");
    -//require_once(PHPEXCEL_PATH."/PHPExcel/Writer/Excel2007.php");
    -require_once(PHPEXCEL_PATH."/PHPExcel/Writer/Excel5.php");
    +require_once PHPEXCEL_PATH."/PHPExcel.php";
    +//require_once PHPEXCEL_PATH."/PHPExcel/Writer/Excel2007.php";
    +require_once PHPEXCEL_PATH."/PHPExcel/Writer/Excel5.php";
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/company/sync_contacts_dolibarr2ldap.php b/scripts/company/sync_contacts_dolibarr2ldap.php
    index 900cdbc35ed..32260291aa7 100755
    --- a/scripts/company/sync_contacts_dolibarr2ldap.php
    +++ b/scripts/company/sync_contacts_dolibarr2ldap.php
    @@ -35,10 +35,10 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     }
     
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/contact/class/contact.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/contact/class/contact.class.php";
    +require_once DOL_DOCUMENT_ROOT."/user/class/user.class.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/contracts/email_expire_services_to_customers.php b/scripts/contracts/email_expire_services_to_customers.php
    index 0f5c91817db..43a0b2524e6 100755
    --- a/scripts/contracts/email_expire_services_to_customers.php
    +++ b/scripts/contracts/email_expire_services_to_customers.php
    @@ -50,12 +50,10 @@ $mode=$argv[1];
     $targettype=$argv[2];
     
     
    -require($path."../../htdocs/master.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php");
    -
    -$langs->load('main');
    -$langs->load('contracts');
    +require $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php";
     
    +$langs->loadLangs(array('main', 'contracts'));
     
     // Global variables
     $version=DOL_VERSION;
    @@ -154,10 +152,9 @@ if ($resql)
                 // Define line content
                 $outputlangs=new Translate('',$conf);
                 $outputlangs->setDefaultLang(empty($obj->default_lang)?$langs->defaultlang:$obj->default_lang);	// By default language of customer
    -            $outputlangs->load("bills");
    -            $outputlangs->load("main");
    -            $outputlangs->load("contracts");
    -    		$outputlangs->load("products");
    +
    +            // Load translation files required by the page
    +            $outputlangs->loadLangs(array("main", "contracts", "bills", "products"));
     
                 if (dol_strlen($newemail))
                 {
    diff --git a/scripts/contracts/email_expire_services_to_representatives.php b/scripts/contracts/email_expire_services_to_representatives.php
    index ad7ccebcba7..a23652a779f 100755
    --- a/scripts/contracts/email_expire_services_to_representatives.php
    +++ b/scripts/contracts/email_expire_services_to_representatives.php
    @@ -48,12 +48,10 @@ if (! isset($argv[1]) || ! $argv[1] || ! in_array($argv[1],array('test','confirm
     $mode=$argv[1];
     
     
    -require($path."../../htdocs/master.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php");
    -
    -$langs->load('main');
    -$langs->load('contracts');
    +require $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php";
     
    +$langs->loadLangs(array('main', 'contracts'));
     
     // Global variables
     $version=DOL_VERSION;
    @@ -127,10 +125,9 @@ if ($resql)
                 // Define line content
                 $outputlangs=new Translate('',$conf);
                 $outputlangs->setDefaultLang(empty($obj->lang)?$langs->defaultlang:$obj->lang);	// By default language of sale representative
    -            $outputlangs->load("bills");
    -            $outputlangs->load("main");
    -    		$outputlangs->load("contracts");
    -            $outputlangs->load("products");
    +
    +            // Load translation files required by the page
    +            $outputlangs->loadLangs(array("main", "contracts", "bills", "products"));
     
                 if (dol_strlen($obj->email))
                 {
    diff --git a/scripts/cron/cron_run_jobs.php b/scripts/cron/cron_run_jobs.php
    index 4e3cefce5af..6104cec3b55 100755
    --- a/scripts/cron/cron_run_jobs.php
    +++ b/scripts/cron/cron_run_jobs.php
    @@ -41,9 +41,9 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once ($path."../../htdocs/master.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/cron/class/cronjob.class.php");
    -require_once (DOL_DOCUMENT_ROOT.'/user/class/user.class.php');
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/cron/class/cronjob.class.php";
    +require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
     
     // Check parameters
     if (! isset($argv[1]) || ! $argv[1]) {
    @@ -223,7 +223,6 @@ if (is_array($qualifiedjobs) && (count($qualifiedjobs)>0))
     				dol_syslog("cron_run_jobs.php::reprogram_jobs Error ".$cronjob->error, LOG_ERR);
     				exit(-1);
     			}
    -
     		}
     		else
     		{
    @@ -245,6 +244,13 @@ exit(0);
     
     
     
    +/**
    + * script cron usage
    + *
    + * @param string $path          path
    + * @param string $script_file   filename
    + * @return void
    + */
     function usage($path,$script_file)
     {
     	global $conf;
    @@ -258,4 +264,3 @@ function usage($path,$script_file)
     	print "For example, to run pending tasks every 5mn, you can add this line:\n";
     	print "*/5 * * * * ".$path.$script_file." securitykey userlogin > ".DOL_DATA_ROOT."/".$script_file.".log\n";
     }
    -
    diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php
    index ef9a35fc1ed..c36e7ea1cc3 100755
    --- a/scripts/emailings/mailing-send.php
    +++ b/scripts/emailings/mailing-send.php
    @@ -44,9 +44,9 @@ $id=$argv[1];
     if (isset($argv[2]) || !empty($argv[2])) $login = $argv[2];
     else $login = '';
     
    -require_once ($path."../../htdocs/master.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php");
    -require_once (DOL_DOCUMENT_ROOT."/comm/mailing/class/mailing.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php";
    +require_once DOL_DOCUMENT_ROOT."/comm/mailing/class/mailing.class.php";
     
     
     // Global variables
    @@ -64,7 +64,6 @@ print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n";
     
     if ($conf->global->MAILING_LIMIT_SENDBYCLI == '-1')
     {
    -
     }
     
     $user = new User($db);
    @@ -329,7 +328,6 @@ if ($resql)
     								if (!empty($conf->global->MAILING_DELAY)) {
     									sleep($conf->global->MAILING_DELAY);
     								}
    -
     							}
     						}
     						else
    diff --git a/scripts/invoices/email_unpaid_invoices_to_customers.php b/scripts/invoices/email_unpaid_invoices_to_customers.php
    index 02e9db2e0ce..5d49beca851 100755
    --- a/scripts/invoices/email_unpaid_invoices_to_customers.php
    +++ b/scripts/invoices/email_unpaid_invoices_to_customers.php
    @@ -50,8 +50,8 @@ $mode=$argv[1];
     $targettype=$argv[2];
     
     
    -require($path."../../htdocs/master.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php");
    +require $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php";
     
     $langs->load('main');
     
    @@ -151,8 +151,9 @@ if ($resql)
                 // Define line content
                 $outputlangs=new Translate('',$conf);
                 $outputlangs->setDefaultLang(empty($obj->default_lang)?$langs->defaultlang:$obj->default_lang);	// By default language of customer
    -            $outputlangs->load("bills");
    -            $outputlangs->load("main");
    +
    +            // Load translation files required by the page
    +            $outputlangs->loadLangs(array("main", "bills"));
     
                 if (dol_strlen($newemail))
                 {
    diff --git a/scripts/invoices/email_unpaid_invoices_to_representatives.php b/scripts/invoices/email_unpaid_invoices_to_representatives.php
    index e134d693d74..54be6f8f40c 100755
    --- a/scripts/invoices/email_unpaid_invoices_to_representatives.php
    +++ b/scripts/invoices/email_unpaid_invoices_to_representatives.php
    @@ -48,8 +48,8 @@ if (! isset($argv[1]) || ! $argv[1] || ! in_array($argv[1],array('test','confirm
     $mode=$argv[1];
     
     
    -require($path."../../htdocs/master.inc.php");
    -require_once (DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php");
    +require $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/CMailFile.class.php";
     
     $langs->load('main');
     
    @@ -131,8 +131,9 @@ if ($resql)
                 // Define line content
                 $outputlangs=new Translate('',$conf);
                 $outputlangs->setDefaultLang(empty($obj->lang)?$langs->defaultlang:$obj->lang);	// By default language of sale representative
    -            $outputlangs->load("bills");
    -            $outputlangs->load("main");
    +
    +            // Load translation files required by the page
    +            $outputlangs->loadLangs(array("main", "bills"));
     
                 if (dol_strlen($obj->email))
                 {
    diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php
    index 30782d3b913..2c71d9cf750 100755
    --- a/scripts/invoices/rebuild_merge_pdf.php
    +++ b/scripts/invoices/rebuild_merge_pdf.php
    @@ -34,12 +34,12 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     }
     
     // Include Dolibarr environment
    -require_once($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     // After this $db is an opened handler to database. We close it at end of file.
    -require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
    -require_once(DOL_DOCUMENT_ROOT.'/core/lib/invoice2.lib.php');
    +require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
    +require_once DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
    +require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice2.lib.php';
     
     
     // Load main language strings
    diff --git a/scripts/members/sync_members_dolibarr2ldap.php b/scripts/members/sync_members_dolibarr2ldap.php
    index a0c393d01c2..e3ca5f38e0a 100755
    --- a/scripts/members/sync_members_dolibarr2ldap.php
    +++ b/scripts/members/sync_members_dolibarr2ldap.php
    @@ -34,9 +34,9 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php";
     
     $langs->load("main");
     
    diff --git a/scripts/members/sync_members_ldap2dolibarr.php b/scripts/members/sync_members_ldap2dolibarr.php
    index e7adb80e733..d7d4fbdeaaf 100755
    --- a/scripts/members/sync_members_ldap2dolibarr.php
    +++ b/scripts/members/sync_members_ldap2dolibarr.php
    @@ -34,15 +34,13 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/adherents/class/subscription.class.php");
    -
    -$langs->load("main");
    -$langs->load("errors");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent.class.php";
    +require_once DOL_DOCUMENT_ROOT."/adherents/class/subscription.class.php";
     
    +$langs->loadLangs(array("main", "errors"));
     
     // Global variables
     $version=DOL_VERSION;
    @@ -301,7 +299,6 @@ if ($result >= 0)
     				//print "yy".dol_print_date($datelast)."\n";
     				$crowid=$member->subscription($datelast, $pricelast, 0);
     			}
    -
     		}
     
     		if (! $error || $forcecommit)
    diff --git a/scripts/members/sync_members_types_dolibarr2ldap.php b/scripts/members/sync_members_types_dolibarr2ldap.php
    index 939a98c8728..dac7ccfd0bc 100755
    --- a/scripts/members/sync_members_types_dolibarr2ldap.php
    +++ b/scripts/members/sync_members_types_dolibarr2ldap.php
    @@ -41,9 +41,9 @@ if (! isset($argv[1]) || ! $argv[1]) {
     }
     $now=$argv[1];
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php";
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/members/sync_members_types_ldap2dolibarr.php b/scripts/members/sync_members_types_ldap2dolibarr.php
    index 55d5606cd30..27d7be686eb 100755
    --- a/scripts/members/sync_members_types_ldap2dolibarr.php
    +++ b/scripts/members/sync_members_types_ldap2dolibarr.php
    @@ -36,14 +36,12 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php");
    -
    -$langs->load("main");
    -$langs->load("errors");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/adherents/class/adherent_type.class.php";
     
    +$langs->loadLangs(array("main", "errors"));
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/modulebuilder/builddoc.php b/scripts/modulebuilder/builddoc.php
    index f2c0eef421f..c0b44a0bed8 100755
    --- a/scripts/modulebuilder/builddoc.php
    +++ b/scripts/modulebuilder/builddoc.php
    @@ -45,7 +45,7 @@ if (! isset($argv[1]) || ! $argv[1]) {
     }
     $modulename=$argv[1];
     
    -require_once ($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
    diff --git a/scripts/modulebuilder/initmodule.php b/scripts/modulebuilder/initmodule.php
    index 6c9801878d3..bee931dc8fa 100755
    --- a/scripts/modulebuilder/initmodule.php
    +++ b/scripts/modulebuilder/initmodule.php
    @@ -41,7 +41,7 @@ if (! isset($argv[1]) || ! $argv[1]) {
     }
     $modulename=$argv[1];
     
    -require_once ($path."../../htdocs/master.inc.php");
    +require_once $path."../../htdocs/master.inc.php";
     require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
     require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
    diff --git a/scripts/product/migrate_picture_path.php b/scripts/product/migrate_picture_path.php
    index d72c60f05e5..eee15cdb7fa 100755
    --- a/scripts/product/migrate_picture_path.php
    +++ b/scripts/product/migrate_picture_path.php
    @@ -37,9 +37,9 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     define('EVEN_IF_ONLY_LOGIN_ALLOWED',1);		// Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only".
     
     // Include and load Dolibarr environment variables
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
     // After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file).
     // $user is created but empty.
     
    @@ -140,7 +140,6 @@ function migrate_product_photospath($product)
         				{
         					dol_move($origin.'/'.$file, $destin.'/'.$file);
         				}
    -
         			}
         		}
             }
    diff --git a/scripts/product/regenerate_thumbs.php b/scripts/product/regenerate_thumbs.php
    index bc3e1f53a6b..a4d114746c2 100755
    --- a/scripts/product/regenerate_thumbs.php
    +++ b/scripts/product/regenerate_thumbs.php
    @@ -37,10 +37,10 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     define('EVEN_IF_ONLY_LOGIN_ALLOWED',1);		// Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only".
     
     // Include and load Dolibarr environment variables
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/images.lib.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/product/class/product.class.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/images.lib.php";
     // After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file).
     // $user is created but empty.
     
    diff --git a/scripts/user/sync_groups_dolibarr2ldap.php b/scripts/user/sync_groups_dolibarr2ldap.php
    index e661a85beb5..ba304305696 100755
    --- a/scripts/user/sync_groups_dolibarr2ldap.php
    +++ b/scripts/user/sync_groups_dolibarr2ldap.php
    @@ -40,9 +40,9 @@ if (! isset($argv[1]) || ! $argv[1]) {
     }
     $now=$argv[1];
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/user/class/usergroup.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/user/class/usergroup.class.php";
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/user/sync_groups_ldap2dolibarr.php b/scripts/user/sync_groups_ldap2dolibarr.php
    index cb745d9aff3..4063d2f9321 100755
    --- a/scripts/user/sync_groups_ldap2dolibarr.php
    +++ b/scripts/user/sync_groups_ldap2dolibarr.php
    @@ -35,15 +35,13 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/user/class/usergroup.class.php");
    -
    -$langs->load("main");
    -$langs->load("errors");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/user/class/user.class.php";
    +require_once DOL_DOCUMENT_ROOT."/user/class/usergroup.class.php";
     
    +$langs->loadLangs(array("main", "errors"));
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/user/sync_users_dolibarr2ldap.php b/scripts/user/sync_users_dolibarr2ldap.php
    index dd5e3d18de4..fa97c871a50 100755
    --- a/scripts/user/sync_users_dolibarr2ldap.php
    +++ b/scripts/user/sync_users_dolibarr2ldap.php
    @@ -40,9 +40,9 @@ if (! isset($argv[1]) || ! $argv[1]) {
     }
     $now=$argv[1];
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/user/class/user.class.php";
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/user/sync_users_ldap2dolibarr.php b/scripts/user/sync_users_ldap2dolibarr.php
    index 9a04f81c557..320a1f495ad 100755
    --- a/scripts/user/sync_users_ldap2dolibarr.php
    +++ b/scripts/user/sync_users_ldap2dolibarr.php
    @@ -34,14 +34,12 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
    -require_once(DOL_DOCUMENT_ROOT."/core/class/ldap.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php");
    -
    -$langs->load("main");
    -$langs->load("errors");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
    +require_once DOL_DOCUMENT_ROOT."/core/class/ldap.class.php";
    +require_once DOL_DOCUMENT_ROOT."/user/class/user.class.php";
     
    +$langs->loadLangs(array("main", "errors"));
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/scripts/withdrawals/build_withdrawal_file.php b/scripts/withdrawals/build_withdrawal_file.php
    index d381c32676a..2f7ad26a1fe 100755
    --- a/scripts/withdrawals/build_withdrawal_file.php
    +++ b/scripts/withdrawals/build_withdrawal_file.php
    @@ -34,11 +34,11 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
     	exit(-1);
     }
     
    -require_once($path."../../htdocs/master.inc.php");
    -require_once(DOL_DOCUMENT_ROOT."/compta/prelevement/class/bonprelevement.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php");
    -require_once(DOL_DOCUMENT_ROOT."/compta/paiement/class/paiement.class.php");
    +require_once $path."../../htdocs/master.inc.php";
    +require_once DOL_DOCUMENT_ROOT."/compta/prelevement/class/bonprelevement.class.php";
    +require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
    +require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
    +require_once DOL_DOCUMENT_ROOT."/compta/paiement/class/paiement.class.php";
     
     // Global variables
     $version=DOL_VERSION;
    diff --git a/test/phpunit/AccountingAccountTest.php b/test/phpunit/AccountingAccountTest.php
    index 46117b4ff38..8f6014cb43d 100644
    --- a/test/phpunit/AccountingAccountTest.php
    +++ b/test/phpunit/AccountingAccountTest.php
    @@ -223,5 +223,4 @@ class AccountingAccountTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/ActionCommTest.php b/test/phpunit/ActionCommTest.php
    index 7b5a9b23b2d..80bb9687529 100644
    --- a/test/phpunit/ActionCommTest.php
    +++ b/test/phpunit/ActionCommTest.php
    @@ -244,5 +244,4 @@ class ActionCommTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/AdminLibTest.php b/test/phpunit/AdminLibTest.php
    index cc83eefe84e..75139ba8aea 100644
    --- a/test/phpunit/AdminLibTest.php
    +++ b/test/phpunit/AdminLibTest.php
    @@ -166,5 +166,4 @@ class AdminLibTest extends PHPUnit_Framework_TestCase
     		$moduledescriptor->init();
     		$conf->setValues($db);
         }
    -
     }
    diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php
    index 206d180f700..008014fbcb5 100644
    --- a/test/phpunit/AllTests.php
    +++ b/test/phpunit/AllTests.php
    @@ -252,4 +252,3 @@ class AllTests
             return $suite;
         }
     }
    -
    diff --git a/test/phpunit/BankAccountTest.php b/test/phpunit/BankAccountTest.php
    index f6c135158d5..f8917a335ca 100644
    --- a/test/phpunit/BankAccountTest.php
    +++ b/test/phpunit/BankAccountTest.php
    @@ -222,5 +222,4 @@ class BankAccountTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/BonPrelevementTest.php b/test/phpunit/BonPrelevementTest.php
    index de0c3be3416..8c6ffbb585d 100644
    --- a/test/phpunit/BonPrelevementTest.php
    +++ b/test/phpunit/BonPrelevementTest.php
    @@ -76,14 +76,24 @@ class BonPrelevementTest extends PHPUnit_Framework_TestCase
     		print "\n";
     	}
     
    -	// Static methods
    -  	public static function setUpBeforeClass()
    +    /**
    +     * setUpBeforeClass
    +     *
    +     * @return	void
    +     */
    +    public static function setUpBeforeClass()
         {
         	global $conf,$user,$langs,$db;
     		$db->begin();	// This is to have all actions inside a transaction even if test launched without suite.
     
         	print __METHOD__."\n";
         }
    +
    +    /**
    +     * tearDownAfterClass
    +     *
    +     * @return	void
    +     */
         public static function tearDownAfterClass()
         {
         	global $conf,$user,$langs,$db;
    @@ -180,5 +190,4 @@ class BonPrelevementTest extends PHPUnit_Framework_TestCase
         	return $result;
         }
     */
    -
     }
    diff --git a/test/phpunit/CMailFileTest.php b/test/phpunit/CMailFileTest.php
    index a1c3aff5641..2c511246c48 100755
    --- a/test/phpunit/CMailFileTest.php
    +++ b/test/phpunit/CMailFileTest.php
    @@ -179,23 +179,22 @@ class CMailFileTest extends PHPUnit_Framework_TestCase
             $result=$localobject->getValidAddress($src,3,1);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result,'"=?UTF-8?B?Sm9obiBEb2U=?=" <john@doe.com>');
    -        
    +
             $src='John Doe <john@doe.com>';
             $result=$localobject->getValidAddress($src,4);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result,'John Doe');
    -        
    +
             $src='John Doe <john@doe.com>, John Doe2 <john@doe3.com>, John Doe3 <john@doe2.com>';
             $result=$localobject->getValidAddress($src,4);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result,'John Doe,John Doe2,John Doe3');
    -        
    +
             $src='John Doe <john@doe.com>, John Doe2 <john@doe3.com>, John Doe3 <john@doe2.com>';
             $result=$localobject->getValidAddress($src,4,0,2);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result,'John Doe,John Doe2...');
    -        
    +
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/CategorieTest.php b/test/phpunit/CategorieTest.php
    index 394267d40e1..19440df33db 100644
    --- a/test/phpunit/CategorieTest.php
    +++ b/test/phpunit/CategorieTest.php
    @@ -337,5 +337,4 @@ class CategorieTest extends PHPUnit_Framework_TestCase
             $this->assertTrue(is_array($retarray));
             return $retarray;
         }
    -
     }
    diff --git a/test/phpunit/ChargeSocialesTest.php b/test/phpunit/ChargeSocialesTest.php
    index 8f06564eb1c..cd01fb906e0 100644
    --- a/test/phpunit/ChargeSocialesTest.php
    +++ b/test/phpunit/ChargeSocialesTest.php
    @@ -241,5 +241,4 @@ class ChargeSocialesTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/CodingSqlTest.php b/test/phpunit/CodingSqlTest.php
    index ee6ad6c674e..349e19a1072 100644
    --- a/test/phpunit/CodingSqlTest.php
    +++ b/test/phpunit/CodingSqlTest.php
    @@ -185,19 +185,16 @@ class CodingSqlTest extends PHPUnit_Framework_TestCase
                     if ($dir == DOL_DOCUMENT_ROOT.'/install/mysql/migration')
                     {
                         // Test for migration files only
    -
                     }
                     elseif ($dir == DOL_DOCUMENT_ROOT.'/install/mysql/data')
                     {
                         // Test for data files only
    -
                     }
                     else
                     {
                         if (preg_match('/\.key\.sql$/',$file))
                         {
                             // Test for key files only
    -
                         }
                         else
                         {
    @@ -249,5 +246,4 @@ class CodingSqlTest extends PHPUnit_Framework_TestCase
     
             return;
         }
    -
     }
    diff --git a/test/phpunit/CommandeFournisseurTest.php b/test/phpunit/CommandeFournisseurTest.php
    index 4fe70eedaee..6a3f7a8696c 100644
    --- a/test/phpunit/CommandeFournisseurTest.php
    +++ b/test/phpunit/CommandeFournisseurTest.php
    @@ -385,5 +385,4 @@ class CommandeFournisseurTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/CommandeTest.php b/test/phpunit/CommandeTest.php
    index 17263e260b7..85e2b972cb5 100644
    --- a/test/phpunit/CommandeTest.php
    +++ b/test/phpunit/CommandeTest.php
    @@ -294,5 +294,4 @@ class CommandeTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/CommonInvoiceTest.php b/test/phpunit/CommonInvoiceTest.php
    new file mode 100644
    index 00000000000..4fab182ad69
    --- /dev/null
    +++ b/test/phpunit/CommonInvoiceTest.php
    @@ -0,0 +1,147 @@
    +<?php
    +/* Copyright (C) 2010 Laurent Destailleur  <eldy@users.sourceforge.net>
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
    +
    +/**
    + *      \file       test/phpunit/CommonObjectTest.php
    + *      \ingroup    test
    + *      \brief      PHPUnit test
    + *      \remarks    To run this script as CLI:  phpunit filename.php
    + */
    +
    +global $conf,$user,$langs,$db;
    +//define('TEST_DB_FORCE_TYPE','mysql');	// This is to force using mysql driver
    +//require_once 'PHPUnit/Autoload.php';
    +require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
    +require_once dirname(__FILE__).'/../../htdocs/compta/facture/class/facture.class.php';
    +
    +if (empty($user->id)) {
    +    print "Load permissions for admin user nb 1\n";
    +    $user->fetch(1);
    +    $user->getrights();
    +}
    +$conf->global->MAIN_DISABLE_ALL_MAILS=1;
    +
    +
    +/**
    + * Class for PHPUnit tests
    + *
    + * @backupGlobals disabled
    + * @backupStaticAttributes enabled
    + * @remarks	backupGlobals must be disabled to have db,conf,user and lang not erased.
    + */
    +class CommonInvoiceTest extends PHPUnit\Framework\TestCase
    +{
    +    protected $savconf;
    +    protected $savuser;
    +    protected $savlangs;
    +    protected $savdb;
    +
    +    /**
    +     * Constructor
    +     * We save global variables into local variables
    +     *
    +     * @return CommonObjectTest
    +     */
    +    function __construct()
    +    {
    +    	parent::__construct();
    +
    +    	//$this->sharedFixture
    +        global $conf,$user,$langs,$db;
    +        $this->savconf=$conf;
    +        $this->savuser=$user;
    +        $this->savlangs=$langs;
    +        $this->savdb=$db;
    +
    +        print __METHOD__." db->type=".$db->type." user->id=".$user->id;
    +        //print " - db ".$db->db;
    +        print "\n";
    +    }
    +
    +    // Static methods
    +    public static function setUpBeforeClass()
    +    {
    +        global $conf,$user,$langs,$db;
    +        $db->begin(); // This is to have all actions inside a transaction even if test launched without suite.
    +
    +        print __METHOD__."\n";
    +    }
    +
    +    // tear down after class
    +    public static function tearDownAfterClass()
    +    {
    +        global $conf,$user,$langs,$db;
    +        $db->rollback();
    +
    +        print __METHOD__."\n";
    +    }
    +
    +    /**
    +     * Init phpunit tests
    +     *
    +     * @return  void
    +     */
    +    protected function setUp()
    +    {
    +        global $conf,$user,$langs,$db;
    +        $conf=$this->savconf;
    +        $user=$this->savuser;
    +        $langs=$this->savlangs;
    +        $db=$this->savdb;
    +
    +        print __METHOD__."\n";
    +    }
    +    /**
    +     * End phpunit tests
    +     *
    +     * @return  void
    +    */
    +    protected function tearDown()
    +    {
    +        print __METHOD__."\n";
    +    }
    +
    +
    +    /**
    +     *  testFetchUser
    +     *
    +     *  @return void
    +     */
    +    public function testCalculateDateLimReglement()
    +    {
    +        global $conf,$user,$langs,$db;
    +        $conf=$this->savconf;
    +        $user=$this->savuser;
    +        $langs=$this->savlangs;
    +        $db=$this->savdb;
    +
    +        $localobject=new Facture($this->savdb);
    +        $localobject->fetch(1);
    +        $localobject->date = dol_mktime(12, 0, 0, 1, 1, 2010);
    +
    +        $result = 0;
    +
    +        // TODO Insert payment terms
    +
    +
    +        //$result=$localobject->calculate_date_lim_reglement(1);
    +        //print __METHOD__." result=".$result."\n";
    +        $this->assertEquals($result, 0);
    +        return $result;
    +    }
    +}
    diff --git a/test/phpunit/CompanyBankAccountTest.php b/test/phpunit/CompanyBankAccountTest.php
    index 5c72dca72a0..c50935c8aac 100644
    --- a/test/phpunit/CompanyBankAccountTest.php
    +++ b/test/phpunit/CompanyBankAccountTest.php
    @@ -235,5 +235,4 @@ class CompanyBankAccountTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $localobject->id;
         }
    -
     }
    diff --git a/test/phpunit/ContratTest.php b/test/phpunit/ContratTest.php
    index 7e7dfb64922..74b30e10268 100644
    --- a/test/phpunit/ContratTest.php
    +++ b/test/phpunit/ContratTest.php
    @@ -220,5 +220,4 @@ class ContratTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/CoreTest.php b/test/phpunit/CoreTest.php
    index 76ea43f9528..63601cb33d3 100644
    --- a/test/phpunit/CoreTest.php
    +++ b/test/phpunit/CoreTest.php
    @@ -252,6 +252,7 @@ class CoreTest extends PHPUnit_Framework_TestCase
     
             // This is code copied from main.inc.php !!!!!!!!!!!!!!!
     
    +        // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
             /**
              * Security: SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF).
              *
    @@ -259,20 +260,21 @@ class CoreTest extends PHPUnit_Framework_TestCase
              * @param       string $type    1=GET, 0=POST, 2=PHP_SELF
              * @return      int             >0 if there is an injection
              */
    -        function test_sql_and_script_inject($val, $type)
    +        function testSqlAndScriptInject($val, $type)
             {
    +            // phpcs:enable
     		    $inj = 0;
     		    // For SQL Injection (only GET and POST are used to be included into bad escaped SQL requests)
     		    if ($type != 2)
     		    {
    -		        $inj += preg_match('/delete\s+from/i',	 $val);
    -		        $inj += preg_match('/create\s+table/i',	 $val);
    -		        $inj += preg_match('/update.+set.+=/i',  $val);
    -		        $inj += preg_match('/insert\s+into/i', 	 $val);
    -		        $inj += preg_match('/select.+from/i', 	 $val);
    -		        $inj += preg_match('/union.+select/i', 	 $val);
    -		        $inj += preg_match('/into\s+(outfile|dumpfile)/i',  $val);
    -		        $inj += preg_match('/(\.\.%2f)+/i',		 $val);
    +		        $inj += preg_match('/delete\s+from/i', $val);
    +		        $inj += preg_match('/create\s+table/i', $val);
    +		        $inj += preg_match('/update.+set.+=/i', $val);
    +		        $inj += preg_match('/insert\s+into/i', $val);
    +		        $inj += preg_match('/select.+from/i', $val);
    +		        $inj += preg_match('/union.+select/i', $val);
    +		        $inj += preg_match('/into\s+(outfile|dumpfile)/i', $val);
    +		        $inj += preg_match('/(\.\.%2f)+/i', $val);
     		    }
     		    // For XSS Injection done by adding javascript with script
     		    // This is all cases a browser consider text is javascript:
    @@ -308,55 +310,55 @@ class CoreTest extends PHPUnit_Framework_TestCase
             $expectedresult=0;
     
             $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices';
    -        $result=test_sql_and_script_inject($_SERVER["PHP_SELF"], 2);
    -        $this->assertEquals($expectedresult, $result, 'Error on test_sql_and_script_inject 1a');
    +        $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2);
    +        $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject 1a');
     
             // Should detect XSS
             $expectedresult=1;
     
             $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices;badaction';
    -        $result=test_sql_and_script_inject($_SERVER["PHP_SELF"], 2);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject 1b');
    +        $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject 1b');
     
             $test="<img src='1.jpg' onerror =javascript:alert('XSS')>";
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa');
     
             $test="<img src='1.jpg' onerror =javascript:alert('XSS')>";
    -        $result=test_sql_and_script_inject($test, 2);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa2');
    +        $result=testSqlAndScriptInject($test, 2);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa2');
     
             $test='<IMG SRC=# onmouseover="alert(1)">';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa3');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa3');
             $test='<IMG SRC onmouseover="alert(1)">';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa4');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa4');
             $test='<IMG onmouseover="alert(1)">';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa5');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa5');
             $test='<IMG SRC=/ onerror="alert(1)">';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa6');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa6');
     		$test='<IMG SRC=" &#14;  javascript:alert(1);">';
    -		$result=test_sql_and_script_inject($test, 0);
    -		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject aaa7');
    +		$result=testSqlAndScriptInject($test, 0);
    +		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa7');
     
     		$test='<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>';
    -		$result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject bbb');
    +		$result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject bbb');
     
             $test='<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject ccc');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ccc');
     
             $test='<IMG SRC="javascript:alert(\'XSS\');">';
    -        $result=test_sql_and_script_inject($test, 1);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject ddd');
    +        $result=testSqlAndScriptInject($test, 1);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ddd');
     
             $test='<IMG """><SCRIPT>alert("XSS")</SCRIPT>">';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject eee');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject eee');
     
             $test='<!-- Google analytics -->
     			<script>
    @@ -369,30 +371,30 @@ class CoreTest extends PHPUnit_Framework_TestCase
     			  ga(\'send\', \'pageview\');
     
     			</script>';
    -        $result=test_sql_and_script_inject($test, 0);
    -        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject eee');
    +        $result=testSqlAndScriptInject($test, 0);
    +        $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject eee');
     
             $test="<IMG SRC=\"jav\tascript:alert('XSS');\">";		// Is locked by some brwoser like chrome because the default directive no-referrer-when-downgrade is sent when requesting the SRC and then refused because of browser protection on img src load without referrer.
     		$test="<IMG SRC=\"jav&#x0D;ascript:alert('XSS');\">";	// Same
     
     		$test='<SCRIPT/XSS SRC="http://xss.rocks/xss.js"></SCRIPT>';
    -		$result=test_sql_and_script_inject($test, 0);
    -		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject fff1');
    +		$result=testSqlAndScriptInject($test, 0);
    +		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject fff1');
     		$test='<SCRIPT/SRC="http://xss.rocks/xss.js"></SCRIPT>';
    -		$result=test_sql_and_script_inject($test, 0);
    -		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject fff2');
    +		$result=testSqlAndScriptInject($test, 0);
    +		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject fff2');
     
     		// This case seems to be filtered by browsers now.
     		$test='<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert(1)>';
    -		//$result=test_sql_and_script_inject($test, 0);
    -		//$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject ggg');
    +		//$result=testSqlAndScriptInject($test, 0);
    +		//$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ggg');
     
     		$test='<iframe src=http://xss.rocks/scriptlet.html <';
    -		$result=test_sql_and_script_inject($test, 0);
    -		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject hhh');
    +		$result=testSqlAndScriptInject($test, 0);
    +		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject hhh');
     
     		$test='Set.constructor`alert\x281\x29```';
    -		$result=test_sql_and_script_inject($test, 0);
    -		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on test_sql_and_script_inject iii');
    +		$result=testSqlAndScriptInject($test, 0);
    +		$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject iii');
         }
     }
    diff --git a/test/phpunit/DateLibTest.php b/test/phpunit/DateLibTest.php
    index e0cd1fab31b..d7f2ad18877 100644
    --- a/test/phpunit/DateLibTest.php
    +++ b/test/phpunit/DateLibTest.php
    @@ -464,5 +464,4 @@ class DateLibTest extends PHPUnit_Framework_TestCase
        		$prev = dol_get_first_day_week($day, $month, $year);
     		$this->assertEquals(1, (int) $prev['first_day']);		// sunday for month 2, year 2015 is the 1st
         }
    -
     }
    diff --git a/test/phpunit/DateLibTzFranceTest.php b/test/phpunit/DateLibTzFranceTest.php
    index b41688c153f..b47cdfbfe7b 100644
    --- a/test/phpunit/DateLibTzFranceTest.php
    +++ b/test/phpunit/DateLibTzFranceTest.php
    @@ -201,5 +201,4 @@ class DateLibTzFranceTest extends PHPUnit_Framework_TestCase
     
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/EntrepotTest.php b/test/phpunit/EntrepotTest.php
    index a1fca65fac7..a5ee6139a48 100644
    --- a/test/phpunit/EntrepotTest.php
    +++ b/test/phpunit/EntrepotTest.php
    @@ -257,7 +257,6 @@ class EntrepotTest extends PHPUnit_Framework_TestCase
     
             $localobject=new Entrepot($db);
     
    -
             return;
         }
     }
    diff --git a/test/phpunit/ExpenseReportTest.php b/test/phpunit/ExpenseReportTest.php
    index 9426b2807a9..ed6ddf97fc7 100644
    --- a/test/phpunit/ExpenseReportTest.php
    +++ b/test/phpunit/ExpenseReportTest.php
    @@ -314,5 +314,4 @@ class ExpenseReportTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/ExportTest.php b/test/phpunit/ExportTest.php
    index d9de0a89eef..cf8be11ab17 100644
    --- a/test/phpunit/ExportTest.php
    +++ b/test/phpunit/ExportTest.php
    @@ -130,31 +130,31 @@ class ExportTest extends PHPUnit_Framework_TestCase
         public function testExportOther()
         {
             global $conf,$user,$langs,$db;
    -    
    +
             $model='csv';
    -    
    +
             // Creation of class to export using model ExportXXX
             $dir = DOL_DOCUMENT_ROOT . "/core/modules/export/";
             $file = "export_".$model.".modules.php";
             $classname = "Export".$model;
             require_once $dir.$file;
             $objmodel = new $classname($this->db);
    -    
    +
             // First test without option USE_STRICT_CSV_RULES
             unset($conf->global->USE_STRICT_CSV_RULES);
    -        
    +
             $valtotest='A simple string';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, 'A simple string');
    -        
    +
             $valtotest='A string with , and ; inside';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, '"A string with , and ; inside"');
    -        
    +
             $valtotest='A string with " inside';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
    @@ -166,48 +166,47 @@ class ExportTest extends PHPUnit_Framework_TestCase
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, '"A string with "" inside and \n carriage returns"');
    -        
    +
             $valtotest='A string with <a href="aaa"><strong>html<br>content</strong></a> inside<br>'."\n";
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, '"A string with <a href=""aaa""><strong>html<br>content</strong></a> inside"');
    -        
    +
             // Same tests with strict mode
             $conf->global->USE_STRICT_CSV_RULES=1;
    -        
    +
             $valtotest='A simple string';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, 'A simple string');
    -        
    +
             $valtotest='A string with , and ; inside';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, '"A string with , and ; inside"');
    -        
    +
             $valtotest='A string with " inside';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, '"A string with "" inside"');
    -        
    +
             $valtotest='A string with " inside and '."\r\n".' carriage returns';
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, "\"A string with \"\" inside and \r\n carriage returns\"");
    -        
    +
             $valtotest='A string with <a href="aaa"><strong>html<br>content</strong></a> inside<br>'."\n";
             print __METHOD__." valtotest=".$valtotest."\n";
             $result = $objmodel->csvClean($valtotest, $langs->charset_output);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals($result, '"A string with <a href=""aaa""><strong>html<br>content</strong></a> inside"');
    -        
         }
    -    
    +
         /**
          * Test export function for a personalized dataset
          *
    @@ -355,5 +354,4 @@ class ExportTest extends PHPUnit_Framework_TestCase
     
             return true;
         }
    -    
     }
    diff --git a/test/phpunit/FactureFournisseurTest.php b/test/phpunit/FactureFournisseurTest.php
    index cda7f9d73f2..63c28945e65 100644
    --- a/test/phpunit/FactureFournisseurTest.php
    +++ b/test/phpunit/FactureFournisseurTest.php
    @@ -268,5 +268,4 @@ class FactureFournisseurTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php
    index d04844783c5..a1dd46de978 100644
    --- a/test/phpunit/FactureTest.php
    +++ b/test/phpunit/FactureTest.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2010 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2010 Laurent Destailleur   <eldy@users.sourceforge.net>
    + * Copyright (C) 2018 Frédéric France       <frederic.france@netlogic.fr>
      *
      * 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
    @@ -228,7 +229,7 @@ class FactureTest extends PHPUnit_Framework_TestCase
     			$newlocalobject,
     			true,
     			array(
    -				'newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem',
    +				'newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','date_modification',
     				'ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement',
     				'cond_reglement_doc','situation_cycle_ref','situation_counter','situation_final','multicurrency_total_ht','multicurrency_total_tva',
     				'multicurrency_total_ttc','fk_multicurrency','multicurrency_code','multicurrency_tx'
    diff --git a/test/phpunit/FactureTestRounding.php b/test/phpunit/FactureTestRounding.php
    index 4ed76d900bf..dbaf598e1a0 100644
    --- a/test/phpunit/FactureTestRounding.php
    +++ b/test/phpunit/FactureTestRounding.php
    @@ -335,5 +335,4 @@ class FactureTestRounding extends PHPUnit_Framework_TestCase
         	$this->assertEquals(20.03, $localobject3->total_tva);
         	$this->assertEquals(115.43, $localobject3->total_ttc);
         }
    -
     }
    diff --git a/test/phpunit/FichinterTest.php b/test/phpunit/FichinterTest.php
    index 4d6e1224498..5c966f4d4ec 100644
    --- a/test/phpunit/FichinterTest.php
    +++ b/test/phpunit/FichinterTest.php
    @@ -244,5 +244,4 @@ class FichinterTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/FilesLibTest.php b/test/phpunit/FilesLibTest.php
    index 4363623adb0..72e809aa051 100644
    --- a/test/phpunit/FilesLibTest.php
    +++ b/test/phpunit/FilesLibTest.php
    @@ -504,5 +504,4 @@ class FilesLibTest extends PHPUnit_Framework_TestCase
             $user->rights->facture->lire = $savpermlire;
             $user->rights->facture->creer = $savpermcreer;
         }
    -
     }
    diff --git a/test/phpunit/FormAdminTest.php b/test/phpunit/FormAdminTest.php
    index 876e733b56d..10998f7776f 100644
    --- a/test/phpunit/FormAdminTest.php
    +++ b/test/phpunit/FormAdminTest.php
    @@ -138,5 +138,4 @@ class FormAdminTest extends PHPUnit_Framework_TestCase
         	print __METHOD__." result=".$result."\n";
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/Functions2LibTest.php b/test/phpunit/Functions2LibTest.php
    index 87b2eaefe58..a11c50b7198 100644
    --- a/test/phpunit/Functions2LibTest.php
    +++ b/test/phpunit/Functions2LibTest.php
    @@ -140,7 +140,6 @@ class Functions2LibTest extends PHPUnit_Framework_TestCase
          */
         public function testIsValidMailDomain()
         {
    -
         }
     
         /**
    @@ -243,10 +242,9 @@ class Functions2LibTest extends PHPUnit_Framework_TestCase
             print __METHOD__." for ".$ip." result=".$result."\n";
         	$this->assertEquals(2,$result,$ip);
     
    -    	$ip='192.168.0.0';
    -    	$result=is_ip($ip);
    +        $ip='192.168.0.0';
    +        $result=is_ip($ip);
             print __METHOD__." for ".$ip." result=".$result."\n";
    -    	$this->assertEquals(2,$result,$ip);
    -
    +        $this->assertEquals(2,$result,$ip);
         }
     }
    diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php
    index 4f7af8b1a1d..daaa0dda2f5 100644
    --- a/test/phpunit/FunctionsLibTest.php
    +++ b/test/phpunit/FunctionsLibTest.php
    @@ -112,7 +112,8 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
     
             print __METHOD__."\n";
         }
    -	/**
    +
    +    /**
     	 * End phpunit tests
     	 *
     	 * @return	void
    @@ -123,6 +124,30 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
         }
     
     
    +    /**
    +     * testIsValidMXRecord
    +     *
    +     * @return void
    +     */
    +    public function testIsValidMXRecord()
    +    {
    +    	// Nb of line is same than entry text
    +
    +    	$input="yahoo.com";
    +    	$result=isValidMXRecord($input);
    +    	print __METHOD__." result=".$result."\n";
    +    	$this->assertEquals(1, $result);
    +
    +    	$input="yhaoo.com";
    +    	$result=isValidMXRecord($input);
    +    	print __METHOD__." result=".$result."\n";
    +    	$this->assertEquals(0, $result);
    +
    +    	$input="dolibarr.fr";
    +    	$result=isValidMXRecord($input);
    +    	print __METHOD__." result=".$result."\n";
    +    	$this->assertEquals(0, $result);
    +    }
     
         /**
          * testDolGetFirstLineOfText
    @@ -367,7 +392,6 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
             $input='This is a text with html comments <!-- comment -->';	// we suppose this is not enough to be html content
             $after=dol_textishtml($input);
             $this->assertFalse($after);
    -
         }
     
     
    @@ -814,7 +838,6 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
             $object->country_code='CA';
             $phone=dol_print_phone('1234567890', $object->country_code, 0, 0, 0, ' ');
             $this->assertEquals('<span style="margin-right: 10px;">(123) 456-7890</span>', $phone, 'Phone for CA 1');
    -
         }
     
     
    @@ -985,7 +1008,6 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
             // Test RULE 5 (FR-US)
             $vat=get_default_tva($companyfr,$companyus,0);
             $this->assertEquals(0,$vat,'RULE 5 ECOMMERCE_200238EC');
    -
         }
     
         /**
    @@ -1095,7 +1117,8 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
     	 *
     	 * @return void
     	 */
    -	public function testDolNl2Br() {
    +    public function testDolNl2Br()
    +    {
     
     		//String to encode
     		$string = "a\na";
    @@ -1186,5 +1209,4 @@ class FunctionsLibTest extends PHPUnit_Framework_TestCase
     
     		return true;
     	}
    -
     }
    diff --git a/test/phpunit/HolidayTest.php b/test/phpunit/HolidayTest.php
    index 625e4cf16a3..37684e731d5 100644
    --- a/test/phpunit/HolidayTest.php
    +++ b/test/phpunit/HolidayTest.php
    @@ -351,5 +351,4 @@ class HolidayTest extends PHPUnit_Framework_TestCase
         	$result=$localobjectc->verifDateHolidayCP($user->id, $date_debut, $date_fin, 2);	// start afternoon and end morning
         	$this->assertTrue($result, 'result should be true, there is no overlapping');
         }
    -
     }
    diff --git a/test/phpunit/ImagesLibTest.php b/test/phpunit/ImagesLibTest.php
    index cc4e6bd7462..cc8ea5cdf67 100644
    --- a/test/phpunit/ImagesLibTest.php
    +++ b/test/phpunit/ImagesLibTest.php
    @@ -145,5 +145,4 @@ class ImagesLibTest extends PHPUnit_Framework_TestCase
     
     		return 1;
         }
    -
     }
    diff --git a/test/phpunit/ImportTest.php b/test/phpunit/ImportTest.php
    index 0e80b6384e8..52be24049bc 100644
    --- a/test/phpunit/ImportTest.php
    +++ b/test/phpunit/ImportTest.php
    @@ -136,5 +136,4 @@ class ImportTest extends PHPUnit_Framework_TestCase
     
     		return true;
         }
    -
     }
    diff --git a/test/phpunit/LoanTest.php b/test/phpunit/LoanTest.php
    index 8341f788ede..d54c810049d 100644
    --- a/test/phpunit/LoanTest.php
    +++ b/test/phpunit/LoanTest.php
    @@ -214,5 +214,4 @@ class LoanTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/MarginsLibTest.php b/test/phpunit/MarginsLibTest.php
    index 21c07f7c04a..5966cb65a74 100644
    --- a/test/phpunit/MarginsLibTest.php
    +++ b/test/phpunit/MarginsLibTest.php
    @@ -149,5 +149,4 @@ class MarginsLibTest extends PHPUnit_Framework_TestCase
     
     		return 0;
         }
    -
     }
    diff --git a/test/phpunit/ModulesTest.php b/test/phpunit/ModulesTest.php
    index f034fd7a8b9..006b6dd2740 100755
    --- a/test/phpunit/ModulesTest.php
    +++ b/test/phpunit/ModulesTest.php
    @@ -138,7 +138,7 @@ class ModulesTest extends PHPUnit_Framework_TestCase
     		'Salaries','Service','Skype','Societe','Stock','Stripe','SupplierProposal','Syslog','Tax','Ticket','User','Variants','WebServices','WebServicesClient','Website','Workflow');
     		foreach($modulelist as $modlabel)
     		{
    -    		require_once(DOL_DOCUMENT_ROOT.'/core/modules/mod'.$modlabel.'.class.php');
    +    		require_once DOL_DOCUMENT_ROOT.'/core/modules/mod'.$modlabel.'.class.php';
                 $class='mod'.$modlabel;
         		$mod=new $class($db);
                 $result=$mod->remove();
    @@ -154,5 +154,4 @@ class ModulesTest extends PHPUnit_Framework_TestCase
     
             return 0;
         }
    -
     }
    diff --git a/test/phpunit/MouvementStockTest.php b/test/phpunit/MouvementStockTest.php
    index 2779b3011d6..cc50460e15f 100644
    --- a/test/phpunit/MouvementStockTest.php
    +++ b/test/phpunit/MouvementStockTest.php
    @@ -252,5 +252,4 @@ class MouvementStockTest extends PHPUnit_Framework_TestCase
     
         	return $localobject;
         }
    -
     }
    diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php
    index 62ff9f8c342..0d229de8aa0 100644
    --- a/test/phpunit/NumberingModulesTest.php
    +++ b/test/phpunit/NumberingModulesTest.php
    @@ -575,5 +575,4 @@ class NumberingModulesTest extends PHPUnit_Framework_TestCase
     
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/PaypalTest.php b/test/phpunit/PaypalTest.php
    index 59c28be2177..ef6f069e6bf 100644
    --- a/test/phpunit/PaypalTest.php
    +++ b/test/phpunit/PaypalTest.php
    @@ -145,5 +145,4 @@ class PaypalTest extends PHPUnit_Framework_TestCase
     
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/PricesTest.php b/test/phpunit/PricesTest.php
    index f7c7fa00354..1c7b05d462b 100755
    --- a/test/phpunit/PricesTest.php
    +++ b/test/phpunit/PricesTest.php
    @@ -353,5 +353,4 @@ class PricesTest extends PHPUnit_Framework_TestCase
             //$this->assertEquals(0.25,$newlocalobject->total_tva);
             //$this->assertEquals(2.73,$newlocalobject->total_ttc);
         }
    -
     }
    diff --git a/test/phpunit/ProjectTest.php b/test/phpunit/ProjectTest.php
    index ea7cf01c328..2779902cabd 100644
    --- a/test/phpunit/ProjectTest.php
    +++ b/test/phpunit/ProjectTest.php
    @@ -239,5 +239,4 @@ class ProjectTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/PropalTest.php b/test/phpunit/PropalTest.php
    index 1ee429509a3..81842063271 100644
    --- a/test/phpunit/PropalTest.php
    +++ b/test/phpunit/PropalTest.php
    @@ -293,5 +293,4 @@ class PropalTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/RestAPIDocumentTest.php b/test/phpunit/RestAPIDocumentTest.php
    index 74225bea2d3..e9606b001b9 100644
    --- a/test/phpunit/RestAPIDocumentTest.php
    +++ b/test/phpunit/RestAPIDocumentTest.php
    @@ -96,6 +96,7 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
     
         /**
          * Init phpunit tests.
    +     * @return void
          */
         protected function setUp()
         {
    @@ -127,6 +128,7 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
     
         /**
          * End phpunit tests.
    +     * @return void
          */
         protected function tearDown()
         {
    diff --git a/test/phpunit/RestAPIUserTest.php b/test/phpunit/RestAPIUserTest.php
    index 4d461ce235d..7b2d345a41a 100644
    --- a/test/phpunit/RestAPIUserTest.php
    +++ b/test/phpunit/RestAPIUserTest.php
    @@ -175,7 +175,13 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase
           $this->assertEquals(1, $object['statut']);
         }
     
    -    public function testRestCreateUser() {
    +    /**
    +     * testRestCreateUser
    +     *
    +     * @return void
    +     */
    +    public function testRestCreateUser()
    +    {
     
           // attemp to create without mandatory fields :
           $url = $this->api_url.'/users?api_key='.$this->api_key;
    @@ -225,5 +231,4 @@ class RestAPIUserTest extends PHPUnit_Framework_TestCase
           $this->assertNotNull($object, "Parsing of json result must no be null");
           $this->assertEquals(500, $object['error']['code'], $object['error']['code'].' '.$object['error']['message']);
         }
    -
    -}
    \ No newline at end of file
    +}
    diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php
    index 6e614032a73..21e25473b8f 100644
    --- a/test/phpunit/SecurityTest.php
    +++ b/test/phpunit/SecurityTest.php
    @@ -296,5 +296,4 @@ class SecurityTest extends PHPUnit_Framework_TestCase
     		$result=restrictedArea($user,'societe');
     		$this->assertEquals(1,$result);
         }
    -
     }
    diff --git a/test/phpunit/SocieteTest.php b/test/phpunit/SocieteTest.php
    index af924d233a9..3e9ee3c2002 100755
    --- a/test/phpunit/SocieteTest.php
    +++ b/test/phpunit/SocieteTest.php
    @@ -457,5 +457,4 @@ class SocieteTest extends PHPUnit_Framework_TestCase
     
             return $localobjectadd->id;
         }
    -
     }
    diff --git a/test/phpunit/SupplierProposalTest.php b/test/phpunit/SupplierProposalTest.php
    index 2428bd6d441..3648e0e61da 100644
    --- a/test/phpunit/SupplierProposalTest.php
    +++ b/test/phpunit/SupplierProposalTest.php
    @@ -31,7 +31,7 @@ require_once dirname(__FILE__).'/../../htdocs/supplier_proposal/class/supplier_p
     
     if (empty($user->id))
     {
    -	print "Load permissions for admin user nb 1\n";
    +	print "Load permissions for user nb 1 (that should be admin)\n";
     	$user->fetch(1);
     
     	//$user->addrights(0, 'supplier_proposal');
    @@ -112,7 +112,12 @@ class SupplierProposalTest extends PHPUnit_Framework_TestCase
     
     		print __METHOD__."\n";
     		//print $db->getVersion()."\n";
    +
    +		// Set permission not set by default sql sample
    +		$user->addrights(0, 'supplier_proposal');
    +		$user->getrights('supplier_proposal', 1);
         }
    +
     	/**
     	 * End phpunit tests
     	 *
    @@ -212,7 +217,7 @@ class SupplierProposalTest extends PHPUnit_Framework_TestCase
     		$langs=$this->savlangs;
     		$db=$this->savdb;
     
    -    	$result=$localobject->valid($user);
    +		$result=$localobject->valid($user);
     
         	print __METHOD__." id=".$localobject->id." result=".$result."\n";
         	$this->assertLessThan($result, 0);
    @@ -273,5 +278,4 @@ class SupplierProposalTest extends PHPUnit_Framework_TestCase
         	$this->assertLessThan($result, 0);
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/UserGroupTest.php b/test/phpunit/UserGroupTest.php
    index b1e9b3bb43f..a74e9d81726 100644
    --- a/test/phpunit/UserGroupTest.php
    +++ b/test/phpunit/UserGroupTest.php
    @@ -285,5 +285,4 @@ class UserGroupTest extends PHPUnit_Framework_TestCase
             $this->assertLessThan($result, 0);
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/UtilsTest.php b/test/phpunit/UtilsTest.php
    index e9c3ede729b..f2f44daa31d 100644
    --- a/test/phpunit/UtilsTest.php
    +++ b/test/phpunit/UtilsTest.php
    @@ -148,7 +148,4 @@ class UtilsTest extends PHPUnit_Framework_TestCase
             print __METHOD__." result=".$result."\n";
             return $result;
         }
    -
    -
    -
     }
    diff --git a/test/phpunit/WebservicesInvoicesTest.php b/test/phpunit/WebservicesInvoicesTest.php
    index adc202abd74..92a336c846e 100644
    --- a/test/phpunit/WebservicesInvoicesTest.php
    +++ b/test/phpunit/WebservicesInvoicesTest.php
    @@ -28,7 +28,7 @@ global $conf,$user,$langs,$db;
     //require_once 'PHPUnit/Autoload.php';
     require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
     require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php';
    -require_once(NUSOAP_PATH.'/nusoap.php');        // Include SOAP
    +require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     
     
     if (empty($user->id))
    @@ -93,6 +93,11 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase
     		print "\n";
     	}
     
    +    /**
    +     * setUpBeforeClass
    +     *
    +     * @return void
    +     */
         public static function setUpBeforeClass()
         {
             global $conf,$user,$langs,$db;
    @@ -133,6 +138,11 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase
             print __METHOD__."\n";
         }
     
    +    /**
    +     * tearDownAfterClass
    +     *
    +     * @return void
    +     */
         public static function tearDownAfterClass()
         {
         	global $conf,$user,$langs,$db;
    @@ -420,5 +430,4 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase
     
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/WebservicesOrdersTest.php b/test/phpunit/WebservicesOrdersTest.php
    index bdd4b138803..a155e5de973 100644
    --- a/test/phpunit/WebservicesOrdersTest.php
    +++ b/test/phpunit/WebservicesOrdersTest.php
    @@ -28,7 +28,7 @@ global $conf,$user,$langs,$db;
     //require_once 'PHPUnit/Autoload.php';
     require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
     require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php';
    -require_once(NUSOAP_PATH.'/nusoap.php');        // Include SOAP
    +require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     
     
     if (empty($user->id)) {
    @@ -180,5 +180,4 @@ class WebservicesOrdersTest extends PHPUnit_Framework_TestCase
     
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/WebservicesOtherTest.php b/test/phpunit/WebservicesOtherTest.php
    index 2feecf7df0e..16b1cd7d531 100644
    --- a/test/phpunit/WebservicesOtherTest.php
    +++ b/test/phpunit/WebservicesOtherTest.php
    @@ -28,7 +28,7 @@ global $conf,$user,$langs,$db;
     //require_once 'PHPUnit/Autoload.php';
     require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
     require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php';
    -require_once(NUSOAP_PATH.'/nusoap.php');        // Include SOAP
    +require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     
     
     if (empty($user->id)) {
    @@ -209,5 +209,4 @@ class WebservicesOtherTest extends PHPUnit_Framework_TestCase
     
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/WebservicesProductsTest.php b/test/phpunit/WebservicesProductsTest.php
    index 0127414627c..60c90ea30d4 100644
    --- a/test/phpunit/WebservicesProductsTest.php
    +++ b/test/phpunit/WebservicesProductsTest.php
    @@ -30,7 +30,7 @@ global $conf,$user,$langs,$db;
     //require_once 'PHPUnit/Autoload.php';
     require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
     require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php';
    -require_once(NUSOAP_PATH.'/nusoap.php');        // Include SOAP
    +require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     
     
     if (empty($user->id)) {
    @@ -324,5 +324,4 @@ class WebservicesProductsTest extends PHPUnit_Framework_TestCase
     
             return 0;
         }
    -
     }
    diff --git a/test/phpunit/WebservicesThirdpartyTest.php b/test/phpunit/WebservicesThirdpartyTest.php
    index 1cf7cc4e8d6..51be1a5dbf6 100644
    --- a/test/phpunit/WebservicesThirdpartyTest.php
    +++ b/test/phpunit/WebservicesThirdpartyTest.php
    @@ -28,7 +28,7 @@ global $conf,$user,$langs,$db;
     //require_once 'PHPUnit/Autoload.php';
     require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
     require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php';
    -require_once(NUSOAP_PATH.'/nusoap.php');        // Include SOAP
    +require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     
     
     if (empty($user->id)) {
    @@ -400,5 +400,4 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase
     
         	return $result;
         }
    -
     }
    diff --git a/test/phpunit/WebservicesUserTest.php b/test/phpunit/WebservicesUserTest.php
    index cdd65b7bc7b..3c97ee719a9 100644
    --- a/test/phpunit/WebservicesUserTest.php
    +++ b/test/phpunit/WebservicesUserTest.php
    @@ -28,7 +28,7 @@ global $conf,$user,$langs,$db;
     //require_once 'PHPUnit/Autoload.php';
     require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
     require_once dirname(__FILE__).'/../../htdocs/core/lib/date.lib.php';
    -require_once(NUSOAP_PATH.'/nusoap.php');        // Include SOAP
    +require_once NUSOAP_PATH.'/nusoap.php';        // Include SOAP
     
     
     if (empty($user->id)) {
    @@ -208,5 +208,4 @@ class WebservicesUserTest extends PHPUnit_Framework_TestCase
     
             return $result;
         }
    -
     }
    diff --git a/test/phpunit/XCalLibTest.php b/test/phpunit/XCalLibTest.php
    index 932f68aa18d..165b8d247b2 100644
    --- a/test/phpunit/XCalLibTest.php
    +++ b/test/phpunit/XCalLibTest.php
    @@ -139,5 +139,4 @@ class XCalLibTest extends PHPUnit_Framework_TestCase
             print __METHOD__." result=".$resultback."\n";
             $this->assertEquals($stringtoencode,$resultback);
         }
    -
     }
    diff --git a/test/phpunit/functional/InstallTest.php b/test/phpunit/functional/InstallTest.php
    index 534d1d602c0..f444d08eec0 100644
    --- a/test/phpunit/functional/InstallTest.php
    +++ b/test/phpunit/functional/InstallTest.php
    @@ -42,6 +42,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		)
     	);
     
    +    /**
    +     * setUpBeforeClass
    +     *
    +     * @return	void
    +     */
     	public static function setUpBeforeClass()
     	{
     		// Make sure we backup and remove the configuration file to force new install.
    @@ -54,12 +59,22 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		self::shareSession(true);
     	}
     
    +    /**
    +     * dropTestDatabase
    +     *
    +     * @return	void
    +     */
     	protected static function dropTestDatabase()
     	{
     		$mysqli = new mysqli(self::$db_host, self::$db_admin_user, self::$db_admin_pass);
     		$mysqli->query("DROP DATABASE " . self::$db_name);
     	}
     
    +    /**
    +     * tearDownAfterClass
    +     *
    +     * @return	void
    +     */
     	public static function tearDownAfterClass()
     	{
     		// Remove the generated configuration and restore the backed up file.
    @@ -70,6 +85,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		self::dropTestDatabase();
     	}
     
    +    /**
    +     * setUp
    +     *
    +     * @return  void
    +     */
     	public function setUp()
     	{
     		// Populating the database can take quite long.
    @@ -77,17 +97,32 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->setBrowserUrl(self::$url);
     	}
     
    +    /**
    +     * testInstallRedirect
    +     *
    +     * @return  void
    +     */
     	public function testInstallRedirect()
     	{
     		$this->url('/');
     		$this->assertContains('/install/index.php', $this->url());
     	}
     
    +    /**
    +     * testInstallPageTitle
    +     *
    +     * @return  void
    +     */
     	public function testInstallPageTitle()
     	{
     		$this->assertContains('Dolibarr', $this->title());
     	}
     
    +    /**
    +     * testInstallProcess
    +     *
    +     * @return  void
    +     */
     	public function testInstallProcess()
     	{
     		// FIXME: the button itself should have an ID
    @@ -95,6 +130,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->assertContains('/install/check.php', $this->url());
     	}
     
    +    /**
    +     * testCheckPage
    +     *
    +     * @return  void
    +     */
     	public function testCheckPage()
     	{
     		$unavailable_choices = $this->byId('navail_choices');
    @@ -109,6 +149,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->assertContains('/install/fileconf.php', $this->url());
     	}
     
    +    /**
    +     * testForm
    +     *
    +     * @return  void
    +     */
     	public function testForm()
     	{
     		$this->assertFalse($this->byClassName('hideroot')->displayed());
    @@ -153,12 +198,22 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->byId('db_pass_root')->value('');
     	}
     
    +    /**
    +     * testFormSubmit
    +     *
    +     * @return  void
    +     */
     	public function testFormSubmit()
     	{
     		$this->byName('forminstall')->submit();
     		$this->assertContains('/install/step1.php', $this->url());
     	}
     
    +    /**
    +     * testStep1
    +     *
    +     * @return  void
    +     */
     	public function testStep1()
     	{
     		$this->assertFalse($this->byId('pleasewait')->displayed());
    @@ -170,6 +225,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->assertContains('/install/step2.php', $this->url());
     	}
     
    +    /**
    +     * testStep2
    +     *
    +     * @return  void
    +     */
     	public function testStep2()
     	{
     		$this->byName('forminstall')->submit();
    @@ -178,6 +238,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     
     	// There is no step 3
     
    +    /**
    +     * testStep4
    +     *
    +     * @return  void
    +     */
     	public function testStep4()
     	{
     		// FIXME: should have an ID
    @@ -191,6 +256,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->assertContains('/install/step5.php', $this->url());
     	}
     
    +    /**
    +     * testStep5
    +     *
    +     * @return  void
    +     */
     	public function testStep5()
     	{
     		// FIXME: this button should have an ID
    @@ -198,6 +268,11 @@ class InstallTest extends PHPUnit_Extensions_Selenium2TestCase
     		$this->assertContains('/admin/index.php', $this->url());
     	}
     
    +    /**
    +     * testFirstLogin
    +     *
    +     * @return  void
    +     */
     	public function testFirstLogin()
     	{
     		$this->assertEquals('login', $this->byTag('form')->attribute('id'));
    diff --git a/test/phpunit/functional/TakePosFunctionalTest.php b/test/phpunit/functional/TakePosFunctionalTest.php
    new file mode 100644
    index 00000000000..b01d86eda10
    --- /dev/null
    +++ b/test/phpunit/functional/TakePosFunctionalTest.php
    @@ -0,0 +1,317 @@
    +<?php
    +/* Copyright (C) 2007-2017 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2018 SuperAdmin
    + *
    + * 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 <http://www.gnu.org/licenses/>.
    + */
    +
    +/**
    + * \file    test/functional/TakePosFunctionalTest.php
    + * \ingroup takepos
    + * \brief   Example Selenium test.
    + */
    +
    +namespace test\functional;
    +
    +use PHPUnit_Extensions_Selenium2TestCase_WebDriverException;
    +
    +/**
    + * Class TakePosFunctionalTest
    + *
    + * Requires chromedriver for Google Chrome
    + * Requires geckodriver for Mozilla Firefox
    + *
    + * @fixme Firefox (Geckodriver/Marionette) support
    + * @todo Opera linux support
    + * @todo Windows support (IE, Google Chrome, Mozilla Firefox, Safari)
    + * @todo OSX support (Safari, Google Chrome, Mozilla Firefox)
    + *
    + * @package Testtakepos
    + */
    +class TakePosFunctionalTest extends \PHPUnit_Extensions_Selenium2TestCase
    +{
    +	// TODO: move to a global configuration file?
    +	/** @var string Base URL of the webserver under test */
    +	protected static $base_url = 'http://dev.zenfusion.fr';
    +	/**
    +	 * @var string Dolibarr admin username
    +	 * @see authenticate
    +	 */
    +	protected static $dol_admin_user = 'admin';
    +	/**
    +	 * @var string Dolibarr admin password
    +	 * @see authenticate
    +	 */
    +	protected static $dol_admin_pass = 'admin';
    +	/** @var int Dolibarr module ID */
    +	private static $module_id = 500000; // TODO: autodetect?
    +
    +	/** @var array Browsers to test with */
    +	public static $browsers = array(
    +		array(
    +			'browser' => 'Google Chrome on Linux',
    +			'browserName' => 'chrome',
    +			'sessionStrategy' => 'shared',
    +			'desiredCapabilities' => array()
    +		),
    +		// Geckodriver does not keep the session at the moment?!
    +		// XPath selectors also don't seem to work
    +//        array(
    +//            'browser' => 'Mozilla Firefox on Linux',
    +//            'browserName' => 'firefox',
    +//            'sessionStrategy' => 'shared',
    +//            'desiredCapabilities' => array(
    +//                'marionette' => true
    +//            )
    +//        )
    +	);
    +
    +	/**
    +	 * Helper function to select links by href
    +	 *
    +	 * @param  string  $value      Href
    +	 * @return mixed               Helper string
    +	 */
    +	protected function byHref($value)
    +	{
    +		$anchor = null;
    +		$anchors = $this->elements($this->using('tag name')->value('a'));
    +		foreach ($anchors as $anchor) {
    +			if (strstr($anchor->attribute('href'), $value)) {
    +				break;
    +			}
    +		}
    +		return $anchor;
    +	}
    +
    +	/**
    +	 * Global test setup
    +	 *
    +	 * @return	void
    +	 */
    +	public static function setUpBeforeClass()
    +	{
    +	}
    +
    +	/**
    +	 * Unit test setup
    +	 *
    +	 * @return	void
    +	 */
    +	public function setUp()
    +	{
    +		$this->setSeleniumServerRequestsTimeout(3600);
    +		$this->setBrowserUrl(self::$base_url);
    +	}
    +
    +	/**
    +	 * Verify pre conditions
    +	 *
    +	 * @return	void
    +	 */
    +	protected function assertPreConditions()
    +	{
    +	}
    +
    +	/**
    +	 * Handle Dolibarr authentication
    +	 *
    +	 * @return	void
    +	 */
    +	private function authenticate()
    +	{
    +		try {
    +			if ($this->byId('login')) {
    +				$login = $this->byId('username');
    +				$login->clear();
    +				$login->value('admin');
    +				$password = $this->byId('password');
    +				$password->clear();
    +				$password->value('admin');
    +				$this->byId('login')->submit();
    +			}
    +		} catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
    +			// Login does not exist. Assume we are already authenticated
    +		}
    +	}
    +
    +	/**
    +	 * Test enabling developer mode
    +	 *
    +	 * @return	void
    +	 */
    +	public function testEnableDeveloperMode()
    +	{
    +		$this->url('/admin/const.php');
    +		$this->authenticate();
    +		$main_features_level_path='//input[@value="MAIN_FEATURES_LEVEL"]/following::input[@type="text"]';
    +		$main_features_level = $this->byXPath($main_features_level_path);
    +		$main_features_level->clear();
    +		$main_features_level->value('2');
    +		$this->byName('update')->click();
    +		// Page reloaded, we need a new XPath
    +		$main_features_level = $this->byXPath($main_features_level_path);
    +		$this->assertEquals('2', $main_features_level->value(), "MAIN_FEATURES_LEVEL value is 2");
    +	}
    +
    +	/**
    +	 * Test enabling the module
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testEnableDeveloperMode
    +	 */
    +	public function testModuleEnabled()
    +	{
    +		$this->url('/admin/modules.php');
    +		$this->authenticate();
    +		$module_status_image_path='//a[contains(@href, "' . self::$module_id . '")]/img';
    +		$module_status_image = $this->byXPath($module_status_image_path);
    +		if (strstr($module_status_image->attribute('src'), 'switch_off.png')) {
    +			// Enable the module
    +			$this->byHref('modTakePos')->click();
    +		} else {
    +			// Disable the module
    +			$this->byHref('modTakePos')->click();
    +			// Reenable the module
    +			$this->byHref('modTakePos')->click();
    +		}
    +		// Page reloaded, we need a new Xpath
    +		$module_status_image = $this->byXPath($module_status_image_path);
    +		$this->assertContains('switch_on.png', $module_status_image->attribute('src'), "Module enabled");
    +	}
    +
    +	/**
    +	 * Test access to the configuration page
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testModuleEnabled
    +	 */
    +	public function testConfigurationPage()
    +	{
    +		$this->url('/custom/takepos/admin/setup.php');
    +		$this->authenticate();
    +		$this->assertContains('takepos/admin/setup.php', $this->url(), 'Configuration page');
    +	}
    +
    +	/**
    +	 * Test access to the about page
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testConfigurationPage
    +	 */
    +	public function testAboutPage()
    +	{
    +		$this->url('/custom/takepos/admin/about.php');
    +		$this->authenticate();
    +		$this->assertContains('takepos/admin/about.php', $this->url(), 'About page');
    +	}
    +
    +	/**
    +	 * Test about page is rendering Markdown
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testAboutPage
    +	 */
    +	public function testAboutPageRendersMarkdownReadme()
    +	{
    +		$this->url('/custom/takepos/admin/about.php');
    +		$this->authenticate();
    +		$this->assertEquals(
    +			'Dolibarr Module Template (aka My Module)',
    +			$this->byTag('h1')->text(),
    +			"Readme title"
    +		);
    +	}
    +
    +	/**
    +	 * Test box is properly declared
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testModuleEnabled
    +	 */
    +	public function testBoxDeclared()
    +	{
    +		$this->url('/admin/boxes.php');
    +		$this->authenticate();
    +		$this->assertContains('takeposwidget1', $this->source(), "Box enabled");
    +	}
    +
    +	/**
    +	 * Test trigger is properly enabled
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testModuleEnabled
    +	 */
    +	public function testTriggerDeclared()
    +	{
    +		$this->url('/admin/triggers.php');
    +		$this->authenticate();
    +		$this->assertContains(
    +			'interface_99_modTakePos_TakePosTriggers.class.php',
    +			$this->byTag('body')->text(),
    +			"Trigger declared"
    +		);
    +	}
    +
    +	/**
    +	 * Test trigger is properly declared
    +	 *
    +	 * @return	void
    +	 *
    +	 * @depends testTriggerDeclared
    +	 */
    +	public function testTriggerEnabled()
    +	{
    +		$this->url('/admin/triggers.php');
    +		$this->authenticate();
    +		$this->assertContains(
    +			'tick.png',
    +			$this->byXPath('//td[text()="interface_99_modTakePos_MyTrigger.class.php"]/following::img')->attribute('src'),
    +			"Trigger enabled"
    +		);
    +	}
    +
    +	/**
    +	 * Verify post conditions
    +	 *
    +	 * @return	void
    +	 */
    +	protected function assertPostConditions()
    +	{
    +	}
    +
    +	/**
    +	 * Unit test teardown
    +	 *
    +	 * @return	void
    +	 */
    +	public function tearDown()
    +	{
    +	}
    +
    +	/**
    +	 * Global test teardown
    +	 *
    +	 * @return	void
    +	 */
    +	public static function tearDownAfterClass()
    +	{
    +	}
    +}